fix: Prevent token race conditions by pre-saving access/refresh tokens to localStorage before NextAuth signIn and refining logout token clearing.
This commit is contained in:
@@ -56,6 +56,13 @@ export default function LoginPage() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save tokens to localStorage BEFORE signIn to prevent race condition
|
||||
// (dashboard components may call API before TokenSync has synced from session)
|
||||
if (validateData.data?.accessToken) {
|
||||
localStorage.setItem('accessToken', validateData.data.accessToken);
|
||||
localStorage.setItem('refreshToken', validateData.data.refreshToken);
|
||||
}
|
||||
|
||||
// If validation passed, use NextAuth to create session
|
||||
const result = await signIn('credentials', {
|
||||
email,
|
||||
@@ -66,6 +73,9 @@ export default function LoginPage() {
|
||||
setLoading(false);
|
||||
|
||||
if (result?.error) {
|
||||
// Login failed - clear the tokens we just saved
|
||||
localStorage.removeItem('accessToken');
|
||||
localStorage.removeItem('refreshToken');
|
||||
setError('Login failed. Please try again.');
|
||||
} else {
|
||||
router.push('/');
|
||||
|
||||
@@ -102,8 +102,11 @@ function VerifyTwoFactorContent() {
|
||||
});
|
||||
}
|
||||
|
||||
// Save tokens to localStorage BEFORE signIn to prevent race condition
|
||||
localStorage.setItem('accessToken', response.data.accessToken);
|
||||
localStorage.setItem('refreshToken', response.data.refreshToken);
|
||||
|
||||
// Now sign in with NextAuth using the tokens we received
|
||||
// We need to call the NextAuth credentials provider with the tokens
|
||||
const result = await signIn('credentials', {
|
||||
email: userEmail,
|
||||
accessToken: response.data.accessToken,
|
||||
@@ -112,6 +115,8 @@ function VerifyTwoFactorContent() {
|
||||
});
|
||||
|
||||
if (result?.error) {
|
||||
localStorage.removeItem('accessToken');
|
||||
localStorage.removeItem('refreshToken');
|
||||
setError('Failed to complete login. Please try again.');
|
||||
setLoading(false);
|
||||
} else {
|
||||
|
||||
@@ -23,11 +23,8 @@ export default function LogoutPage() {
|
||||
// Delete httpOnly cookies via server action (Next.js cookies() API)
|
||||
await clearAuthCookies();
|
||||
|
||||
setTimeout(() => {
|
||||
// Redirect to login
|
||||
window.location.reload();
|
||||
window.location.href = '/login';
|
||||
}, 3000);
|
||||
// Redirect to login immediately
|
||||
window.location.href = '/login';
|
||||
};
|
||||
|
||||
performLogout().catch(() => {
|
||||
|
||||
@@ -39,9 +39,14 @@ function TokenSync() {
|
||||
hasInitialized.current = true;
|
||||
}
|
||||
} else if (status === "unauthenticated") {
|
||||
// Clear tokens when logged out
|
||||
localStorage.removeItem("accessToken");
|
||||
localStorage.removeItem("refreshToken");
|
||||
// Only clear tokens if a logout is explicitly in progress.
|
||||
// Don't clear during normal page loads or brief unauthenticated flickers,
|
||||
// as the login page saves tokens to localStorage before signIn completes.
|
||||
const loggingOut = localStorage.getItem("isLoggingOut") === "true";
|
||||
if (loggingOut) {
|
||||
localStorage.removeItem("accessToken");
|
||||
localStorage.removeItem("refreshToken");
|
||||
}
|
||||
hasInitialized.current = false;
|
||||
}
|
||||
}, [session, status]);
|
||||
|
||||
Reference in New Issue
Block a user