Fix session persistence - improve token restoration
cgen-47838b8ee0e941d4845ff07ce0b2a7fd
This commit is contained in:
parent
e3f4f06a9c
commit
dea4a6c9ed
1 changed files with 46 additions and 17 deletions
|
|
@ -165,11 +165,15 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
const storageClearedRef = useRef(false);
|
const storageClearedRef = useRef(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let sessionRestored = false;
|
||||||
|
|
||||||
// Add timeout to ensure loading doesn't get stuck
|
// Add timeout to ensure loading doesn't get stuck
|
||||||
const loadingTimeout = setTimeout(() => {
|
const loadingTimeout = setTimeout(() => {
|
||||||
console.log("Auth loading timeout - forcing loading to false");
|
console.log("Auth loading timeout - forcing loading to false");
|
||||||
setLoading(false);
|
if (!sessionRestored) {
|
||||||
}, 5000);
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, 8000);
|
||||||
|
|
||||||
if (!storageClearedRef.current && typeof window !== "undefined") {
|
if (!storageClearedRef.current && typeof window !== "undefined") {
|
||||||
try {
|
try {
|
||||||
|
|
@ -189,29 +193,51 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get initial session
|
// Helper to check if auth tokens exist in localStorage
|
||||||
supabase.auth
|
const hasAuthTokens = () => {
|
||||||
.getSession()
|
if (typeof window === "undefined") return false;
|
||||||
.then(({ data: { session } }) => {
|
const keys = Object.keys(window.localStorage);
|
||||||
clearTimeout(loadingTimeout);
|
return keys.some((key) => key.includes("auth-token") || key.includes("sb-") && key.includes("-auth"));
|
||||||
setSession(session);
|
};
|
||||||
setUser(session?.user ?? null);
|
|
||||||
|
// Get initial session with persistence recovery
|
||||||
|
const initializeAuth = async () => {
|
||||||
|
try {
|
||||||
|
const { data: { session } } = await supabase.auth.getSession();
|
||||||
|
|
||||||
|
// If no session but tokens exist, the session might not have restored yet
|
||||||
|
// Wait a bit for onAuthStateChange to trigger
|
||||||
|
if (!session && hasAuthTokens()) {
|
||||||
|
console.log("Tokens exist in storage but session not yet restored, waiting...");
|
||||||
|
// Don't set loading to false yet - wait for onAuthStateChange
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (session?.user) {
|
if (session?.user) {
|
||||||
fetchUserProfile(session.user.id);
|
sessionRestored = true;
|
||||||
|
setSession(session);
|
||||||
|
setUser(session.user);
|
||||||
|
await fetchUserProfile(session.user.id);
|
||||||
} else {
|
} else {
|
||||||
|
sessionRestored = true;
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
})
|
} catch (error) {
|
||||||
.catch((error) => {
|
|
||||||
clearTimeout(loadingTimeout);
|
|
||||||
console.error("Error getting session:", error);
|
console.error("Error getting session:", error);
|
||||||
|
sessionRestored = true;
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
});
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Listen for auth changes
|
initializeAuth();
|
||||||
|
|
||||||
|
// Listen for auth changes - this is the source of truth
|
||||||
const {
|
const {
|
||||||
data: { subscription },
|
data: { subscription },
|
||||||
} = supabase.auth.onAuthStateChange(async (event, session) => {
|
} = supabase.auth.onAuthStateChange(async (event, session) => {
|
||||||
|
console.log("Auth state change:", event, !!session?.user);
|
||||||
|
|
||||||
|
sessionRestored = true;
|
||||||
setSession(session);
|
setSession(session);
|
||||||
setUser(session?.user ?? null);
|
setUser(session?.user ?? null);
|
||||||
|
|
||||||
|
|
@ -220,8 +246,8 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
} else {
|
} else {
|
||||||
setProfile(null);
|
setProfile(null);
|
||||||
setRoles([]);
|
setRoles([]);
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
setLoading(false);
|
|
||||||
|
|
||||||
// Handle token refresh failures specifically
|
// Handle token refresh failures specifically
|
||||||
if (event === "TOKEN_REFRESH_FAILED") {
|
if (event === "TOKEN_REFRESH_FAILED") {
|
||||||
|
|
@ -257,7 +283,10 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => subscription.unsubscribe();
|
return () => {
|
||||||
|
clearTimeout(loadingTimeout);
|
||||||
|
subscription.unsubscribe();
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const fetchUserProfile = async (
|
const fetchUserProfile = async (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue