|
4 | 4 |
|
5 | 5 | import { errorMessage } from '../utils/error'; |
6 | 6 |
|
7 | | -export const AUTH_USER_CACHE_TTL_MS = 5_000; |
8 | | - |
9 | | -let cachedUser: unknown = undefined; |
10 | | -let cachedUserExpiresAt = 0; |
11 | | -let hasCachedUser = false; |
12 | 7 | let pendingUserRequest: Promise<unknown> | undefined; |
13 | 8 |
|
14 | | -function setCachedUser(user: unknown, now = Date.now()) { |
15 | | - cachedUser = user; |
16 | | - cachedUserExpiresAt = now + AUTH_USER_CACHE_TTL_MS; |
17 | | - hasCachedUser = true; |
18 | | - return user; |
19 | | -} |
20 | | - |
21 | 9 | function clearCachedUser() { |
22 | | - cachedUser = undefined; |
23 | | - cachedUserExpiresAt = 0; |
24 | | - hasCachedUser = false; |
25 | 10 | pendingUserRequest = undefined; |
26 | 11 | } |
27 | 12 |
|
28 | | -function hasFreshUserCache(now = Date.now()) { |
29 | | - return hasCachedUser && cachedUserExpiresAt > now; |
30 | | -} |
31 | | - |
32 | 13 | function getPayloadErrorMessage(payload: unknown): string { |
33 | 14 | if (typeof payload !== 'object' || payload === null) { |
34 | 15 | return ''; |
@@ -61,27 +42,25 @@ async function getStrategies(): Promise<{ |
61 | 42 | * @returns {Promise<*>} |
62 | 43 | */ |
63 | 44 | async function getUser() { |
64 | | - if (hasFreshUserCache()) { |
65 | | - return cachedUser; |
66 | | - } |
67 | | - |
68 | 45 | if (pendingUserRequest) { |
69 | 46 | return pendingUserRequest; |
70 | 47 | } |
71 | 48 |
|
72 | 49 | pendingUserRequest = (async () => { |
73 | 50 | try { |
| 51 | + // Only dedupe concurrent callers. Always revalidate settled auth state so |
| 52 | + // logout/session expiry in another tab is reflected on the next check. |
74 | 53 | const response = await fetch('/auth/user', { |
75 | 54 | redirect: 'manual', |
76 | 55 | credentials: 'include', |
77 | 56 | }); |
78 | 57 | if (response.ok) { |
79 | | - return setCachedUser(await response.json()); |
| 58 | + return await response.json(); |
80 | 59 | } |
81 | | - return setCachedUser(undefined); |
| 60 | + return undefined; |
82 | 61 | } catch (e: unknown) { |
83 | 62 | console.debug(`Unable to fetch current user: ${errorMessage(e)}`); |
84 | | - return setCachedUser(undefined); |
| 63 | + return undefined; |
85 | 64 | } finally { |
86 | 65 | pendingUserRequest = undefined; |
87 | 66 | } |
@@ -122,7 +101,8 @@ async function loginBasic(username: string, password: string, remember: boolean |
122 | 101 |
|
123 | 102 | throw new Error(message || 'Username or password error'); |
124 | 103 | } |
125 | | - return setCachedUser(await response.json()); |
| 104 | + clearCachedUser(); |
| 105 | + return await response.json(); |
126 | 106 | } |
127 | 107 |
|
128 | 108 | /** |
|
0 commit comments