···
1
1
import type { Cookies } from '@sveltejs/kit';
2
2
import { Client } from '@atcute/client';
3
3
import type { Did } from '@atcute/lexicons';
4
4
-
import type { OAuthSession } from '@atcute/oauth-node-client';
4
4
+
import {
5
5
+
type OAuthSession,
6
6
+
TokenInvalidError,
7
7
+
TokenRefreshError,
8
8
+
TokenRevokedError,
9
9
+
AuthMethodUnsatisfiableError
10
10
+
} from '@atcute/oauth-node-client';
5
11
import { createOAuthClient } from './oauth';
6
12
import { getSignedCookie } from './signed-cookie';
7
13
import { scopes } from '../settings';
···
15
21
/**
16
22
* Restores an OAuth session from the signed `did` cookie.
17
23
* Returns session locals to be assigned to `event.locals`.
18
18
-
* Deletes the cookie if the session can't be restored.
24
24
+
* Deletes the cookie only if the session is genuinely unrecoverable.
25
25
+
* Transient failures (network, KV) preserve the cookie for retry.
19
26
*/
20
27
export async function restoreSession(
21
28
cookies: Cookies,
···
29
36
30
37
// If permissions changed since login, invalidate the session
31
38
const savedScope = getSignedCookie(cookies, 'scope');
32
32
-
if (savedScope !== scopes.join(' ')) {
39
39
+
if (savedScope !== null && savedScope !== scopes.join(' ')) {
33
40
cookies.delete('did', { path: '/' });
34
41
cookies.delete('scope', { path: '/' });
35
42
return { session: null, client: null, did: null };
···
46
53
};
47
54
} catch (e) {
48
55
console.error('Failed to restore session:', e);
49
49
-
cookies.delete('did', { path: '/' });
50
50
-
cookies.delete('scope', { path: '/' });
56
56
+
57
57
+
// Only delete cookies when the session is genuinely unrecoverable.
58
58
+
// Transient errors (network issues, KV hiccups) should preserve the
59
59
+
// cookie so the next request can retry without forcing a full re-login.
60
60
+
const isSessionGone =
61
61
+
e instanceof TokenInvalidError ||
62
62
+
e instanceof TokenRevokedError ||
63
63
+
e instanceof TokenRefreshError ||
64
64
+
e instanceof AuthMethodUnsatisfiableError;
65
65
+
66
66
+
if (isSessionGone) {
67
67
+
cookies.delete('did', { path: '/' });
68
68
+
cookies.delete('scope', { path: '/' });
69
69
+
}
70
70
+
51
71
return { session: null, client: null, did: null };
52
72
}
53
73
}