···
5
5
6
6
// This component handles the callback redirect from the Bluesky OAuth process
7
7
const LoginCallback = () => {
8
8
-
const { loading, isAuthenticated, checkAuthStatus } = useAuth();
8
8
+
const { loading, isAuthenticated, session, checkAuthStatus } = useAuth();
9
9
const [error, setError] = useState(null);
10
10
const [returnUrl, setReturnUrl] = useState('/');
11
11
const [processingComplete, setProcessingComplete] = useState(false);
12
12
const location = useLocation();
13
13
const callbackAttempts = useRef(0);
14
14
const maxAttempts = 2;
15
15
+
16
16
+
useEffect(() => {
17
17
+
// If we already have authentication after loading, we can redirect
18
18
+
if (!loading && isAuthenticated && session) {
19
19
+
setProcessingComplete(true);
20
20
+
}
21
21
+
}, [loading, isAuthenticated, session]);
15
22
16
23
useEffect(() => {
17
24
// Skip if already processed or max attempts reached
···
55
62
return;
56
63
}
57
64
65
65
+
// Already authenticated? Don't do anything else
66
66
+
if (isAuthenticated && session) {
67
67
+
console.log('Already authenticated, completing processing');
68
68
+
setProcessingComplete(true);
69
69
+
return;
70
70
+
}
71
71
+
58
72
// Check server-side authentication status
59
73
const authResult = await checkAuthStatus();
60
60
-
setProcessingComplete(true);
61
74
62
62
-
if (!authResult) {
75
75
+
// Consider authentication successful if:
76
76
+
// 1. checkAuthStatus returned true OR
77
77
+
// 2. isAuthenticated is now true (state might have updated separately)
78
78
+
if (authResult || isAuthenticated) {
79
79
+
console.log('Auth check success, completing processing');
80
80
+
setProcessingComplete(true);
81
81
+
} else {
82
82
+
console.error('Auth check failed, setting error');
63
83
setError('Authentication failed. Could not establish a valid session.');
84
84
+
setProcessingComplete(true);
64
85
}
65
86
} catch (err) {
66
87
console.error('Error handling login callback:', err);
67
67
-
setError('Failed to complete login process');
68
68
-
setProcessingComplete(true);
88
88
+
// If we have a session despite the error, still consider it successful
89
89
+
if (session && isAuthenticated) {
90
90
+
console.log('Error occurred but we have a session, proceeding');
91
91
+
setProcessingComplete(true);
92
92
+
} else {
93
93
+
setError('Failed to complete login process');
94
94
+
setProcessingComplete(true);
95
95
+
}
69
96
}
70
97
};
71
98
72
99
handleCallback();
73
73
-
}, [location, checkAuthStatus, processingComplete]);
100
100
+
}, [location, checkAuthStatus, isAuthenticated, session, processingComplete]);
74
101
75
102
// Don't redirect immediately while loading - wait for the check to complete
76
103
if (loading && !processingComplete) {
77
104
return <Loading message="Processing login..." />;
105
105
+
}
106
106
+
107
107
+
// If we're authenticated regardless of errors, redirect
108
108
+
if (isAuthenticated && session) {
109
109
+
console.log(`Redirecting to ${returnUrl} since we have a session`);
110
110
+
return <Navigate to={returnUrl} replace />;
78
111
}
79
112
80
113
if (error) {
···
63
63
setClient(oauthClient);
64
64
65
65
if (result?.session) {
66
66
+
console.log('Found existing OAuth session:', result.session);
67
67
+
66
68
// If client has session but server doesn't, we need to sync them
67
67
-
await fetch('/api/sync-session', {
68
68
-
method: 'POST',
69
69
-
headers: {
70
70
-
'Content-Type': 'application/json'
71
71
-
},
72
72
-
body: JSON.stringify({
73
73
-
did: result.session.sub,
74
74
-
handle: result.session.handle
75
75
-
}),
76
76
-
credentials: 'include'
77
77
-
});
78
78
-
79
79
-
setSession(result.session);
69
69
+
try {
70
70
+
const syncResponse = await fetch('/api/sync-session', {
71
71
+
method: 'POST',
72
72
+
headers: {
73
73
+
'Content-Type': 'application/json'
74
74
+
},
75
75
+
body: JSON.stringify({
76
76
+
did: result.session.sub,
77
77
+
handle: result.session.handle
78
78
+
}),
79
79
+
credentials: 'include'
80
80
+
});
81
81
+
82
82
+
if (syncResponse.ok) {
83
83
+
const syncData = await syncResponse.json();
84
84
+
console.log('Session sync successful:', syncData);
85
85
+
// Use the server session data which may have more info
86
86
+
setSession(syncData.user);
87
87
+
} else {
88
88
+
console.warn('Session sync failed, using client session');
89
89
+
// Still use the client session if sync fails
90
90
+
setSession(result.session);
91
91
+
}
92
92
+
} catch (syncError) {
93
93
+
console.error('Error syncing session:', syncError);
94
94
+
// If sync fails, still use the client session
95
95
+
setSession(result.session);
96
96
+
}
80
97
}
81
98
82
99
// Listen for session deletion events
83
100
oauthClient.addEventListener('deleted', (event) => {
84
84
-
if (event.data.did === session?.sub) {
101
101
+
if (event.data.did === session?.sub || event.data.did === session?.did) {
85
102
setSession(null);
86
103
// Also logout from server
87
104
fetch('/api/logout', {