@payloadcms/ui 4.0.0-canary.20 → 4.0.0-canary.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/elements/CopyToClipboard/index.d.ts +1 -0
- package/dist/elements/CopyToClipboard/index.d.ts.map +1 -1
- package/dist/elements/CopyToClipboard/index.js +10 -8
- package/dist/elements/CopyToClipboard/index.js.map +1 -1
- package/dist/elements/FileManager/FileToolbar/index.d.ts.map +1 -1
- package/dist/elements/FileManager/FileToolbar/index.js +3 -0
- package/dist/elements/FileManager/FileToolbar/index.js.map +1 -1
- package/dist/exports/client/index.d.ts +2 -1
- package/dist/exports/client/index.d.ts.map +1 -1
- package/dist/exports/client/index.js +1 -1
- package/dist/exports/client/index.js.map +3 -3
- package/dist/forms/Form/index.d.ts.map +1 -1
- package/dist/forms/Form/index.js +4 -1
- package/dist/forms/Form/index.js.map +1 -1
- package/dist/providers/Auth/AuthSessionDebug/index.css +48 -0
- package/dist/providers/Auth/AuthSessionDebug/index.d.ts +13 -0
- package/dist/providers/Auth/AuthSessionDebug/index.d.ts.map +1 -0
- package/dist/providers/Auth/AuthSessionDebug/index.js +93 -0
- package/dist/providers/Auth/AuthSessionDebug/index.js.map +1 -0
- package/dist/providers/Auth/AuthSessionDebug/utilities.d.ts +21 -0
- package/dist/providers/Auth/AuthSessionDebug/utilities.d.ts.map +1 -0
- package/dist/providers/Auth/AuthSessionDebug/utilities.js +53 -0
- package/dist/providers/Auth/AuthSessionDebug/utilities.js.map +1 -0
- package/dist/providers/Auth/authSessionRequests.d.ts +27 -0
- package/dist/providers/Auth/authSessionRequests.d.ts.map +1 -0
- package/dist/providers/Auth/authSessionRequests.js +119 -0
- package/dist/providers/Auth/authSessionRequests.js.map +1 -0
- package/dist/providers/Auth/authSessionRequests.spec.js +121 -0
- package/dist/providers/Auth/authSessionRequests.spec.js.map +1 -0
- package/dist/providers/Auth/index.d.ts +2 -56
- package/dist/providers/Auth/index.d.ts.map +1 -1
- package/dist/providers/Auth/index.js +283 -135
- package/dist/providers/Auth/index.js.map +1 -1
- package/dist/providers/Auth/sessionActivity.d.ts +23 -0
- package/dist/providers/Auth/sessionActivity.d.ts.map +1 -0
- package/dist/providers/Auth/sessionActivity.js +49 -0
- package/dist/providers/Auth/sessionActivity.js.map +1 -0
- package/dist/providers/Auth/sessionActivity.spec.js +44 -0
- package/dist/providers/Auth/sessionActivity.spec.js.map +1 -0
- package/dist/providers/Auth/sessionTiming.d.ts +11 -0
- package/dist/providers/Auth/sessionTiming.d.ts.map +1 -0
- package/dist/providers/Auth/sessionTiming.js +18 -0
- package/dist/providers/Auth/sessionTiming.js.map +1 -0
- package/dist/providers/Auth/tabSessionSync/index.d.ts +17 -0
- package/dist/providers/Auth/tabSessionSync/index.d.ts.map +1 -0
- package/dist/providers/Auth/tabSessionSync/index.js +263 -0
- package/dist/providers/Auth/tabSessionSync/index.js.map +1 -0
- package/dist/providers/Auth/tabSessionSync/index.spec.js +463 -0
- package/dist/providers/Auth/tabSessionSync/index.spec.js.map +1 -0
- package/dist/providers/Auth/tabSessionSync/types.d.ts +107 -0
- package/dist/providers/Auth/tabSessionSync/types.d.ts.map +1 -0
- package/dist/providers/Auth/tabSessionSync/types.js +6 -0
- package/dist/providers/Auth/tabSessionSync/types.js.map +1 -0
- package/dist/providers/Auth/tabSessionSync/useTabSessionSync.d.ts +11 -0
- package/dist/providers/Auth/tabSessionSync/useTabSessionSync.d.ts.map +1 -0
- package/dist/providers/Auth/tabSessionSync/useTabSessionSync.js +90 -0
- package/dist/providers/Auth/tabSessionSync/useTabSessionSync.js.map +1 -0
- package/dist/providers/Auth/tabSessionSync/utilities.d.ts +26 -0
- package/dist/providers/Auth/tabSessionSync/utilities.d.ts.map +1 -0
- package/dist/providers/Auth/tabSessionSync/utilities.js +159 -0
- package/dist/providers/Auth/tabSessionSync/utilities.js.map +1 -0
- package/dist/providers/Auth/types.d.ts +66 -0
- package/dist/providers/Auth/types.d.ts.map +1 -0
- package/dist/providers/Auth/types.js +2 -0
- package/dist/providers/Auth/types.js.map +1 -0
- package/dist/providers/Auth/useAuthSessionTimers.d.ts +26 -0
- package/dist/providers/Auth/useAuthSessionTimers.d.ts.map +1 -0
- package/dist/providers/Auth/useAuthSessionTimers.js +203 -0
- package/dist/providers/Auth/useAuthSessionTimers.js.map +1 -0
- package/dist/providers/Auth/useAuthSessionTimers.spec.js +311 -0
- package/dist/providers/Auth/useAuthSessionTimers.spec.js.map +1 -0
- package/dist/providers/FormErrorHandler/index.d.ts +5 -1
- package/dist/providers/FormErrorHandler/index.d.ts.map +1 -1
- package/dist/providers/FormErrorHandler/index.js.map +1 -1
- package/dist/providers/Root/index.js +4 -4
- package/dist/providers/Root/index.js.map +1 -1
- package/dist/providers/RouteTransition/ProgressBar/index.js +4 -1
- package/dist/providers/RouteTransition/ProgressBar/index.js.map +1 -1
- package/dist/providers/RouteTransition/ProgressBar/index.spec.js +44 -0
- package/dist/providers/RouteTransition/ProgressBar/index.spec.js.map +1 -0
- package/dist/providers/RouteTransition/index.d.ts +2 -0
- package/dist/providers/RouteTransition/index.d.ts.map +1 -1
- package/dist/providers/RouteTransition/index.js +42 -14
- package/dist/providers/RouteTransition/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +5 -5
|
@@ -11,10 +11,13 @@ import { useEffectEvent } from '../../hooks/useEffectEvent.js';
|
|
|
11
11
|
import { useTranslation } from '../../providers/Translation/index.js';
|
|
12
12
|
import { requests } from '../../utilities/api.js';
|
|
13
13
|
import { useConfig } from '../Config/index.js';
|
|
14
|
-
import { usePathname, useRouter } from '../RouterAdapter/index.js';
|
|
14
|
+
import { usePathname, useRouter, useSearchParams } from '../RouterAdapter/index.js';
|
|
15
15
|
import { useRouteTransition } from '../RouteTransition/index.js';
|
|
16
|
+
import { createAuthSessionRequests } from './authSessionRequests.js';
|
|
17
|
+
import { TAB_SESSION_EVENT_TYPES } from './tabSessionSync/index.js';
|
|
18
|
+
import { useTabSessionSync } from './tabSessionSync/useTabSessionSync.js';
|
|
19
|
+
import { useAuthSessionTimers } from './useAuthSessionTimers.js';
|
|
16
20
|
const Context = /*#__PURE__*/createContext({});
|
|
17
|
-
const maxTimeoutMs = 2147483647;
|
|
18
21
|
export function AuthProvider({
|
|
19
22
|
children,
|
|
20
23
|
permissions: initialPermissions,
|
|
@@ -22,6 +25,8 @@ export function AuthProvider({
|
|
|
22
25
|
}) {
|
|
23
26
|
const pathname = usePathname();
|
|
24
27
|
const router = useRouter();
|
|
28
|
+
const searchParams = useSearchParams();
|
|
29
|
+
const route = `${pathname}?${searchParams.toString()}`;
|
|
25
30
|
const {
|
|
26
31
|
config
|
|
27
32
|
} = useConfig();
|
|
@@ -30,7 +35,8 @@ export function AuthProvider({
|
|
|
30
35
|
autoLogin,
|
|
31
36
|
autoRefresh,
|
|
32
37
|
routes: {
|
|
33
|
-
inactivity: logoutInactivityRoute
|
|
38
|
+
inactivity: logoutInactivityRoute,
|
|
39
|
+
login: loginRoute
|
|
34
40
|
},
|
|
35
41
|
user: userSlug
|
|
36
42
|
},
|
|
@@ -51,14 +57,12 @@ export function AuthProvider({
|
|
|
51
57
|
} = useRouteTransition();
|
|
52
58
|
const [user, setUserInMemory] = useState(initialUser);
|
|
53
59
|
const [tokenInMemory, setTokenInMemory] = useState();
|
|
54
|
-
const [
|
|
60
|
+
const [authSession, setAuthSession] = useState();
|
|
55
61
|
const [permissions, setPermissions] = useState(initialPermissions);
|
|
56
|
-
const [forceLogoutBufferMs, setForceLogoutBufferMs] = useState(120_000);
|
|
57
62
|
const [fetchedUserOnMount, setFetchedUserOnMount] = useState(false);
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const id = user?.id;
|
|
63
|
+
const [authRequests] = useState(createAuthSessionRequests);
|
|
64
|
+
const userRef = React.useRef(initialUser);
|
|
65
|
+
const isAuthenticated = Boolean(user);
|
|
62
66
|
const redirectToInactivityRoute = useCallback(() => {
|
|
63
67
|
const baseAdminRoute = formatAdminURL({
|
|
64
68
|
adminRoute,
|
|
@@ -70,111 +74,221 @@ export function AuthProvider({
|
|
|
70
74
|
})));
|
|
71
75
|
closeAllModals();
|
|
72
76
|
}, [router, adminRoute, logoutInactivityRoute, closeAllModals, startRouteTransition]);
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
const redirectToLoginRoute = useCallback(() => {
|
|
78
|
+
startRouteTransition(() => router.replace(formatAdminURL({
|
|
79
|
+
adminRoute,
|
|
80
|
+
path: loginRoute
|
|
81
|
+
})));
|
|
82
|
+
closeAllModals();
|
|
83
|
+
}, [adminRoute, closeAllModals, loginRoute, router, startRouteTransition]);
|
|
84
|
+
function onSessionActivity() {
|
|
85
|
+
setAuthSession(currentAuthSession => {
|
|
86
|
+
if (!currentAuthSession || currentAuthSession.activityRecorded) {
|
|
87
|
+
return currentAuthSession;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
...currentAuthSession,
|
|
91
|
+
activityRecorded: true
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function onSessionActivityRefresh() {
|
|
96
|
+
void refreshSession({
|
|
97
|
+
isActivityRefresh: true
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function onSessionExpiration(expirationMs) {
|
|
101
|
+
const collection = userRef.current?.collection;
|
|
102
|
+
tabSessionSync.broadcast({
|
|
103
|
+
type: TAB_SESSION_EVENT_TYPES.EXPIRED,
|
|
104
|
+
expiredTokenAt: expirationMs
|
|
105
|
+
});
|
|
106
|
+
void logOutSession({
|
|
107
|
+
collection
|
|
108
|
+
}).then(redirectToInactivityRoute);
|
|
109
|
+
}
|
|
110
|
+
function onSessionReminder() {
|
|
81
111
|
if (autoRefresh) {
|
|
82
|
-
|
|
112
|
+
sessionTimers.scheduleRefresh();
|
|
83
113
|
} else {
|
|
84
114
|
openModal(stayLoggedInModalSlug);
|
|
85
115
|
}
|
|
116
|
+
}
|
|
117
|
+
const sessionTimers = useAuthSessionTimers({
|
|
118
|
+
isAuthenticated,
|
|
119
|
+
onActivity: onSessionActivity,
|
|
120
|
+
onActivityRefresh: onSessionActivityRefresh,
|
|
121
|
+
onExpire: onSessionExpiration,
|
|
122
|
+
onReminder: onSessionReminder
|
|
86
123
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
sessionTimers.recordActivity('route');
|
|
126
|
+
}, [route, sessionTimers]);
|
|
127
|
+
const clearUserInMemory = useCallback(() => {
|
|
128
|
+
userRef.current = null;
|
|
129
|
+
setUserInMemory(null);
|
|
130
|
+
setTokenInMemory(undefined);
|
|
131
|
+
setAuthSession(undefined);
|
|
132
|
+
sessionTimers.clear();
|
|
133
|
+
}, [sessionTimers]);
|
|
134
|
+
const setLocalSession = useCallback(session => {
|
|
135
|
+
if (session?.user) {
|
|
136
|
+
const expirationMs_0 = typeof session.exp === 'number' && Number.isFinite(session.exp) ? session.exp * 1000 : undefined;
|
|
137
|
+
const nextSessionTiming = expirationMs_0 !== undefined ? sessionTimers.setExpiration(expirationMs_0) : undefined;
|
|
138
|
+
userRef.current = session.user;
|
|
139
|
+
setUserInMemory(session.user);
|
|
140
|
+
setTokenInMemory(session.token ?? session.refreshedToken);
|
|
141
|
+
if (nextSessionTiming) {
|
|
142
|
+
setAuthSession({
|
|
143
|
+
...nextSessionTiming,
|
|
144
|
+
activityRecorded: false
|
|
145
|
+
});
|
|
103
146
|
}
|
|
104
147
|
} else {
|
|
105
|
-
|
|
148
|
+
clearUserInMemory();
|
|
106
149
|
}
|
|
107
|
-
}, [
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
150
|
+
}, [clearUserInMemory, sessionTimers]);
|
|
151
|
+
const setUser = useCallback(session_0 => {
|
|
152
|
+
authRequests.discardPendingResults();
|
|
153
|
+
setLocalSession(session_0);
|
|
154
|
+
}, [authRequests, setLocalSession]);
|
|
155
|
+
const tabSessionSync = useTabSessionSync({
|
|
156
|
+
getTokenExpirationMs: sessionTimers.getCurrentExpirationMs,
|
|
157
|
+
onSessionExpired: () => {
|
|
158
|
+
const collection_0 = userRef.current?.collection;
|
|
159
|
+
void logOutSession({
|
|
160
|
+
collection: collection_0
|
|
161
|
+
}).then(redirectToInactivityRoute);
|
|
162
|
+
},
|
|
163
|
+
onSessionLoggedOut: () => {
|
|
164
|
+
const collection_1 = userRef.current?.collection;
|
|
165
|
+
void logOutSession({
|
|
166
|
+
collection: collection_1
|
|
167
|
+
}).then(redirectToLoginRoute);
|
|
168
|
+
},
|
|
169
|
+
onSessionRefreshed: session_1 => {
|
|
170
|
+
if (!authRequests.isLoggingOut()) {
|
|
171
|
+
authRequests.discardPendingResults();
|
|
172
|
+
setLocalSession(session_1);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
onTabSessionUnauthenticated: () => {
|
|
176
|
+
redirectToInactivityRoute();
|
|
177
|
+
},
|
|
178
|
+
reconcileSession: async options => {
|
|
179
|
+
const result = await fetchFullUserResult(options);
|
|
180
|
+
if (result.status === 'authenticated' && result.expirationMs !== undefined) {
|
|
181
|
+
return {
|
|
182
|
+
expirationMs: result.expirationMs,
|
|
183
|
+
status: result.status,
|
|
184
|
+
user: result.user
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (result.status === 'unauthenticated') {
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
status: 'indeterminate'
|
|
192
|
+
};
|
|
111
193
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
194
|
+
});
|
|
195
|
+
const refreshSession = useCallback(({
|
|
196
|
+
isActivityRefresh
|
|
197
|
+
}) => {
|
|
198
|
+
return authRequests.refresh(async ({
|
|
199
|
+
acceptResult,
|
|
200
|
+
invalidateWhenIdle,
|
|
201
|
+
isResultStale
|
|
202
|
+
}) => {
|
|
203
|
+
if (isResultStale()) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
const handledExpiration = sessionTimers.getCurrentExpirationMs();
|
|
207
|
+
const handledUser = userRef.current;
|
|
208
|
+
try {
|
|
209
|
+
const refreshStartedAt = Date.now();
|
|
210
|
+
const request = await requests.post(formatAdminURL({
|
|
211
|
+
apiRoute,
|
|
212
|
+
path: `/${userSlug}/refresh-token${isActivityRefresh ? '?refresh' : ''}`
|
|
213
|
+
}), {
|
|
214
|
+
headers: {
|
|
215
|
+
'Accept-Language': i18n.language
|
|
131
216
|
}
|
|
132
|
-
}
|
|
133
|
-
|
|
217
|
+
});
|
|
218
|
+
if (isResultStale()) {
|
|
219
|
+
return null;
|
|
134
220
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
221
|
+
if (request.status === 200) {
|
|
222
|
+
const json = await request.json();
|
|
223
|
+
if (!acceptResult()) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
setLocalSession(json);
|
|
227
|
+
tabSessionSync.broadcast({
|
|
228
|
+
type: TAB_SESSION_EVENT_TYPES.REFRESHED,
|
|
229
|
+
refreshStartedAt,
|
|
230
|
+
session: json
|
|
231
|
+
});
|
|
232
|
+
return json.user;
|
|
146
233
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
234
|
+
if (handledUser) {
|
|
235
|
+
const invalidateSession = () => {
|
|
236
|
+
if (handledExpiration !== undefined) {
|
|
237
|
+
tabSessionSync.broadcast({
|
|
238
|
+
type: TAB_SESSION_EVENT_TYPES.EXPIRED,
|
|
239
|
+
expiredTokenAt: handledExpiration
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
setLocalSession(null);
|
|
243
|
+
redirectToInactivityRoute();
|
|
244
|
+
};
|
|
245
|
+
invalidateWhenIdle(invalidateSession);
|
|
152
246
|
}
|
|
153
|
-
|
|
247
|
+
} catch (e) {
|
|
248
|
+
toast.error(`Refreshing token failed: ${e.message}`);
|
|
154
249
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
250
|
+
return null;
|
|
251
|
+
});
|
|
252
|
+
}, [apiRoute, authRequests, tabSessionSync, i18n.language, redirectToInactivityRoute, sessionTimers, setLocalSession, userSlug]);
|
|
253
|
+
const refreshCookieAsync = useCallback(() => refreshSession({
|
|
254
|
+
isActivityRefresh: false
|
|
255
|
+
}), [refreshSession]);
|
|
256
|
+
const logOutSession = useCallback(({
|
|
257
|
+
collection: collection_2
|
|
258
|
+
}) => {
|
|
259
|
+
return authRequests.logOut({
|
|
260
|
+
clearSession: () => {
|
|
261
|
+
authRequests.discardPendingResults();
|
|
262
|
+
setLocalSession(null);
|
|
263
|
+
},
|
|
264
|
+
request: async () => {
|
|
265
|
+
try {
|
|
266
|
+
if (collection_2) {
|
|
267
|
+
await requests.post(formatAdminURL({
|
|
268
|
+
apiRoute,
|
|
269
|
+
path: `/${collection_2}/logout`
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
272
|
+
} catch (_) {
|
|
273
|
+
// Explicit logout always clears local state, even if server revocation fails.
|
|
274
|
+
}
|
|
158
275
|
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
return null;
|
|
163
|
-
}, [apiRoute, i18n.language, redirectToInactivityRoute, setNewUser, userSlug, user]);
|
|
276
|
+
});
|
|
277
|
+
}, [apiRoute, authRequests, setLocalSession]);
|
|
164
278
|
const logOut = useCallback(async () => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
279
|
+
const logoutEvent = {
|
|
280
|
+
type: TAB_SESSION_EVENT_TYPES.LOGGED_OUT
|
|
281
|
+
};
|
|
282
|
+
const logoutPublication = tabSessionSync.broadcast(logoutEvent);
|
|
283
|
+
const collection_3 = userRef.current?.collection;
|
|
284
|
+
await logOutSession({
|
|
285
|
+
collection: collection_3
|
|
286
|
+
});
|
|
287
|
+
if (logoutPublication?.type === TAB_SESSION_EVENT_TYPES.LOGGED_OUT) {
|
|
288
|
+
tabSessionSync.broadcastLogoutSettlement(logoutPublication);
|
|
175
289
|
}
|
|
176
290
|
return true;
|
|
177
|
-
}, [
|
|
291
|
+
}, [tabSessionSync, logOutSession]);
|
|
178
292
|
const refreshPermissions = useCallback(async ({
|
|
179
293
|
locale
|
|
180
294
|
} = {}) => {
|
|
@@ -184,7 +298,7 @@ export function AuthProvider({
|
|
|
184
298
|
addQueryPrefix: true
|
|
185
299
|
});
|
|
186
300
|
try {
|
|
187
|
-
const
|
|
301
|
+
const request_0 = await requests.get(formatAdminURL({
|
|
188
302
|
apiRoute,
|
|
189
303
|
path: `/access${params}`
|
|
190
304
|
}), {
|
|
@@ -192,42 +306,79 @@ export function AuthProvider({
|
|
|
192
306
|
'Accept-Language': i18n.language
|
|
193
307
|
}
|
|
194
308
|
});
|
|
195
|
-
if (
|
|
196
|
-
const
|
|
197
|
-
setPermissions(
|
|
309
|
+
if (request_0.status === 200) {
|
|
310
|
+
const json_0 = await request_0.json();
|
|
311
|
+
setPermissions(json_0);
|
|
198
312
|
} else {
|
|
199
|
-
throw new Error(`Fetching permissions failed with status code ${
|
|
313
|
+
throw new Error(`Fetching permissions failed with status code ${request_0.status}`);
|
|
200
314
|
}
|
|
201
|
-
} catch (
|
|
202
|
-
toast.error(`Refreshing permissions failed: ${
|
|
315
|
+
} catch (e_0) {
|
|
316
|
+
toast.error(`Refreshing permissions failed: ${e_0.message}`);
|
|
203
317
|
}
|
|
204
318
|
}, [apiRoute, i18n]);
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
319
|
+
const fetchFullUserResult = React.useCallback(({
|
|
320
|
+
isTabSessionEventStale
|
|
321
|
+
} = {}) => {
|
|
322
|
+
return authRequests.queue(async ({
|
|
323
|
+
acceptResult: acceptResult_0,
|
|
324
|
+
isResultStale: isResultStale_0
|
|
325
|
+
}) => {
|
|
326
|
+
const isResponseStale = () => isResultStale_0() || Boolean(isTabSessionEventStale?.());
|
|
327
|
+
if (isResponseStale()) {
|
|
328
|
+
return {
|
|
329
|
+
status: 'indeterminate'
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
const request_1 = await requests.get(formatAdminURL({
|
|
334
|
+
apiRoute,
|
|
335
|
+
path: `/${userSlug}/me`
|
|
336
|
+
}), {
|
|
337
|
+
credentials: 'include',
|
|
338
|
+
headers: {
|
|
339
|
+
'Accept-Language': i18n.language
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
if (request_1.status !== 200) {
|
|
343
|
+
return {
|
|
344
|
+
status: 'indeterminate'
|
|
345
|
+
};
|
|
214
346
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
347
|
+
const json_1 = await request_1.json();
|
|
348
|
+
if (isResponseStale()) {
|
|
349
|
+
return {
|
|
350
|
+
status: 'indeterminate'
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
if (json_1?.user) {
|
|
354
|
+
if (!acceptResult_0()) {
|
|
355
|
+
return {
|
|
356
|
+
status: 'indeterminate'
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
setLocalSession(json_1);
|
|
360
|
+
return {
|
|
361
|
+
expirationMs: typeof json_1.exp === 'number' && Number.isFinite(json_1.exp) ? json_1.exp * 1000 : sessionTimers.getCurrentExpirationMs(),
|
|
362
|
+
status: 'authenticated',
|
|
363
|
+
user: json_1.user
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
setLocalSession(null);
|
|
367
|
+
return {
|
|
368
|
+
status: 'unauthenticated'
|
|
369
|
+
};
|
|
370
|
+
} catch (e_1) {
|
|
371
|
+
toast.error(`Fetching user failed: ${e_1.message}`);
|
|
220
372
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}, [apiRoute,
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}, [pathname]);
|
|
373
|
+
return {
|
|
374
|
+
status: 'indeterminate'
|
|
375
|
+
};
|
|
376
|
+
});
|
|
377
|
+
}, [apiRoute, authRequests, i18n.language, sessionTimers, setLocalSession, userSlug]);
|
|
378
|
+
const fetchFullUser = React.useCallback(async () => {
|
|
379
|
+
const result_0 = await fetchFullUserResult();
|
|
380
|
+
return result_0.status === 'authenticated' ? result_0.user : null;
|
|
381
|
+
}, [fetchFullUserResult]);
|
|
231
382
|
const fetchFullUserEvent = useEffectEvent(fetchFullUser);
|
|
232
383
|
useEffect(() => {
|
|
233
384
|
async function fetchUserOnMount() {
|
|
@@ -242,26 +393,23 @@ export function AuthProvider({
|
|
|
242
393
|
}
|
|
243
394
|
}, [user, autoLogin]);
|
|
244
395
|
useEffect(() => () => {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
clearTimeout(reminderTimeoutRef.current);
|
|
248
|
-
clearTimeout(forceLogOutTimeoutRef.current);
|
|
249
|
-
}, []);
|
|
396
|
+
authRequests.discardPendingResults();
|
|
397
|
+
}, [authRequests]);
|
|
250
398
|
if (!user && !fetchedUserOnMount) {
|
|
251
399
|
return null;
|
|
252
400
|
}
|
|
253
401
|
return /*#__PURE__*/_jsx(Context, {
|
|
254
402
|
value: {
|
|
403
|
+
authSession,
|
|
255
404
|
fetchFullUser,
|
|
256
405
|
logOut,
|
|
257
406
|
permissions,
|
|
258
|
-
refreshCookie,
|
|
407
|
+
refreshCookie: sessionTimers.scheduleRefresh,
|
|
259
408
|
refreshCookieAsync,
|
|
260
409
|
refreshPermissions,
|
|
261
410
|
setPermissions,
|
|
262
|
-
setUser
|
|
411
|
+
setUser,
|
|
263
412
|
token: tokenInMemory,
|
|
264
|
-
tokenExpirationMs,
|
|
265
413
|
user
|
|
266
414
|
},
|
|
267
415
|
children: children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["useModal","formatAdminURL","qs","React","createContext","use","useCallback","useEffect","useState","toast","stayLoggedInModalSlug","useEffectEvent","useTranslation","requests","useConfig","usePathname","useRouter","useRouteTransition","Context","maxTimeoutMs","AuthProvider","children","permissions","initialPermissions","user","initialUser","pathname","router","config","admin","autoLogin","autoRefresh","routes","inactivity","logoutInactivityRoute","userSlug","adminRoute","api","apiRoute","i18n","closeAllModals","openModal","startRouteTransition","setUserInMemory","tokenInMemory","setTokenInMemory","tokenExpirationMs","setTokenExpirationMs","setPermissions","forceLogoutBufferMs","setForceLogoutBufferMs","fetchedUserOnMount","setFetchedUserOnMount","refreshTokenTimeoutRef","useRef","reminderTimeoutRef","forceLogOutTimeoutRef","id","redirectToInactivityRoute","baseAdminRoute","path","replace","window","location","startsWith","encodeURIComponent","revokeTokenAndExpire","undefined","clearTimeout","current","handleReminderTimeout","refreshCookieEvent","setNewUser","userResponse","token","refreshedToken","exp","expiresInMs","Math","max","min","Date","now","nextForceLogoutBufferMs","setTimeout","refreshCookie","forceRefresh","request","post","headers","language","status","json","e","error","message","refreshCookieAsync","skipSetUser","logOut","collection","_","refreshPermissions","locale","params","stringify","addQueryPrefix","get","Error","fetchFullUser","credentials","fetchFullUserEvent","fetchUserOnMount","prefillOnly","_jsx","value","setUser","useAuth"],"sources":["../../../src/providers/Auth/index.tsx"],"sourcesContent":["'use client'\nimport type { AuthenticatedUser, SanitizedPermissions } from 'payload'\n\nimport { useModal } from '@faceless-ui/modal'\nimport { formatAdminURL } from 'payload/shared'\nimport * as qs from 'qs-esm'\nimport React, { createContext, use, useCallback, useEffect, useState } from 'react'\nimport { toast } from 'sonner'\n\nimport { stayLoggedInModalSlug } from '../../elements/StayLoggedIn/index.js'\nimport { useEffectEvent } from '../../hooks/useEffectEvent.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { requests } from '../../utilities/api.js'\nimport { useConfig } from '../Config/index.js'\nimport { usePathname, useRouter } from '../RouterAdapter/index.js'\nimport { useRouteTransition } from '../RouteTransition/index.js'\n\nexport type UserWithToken<T = AuthenticatedUser> = {\n /** seconds until expiration */\n exp: number\n refreshedToken?: string\n token?: string\n user: T\n}\n\nexport type AuthContext<T = AuthenticatedUser> = {\n fetchFullUser: () => Promise<null | T>\n logOut: () => Promise<boolean>\n /**\n * These are the permissions for the current user from a global scope.\n *\n * When checking for permissions on document specific level, use the `useDocumentInfo` hook instead.\n *\n * @example\n *\n * ```tsx\n * import { useAuth } from 'payload/ui'\n *\n * const MyComponent: React.FC = () => {\n * const { permissions } = useAuth()\n *\n * if (permissions?.collections?.myCollection?.create) {\n * // user can create documents in 'myCollection'\n * }\n *\n * return null\n * }\n * ```\n *\n * with useDocumentInfo:\n *\n * ```tsx\n * import { useDocumentInfo } from 'payload/ui'\n *\n * const MyComponent: React.FC = () => {\n * const { docPermissions } = useDocumentInfo()\n * if (docPermissions?.create) {\n * // user can create this document\n * }\n * return null\n * } ```\n */\n permissions?: SanitizedPermissions\n refreshCookie: (forceRefresh?: boolean) => void\n refreshCookieAsync: () => Promise<null | T>\n refreshPermissions: () => Promise<void>\n setPermissions: (permissions: SanitizedPermissions) => void\n setUser: (user: null | UserWithToken<T>) => void\n strategy?: string\n token?: string\n tokenExpirationMs?: number\n user?: null | T\n}\n\nconst Context = createContext({} as AuthContext)\n\nconst maxTimeoutMs = 2147483647\n\ntype Props = {\n children: React.ReactNode\n permissions?: SanitizedPermissions\n user?: AuthenticatedUser | null\n}\n\nexport function AuthProvider({\n children,\n permissions: initialPermissions,\n user: initialUser,\n}: Props) {\n const pathname = usePathname()\n const router = useRouter()\n\n const { config } = useConfig()\n\n const {\n admin: {\n autoLogin,\n autoRefresh,\n routes: { inactivity: logoutInactivityRoute },\n user: userSlug,\n },\n routes: { admin: adminRoute, api: apiRoute },\n } = config\n\n const { i18n } = useTranslation()\n const { closeAllModals, openModal } = useModal()\n const { startRouteTransition } = useRouteTransition()\n\n const [user, setUserInMemory] = useState<AuthenticatedUser | null>(initialUser)\n const [tokenInMemory, setTokenInMemory] = useState<string>()\n const [tokenExpirationMs, setTokenExpirationMs] = useState<number>()\n const [permissions, setPermissions] = useState<SanitizedPermissions>(initialPermissions)\n const [forceLogoutBufferMs, setForceLogoutBufferMs] = useState<number>(120_000)\n const [fetchedUserOnMount, setFetchedUserOnMount] = useState(false)\n\n const refreshTokenTimeoutRef = React.useRef<ReturnType<typeof setTimeout>>(null)\n const reminderTimeoutRef = React.useRef<ReturnType<typeof setTimeout>>(null)\n const forceLogOutTimeoutRef = React.useRef<ReturnType<typeof setTimeout>>(null)\n\n const id = user?.id\n\n const redirectToInactivityRoute = useCallback(() => {\n const baseAdminRoute = formatAdminURL({ adminRoute, path: '' })\n startRouteTransition(() =>\n router.replace(\n formatAdminURL({\n adminRoute,\n path: `${logoutInactivityRoute}${window.location.pathname.startsWith(baseAdminRoute) ? `?redirect=${encodeURIComponent(window.location.pathname)}` : ''}`,\n }),\n ),\n )\n\n closeAllModals()\n }, [router, adminRoute, logoutInactivityRoute, closeAllModals, startRouteTransition])\n\n const revokeTokenAndExpire = useCallback(() => {\n setUserInMemory(null)\n setTokenInMemory(undefined)\n setTokenExpirationMs(undefined)\n clearTimeout(refreshTokenTimeoutRef.current)\n }, [])\n\n // Handler for reminder timeout - uses useEffectEvent to capture latest autoRefresh value\n const handleReminderTimeout = useEffectEvent(() => {\n if (autoRefresh) {\n refreshCookieEvent()\n } else {\n openModal(stayLoggedInModalSlug)\n }\n })\n\n const setNewUser = useCallback(\n (userResponse: null | UserWithToken) => {\n clearTimeout(reminderTimeoutRef.current)\n clearTimeout(forceLogOutTimeoutRef.current)\n\n if (userResponse?.user) {\n setUserInMemory(userResponse.user)\n setTokenInMemory(userResponse.token ?? userResponse.refreshedToken)\n setTokenExpirationMs(userResponse.exp * 1000)\n\n const expiresInMs = Math.max(\n 0,\n Math.min((userResponse.exp ?? 0) * 1000 - Date.now(), maxTimeoutMs),\n )\n\n if (expiresInMs) {\n const nextForceLogoutBufferMs = Math.min(60_000, expiresInMs / 2)\n setForceLogoutBufferMs(nextForceLogoutBufferMs)\n\n reminderTimeoutRef.current = setTimeout(\n handleReminderTimeout,\n Math.max(expiresInMs - nextForceLogoutBufferMs, 0),\n )\n\n forceLogOutTimeoutRef.current = setTimeout(() => {\n revokeTokenAndExpire()\n redirectToInactivityRoute()\n }, expiresInMs)\n }\n } else {\n revokeTokenAndExpire()\n }\n },\n [redirectToInactivityRoute, revokeTokenAndExpire],\n )\n\n const refreshCookie = useCallback(\n (forceRefresh?: boolean) => {\n if (!id) {\n return\n }\n\n const expiresInMs = Math.max(0, (tokenExpirationMs ?? 0) - Date.now())\n\n if (forceRefresh || (tokenExpirationMs && expiresInMs < forceLogoutBufferMs * 2)) {\n clearTimeout(refreshTokenTimeoutRef.current)\n refreshTokenTimeoutRef.current = setTimeout(async () => {\n try {\n const request = await requests.post(\n formatAdminURL({\n apiRoute,\n path: `/${userSlug}/refresh-token?refresh`,\n }),\n {\n headers: {\n 'Accept-Language': i18n.language,\n },\n },\n )\n\n if (request.status === 200) {\n const json: UserWithToken = await request.json()\n setNewUser(json)\n } else {\n setNewUser(null)\n redirectToInactivityRoute()\n }\n } catch (e) {\n toast.error(e.message)\n }\n }, 1000)\n }\n },\n [\n apiRoute,\n i18n.language,\n redirectToInactivityRoute,\n setNewUser,\n tokenExpirationMs,\n userSlug,\n forceLogoutBufferMs,\n id,\n ],\n )\n\n const refreshCookieAsync = useCallback(\n async (skipSetUser?: boolean): Promise<AuthenticatedUser | null> => {\n try {\n const request = await requests.post(\n formatAdminURL({\n apiRoute,\n path: `/${userSlug}/refresh-token`,\n }),\n {\n headers: {\n 'Accept-Language': i18n.language,\n },\n },\n )\n\n if (request.status === 200) {\n const json: UserWithToken = await request.json()\n if (!skipSetUser) {\n setNewUser(json)\n }\n return json.user\n }\n\n if (user) {\n setNewUser(null)\n redirectToInactivityRoute()\n }\n } catch (e) {\n toast.error(`Refreshing token failed: ${e.message}`)\n }\n return null\n },\n [apiRoute, i18n.language, redirectToInactivityRoute, setNewUser, userSlug, user],\n )\n\n const logOut = useCallback(async () => {\n try {\n if (user && user.collection) {\n setNewUser(null)\n await requests.post(\n formatAdminURL({\n apiRoute,\n path: `/${user.collection}/logout`,\n }),\n )\n }\n } catch (_) {\n // fail silently and log the user out in state\n }\n\n return true\n }, [apiRoute, setNewUser, user])\n\n const refreshPermissions = useCallback(\n async ({ locale }: { locale?: string } = {}) => {\n const params = qs.stringify(\n {\n locale,\n },\n {\n addQueryPrefix: true,\n },\n )\n\n try {\n const request = await requests.get(\n formatAdminURL({\n apiRoute,\n path: `/access${params}`,\n }),\n {\n headers: {\n 'Accept-Language': i18n.language,\n },\n },\n )\n\n if (request.status === 200) {\n const json: SanitizedPermissions = await request.json()\n setPermissions(json)\n } else {\n throw new Error(`Fetching permissions failed with status code ${request.status}`)\n }\n } catch (e) {\n toast.error(`Refreshing permissions failed: ${e.message}`)\n }\n },\n [apiRoute, i18n],\n )\n\n const fetchFullUser = React.useCallback(async () => {\n try {\n const request = await requests.get(\n formatAdminURL({\n apiRoute,\n path: `/${userSlug}/me`,\n }),\n {\n credentials: 'include',\n headers: {\n 'Accept-Language': i18n.language,\n },\n },\n )\n\n if (request.status === 200) {\n const json: UserWithToken = await request.json()\n setNewUser(json)\n return json?.user || null\n }\n } catch (e) {\n toast.error(`Fetching user failed: ${e.message}`)\n }\n\n return null\n }, [apiRoute, userSlug, i18n.language, setNewUser])\n\n const refreshCookieEvent = useEffectEvent(refreshCookie)\n useEffect(() => {\n // when location changes, refresh cookie\n refreshCookieEvent()\n }, [pathname])\n\n const fetchFullUserEvent = useEffectEvent(fetchFullUser)\n useEffect(() => {\n async function fetchUserOnMount() {\n await fetchFullUserEvent()\n setFetchedUserOnMount(true)\n }\n\n void fetchUserOnMount()\n }, [])\n\n useEffect(() => {\n if (!user && autoLogin && !autoLogin.prefillOnly) {\n void fetchFullUserEvent()\n }\n }, [user, autoLogin])\n\n useEffect(\n () => () => {\n // remove all timeouts on unmount\n clearTimeout(refreshTokenTimeoutRef.current)\n clearTimeout(reminderTimeoutRef.current)\n clearTimeout(forceLogOutTimeoutRef.current)\n },\n [],\n )\n\n if (!user && !fetchedUserOnMount) {\n return null\n }\n\n return (\n <Context\n value={{\n fetchFullUser,\n logOut,\n permissions,\n refreshCookie,\n refreshCookieAsync,\n refreshPermissions,\n setPermissions,\n setUser: setNewUser,\n token: tokenInMemory,\n tokenExpirationMs,\n user,\n }}\n >\n {children}\n </Context>\n )\n}\n\nexport const useAuth = <T = AuthenticatedUser,>(): AuthContext<T> => use(Context) as AuthContext<T>\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["useModal","formatAdminURL","qs","React","createContext","use","useCallback","useEffect","useState","toast","stayLoggedInModalSlug","useEffectEvent","useTranslation","requests","useConfig","usePathname","useRouter","useSearchParams","useRouteTransition","createAuthSessionRequests","TAB_SESSION_EVENT_TYPES","useTabSessionSync","useAuthSessionTimers","Context","AuthProvider","children","permissions","initialPermissions","user","initialUser","pathname","router","searchParams","route","toString","config","admin","autoLogin","autoRefresh","routes","inactivity","logoutInactivityRoute","login","loginRoute","userSlug","adminRoute","api","apiRoute","i18n","closeAllModals","openModal","startRouteTransition","setUserInMemory","tokenInMemory","setTokenInMemory","authSession","setAuthSession","setPermissions","fetchedUserOnMount","setFetchedUserOnMount","authRequests","userRef","useRef","isAuthenticated","Boolean","redirectToInactivityRoute","baseAdminRoute","path","replace","window","location","startsWith","encodeURIComponent","redirectToLoginRoute","onSessionActivity","currentAuthSession","activityRecorded","onSessionActivityRefresh","refreshSession","isActivityRefresh","onSessionExpiration","expirationMs","collection","current","tabSessionSync","broadcast","type","EXPIRED","expiredTokenAt","logOutSession","then","onSessionReminder","sessionTimers","scheduleRefresh","onActivity","onActivityRefresh","onExpire","onReminder","recordActivity","clearUserInMemory","undefined","clear","setLocalSession","session","exp","Number","isFinite","nextSessionTiming","setExpiration","token","refreshedToken","setUser","discardPendingResults","getTokenExpirationMs","getCurrentExpirationMs","onSessionExpired","onSessionLoggedOut","onSessionRefreshed","isLoggingOut","onTabSessionUnauthenticated","reconcileSession","options","result","fetchFullUserResult","status","refresh","acceptResult","invalidateWhenIdle","isResultStale","handledExpiration","handledUser","refreshStartedAt","Date","now","request","post","headers","language","json","REFRESHED","invalidateSession","e","error","message","refreshCookieAsync","logOut","clearSession","_","logoutEvent","LOGGED_OUT","logoutPublication","broadcastLogoutSettlement","refreshPermissions","locale","params","stringify","addQueryPrefix","get","Error","isTabSessionEventStale","queue","isResponseStale","credentials","fetchFullUser","fetchFullUserEvent","fetchUserOnMount","prefillOnly","_jsx","value","refreshCookie","useAuth"],"sources":["../../../src/providers/Auth/index.tsx"],"sourcesContent":["'use client'\nimport type { AuthenticatedUser, SanitizedPermissions } from 'payload'\n\nimport { useModal } from '@faceless-ui/modal'\nimport { formatAdminURL } from 'payload/shared'\nimport * as qs from 'qs-esm'\nimport React, { createContext, use, useCallback, useEffect, useState } from 'react'\nimport { toast } from 'sonner'\n\nimport type { TabSessionReconciliationOptions } from './tabSessionSync/index.js'\nimport type { AuthContext, AuthSession, UserWithToken } from './types.js'\n\nimport { stayLoggedInModalSlug } from '../../elements/StayLoggedIn/index.js'\nimport { useEffectEvent } from '../../hooks/useEffectEvent.js'\nimport { useTranslation } from '../../providers/Translation/index.js'\nimport { requests } from '../../utilities/api.js'\nimport { useConfig } from '../Config/index.js'\nimport { usePathname, useRouter, useSearchParams } from '../RouterAdapter/index.js'\nimport { useRouteTransition } from '../RouteTransition/index.js'\nimport { createAuthSessionRequests } from './authSessionRequests.js'\nimport { TAB_SESSION_EVENT_TYPES } from './tabSessionSync/index.js'\nimport { useTabSessionSync } from './tabSessionSync/useTabSessionSync.js'\nimport { useAuthSessionTimers } from './useAuthSessionTimers.js'\n\nexport type { AuthContext, AuthSession, UserWithToken } from './types.js'\n\nconst Context = createContext({} as AuthContext)\n\ntype Props = {\n children: React.ReactNode\n permissions?: SanitizedPermissions\n user?: AuthenticatedUser | null\n}\n\ntype FetchFullUserResult =\n | {\n expirationMs?: number\n status: 'authenticated'\n user: AuthenticatedUser\n }\n | {\n status: 'indeterminate'\n }\n | {\n status: 'unauthenticated'\n }\n\ntype UserResponse = {\n exp?: number\n refreshedToken?: string\n token?: string\n user?: AuthenticatedUser | null\n}\n\nexport function AuthProvider({\n children,\n permissions: initialPermissions,\n user: initialUser,\n}: Props) {\n const pathname = usePathname()\n const router = useRouter()\n const searchParams = useSearchParams()\n const route = `${pathname}?${searchParams.toString()}`\n\n const { config } = useConfig()\n\n const {\n admin: {\n autoLogin,\n autoRefresh,\n routes: { inactivity: logoutInactivityRoute, login: loginRoute },\n user: userSlug,\n },\n routes: { admin: adminRoute, api: apiRoute },\n } = config\n\n const { i18n } = useTranslation()\n const { closeAllModals, openModal } = useModal()\n const { startRouteTransition } = useRouteTransition()\n\n const [user, setUserInMemory] = useState<AuthenticatedUser | null>(initialUser)\n const [tokenInMemory, setTokenInMemory] = useState<string>()\n const [authSession, setAuthSession] = useState<AuthSession>()\n const [permissions, setPermissions] = useState<SanitizedPermissions>(initialPermissions)\n const [fetchedUserOnMount, setFetchedUserOnMount] = useState(false)\n\n const [authRequests] = useState(createAuthSessionRequests)\n const userRef = React.useRef<AuthenticatedUser | null>(initialUser)\n\n const isAuthenticated = Boolean(user)\n\n const redirectToInactivityRoute = useCallback(() => {\n const baseAdminRoute = formatAdminURL({ adminRoute, path: '' })\n startRouteTransition(() =>\n router.replace(\n formatAdminURL({\n adminRoute,\n path: `${logoutInactivityRoute}${window.location.pathname.startsWith(baseAdminRoute) ? `?redirect=${encodeURIComponent(window.location.pathname)}` : ''}`,\n }),\n ),\n )\n\n closeAllModals()\n }, [router, adminRoute, logoutInactivityRoute, closeAllModals, startRouteTransition])\n\n const redirectToLoginRoute = useCallback(() => {\n startRouteTransition(() =>\n router.replace(\n formatAdminURL({\n adminRoute,\n path: loginRoute,\n }),\n ),\n )\n\n closeAllModals()\n }, [adminRoute, closeAllModals, loginRoute, router, startRouteTransition])\n\n function onSessionActivity() {\n setAuthSession((currentAuthSession) => {\n if (!currentAuthSession || currentAuthSession.activityRecorded) {\n return currentAuthSession\n }\n\n return {\n ...currentAuthSession,\n activityRecorded: true,\n }\n })\n }\n\n function onSessionActivityRefresh() {\n void refreshSession({ isActivityRefresh: true })\n }\n\n function onSessionExpiration(expirationMs: number) {\n const collection = userRef.current?.collection\n\n tabSessionSync.broadcast({\n type: TAB_SESSION_EVENT_TYPES.EXPIRED,\n expiredTokenAt: expirationMs,\n })\n void logOutSession({ collection }).then(redirectToInactivityRoute)\n }\n\n function onSessionReminder() {\n if (autoRefresh) {\n sessionTimers.scheduleRefresh()\n } else {\n openModal(stayLoggedInModalSlug)\n }\n }\n\n const sessionTimers = useAuthSessionTimers({\n isAuthenticated,\n onActivity: onSessionActivity,\n onActivityRefresh: onSessionActivityRefresh,\n onExpire: onSessionExpiration,\n onReminder: onSessionReminder,\n })\n\n useEffect(() => {\n sessionTimers.recordActivity('route')\n }, [route, sessionTimers])\n\n const clearUserInMemory = useCallback(() => {\n userRef.current = null\n setUserInMemory(null)\n setTokenInMemory(undefined)\n setAuthSession(undefined)\n sessionTimers.clear()\n }, [sessionTimers])\n\n const setLocalSession = useCallback(\n (session: null | UserResponse) => {\n if (session?.user) {\n const expirationMs =\n typeof session.exp === 'number' && Number.isFinite(session.exp)\n ? session.exp * 1000\n : undefined\n const nextSessionTiming =\n expirationMs !== undefined ? sessionTimers.setExpiration(expirationMs) : undefined\n\n userRef.current = session.user\n setUserInMemory(session.user)\n setTokenInMemory(session.token ?? session.refreshedToken)\n\n if (nextSessionTiming) {\n setAuthSession({\n ...nextSessionTiming,\n activityRecorded: false,\n })\n }\n } else {\n clearUserInMemory()\n }\n },\n [clearUserInMemory, sessionTimers],\n )\n\n const setUser = useCallback(\n (session: null | UserWithToken) => {\n authRequests.discardPendingResults()\n setLocalSession(session)\n },\n [authRequests, setLocalSession],\n )\n\n const tabSessionSync = useTabSessionSync({\n getTokenExpirationMs: sessionTimers.getCurrentExpirationMs,\n onSessionExpired: () => {\n const collection = userRef.current?.collection\n\n void logOutSession({ collection }).then(redirectToInactivityRoute)\n },\n onSessionLoggedOut: () => {\n const collection = userRef.current?.collection\n\n void logOutSession({ collection }).then(redirectToLoginRoute)\n },\n onSessionRefreshed: (session) => {\n if (!authRequests.isLoggingOut()) {\n authRequests.discardPendingResults()\n setLocalSession(session)\n }\n },\n onTabSessionUnauthenticated: () => {\n redirectToInactivityRoute()\n },\n reconcileSession: async (options) => {\n const result = await fetchFullUserResult(options)\n\n if (result.status === 'authenticated' && result.expirationMs !== undefined) {\n return {\n expirationMs: result.expirationMs,\n status: result.status,\n user: result.user,\n }\n }\n\n if (result.status === 'unauthenticated') {\n return result\n }\n\n return { status: 'indeterminate' }\n },\n })\n\n const refreshSession = useCallback(\n ({ isActivityRefresh }: { isActivityRefresh: boolean }): Promise<AuthenticatedUser | null> => {\n return authRequests.refresh(async ({ acceptResult, invalidateWhenIdle, isResultStale }) => {\n if (isResultStale()) {\n return null\n }\n\n const handledExpiration = sessionTimers.getCurrentExpirationMs()\n const handledUser = userRef.current\n\n try {\n const refreshStartedAt = Date.now()\n const request = await requests.post(\n formatAdminURL({\n apiRoute,\n path: `/${userSlug}/refresh-token${isActivityRefresh ? '?refresh' : ''}`,\n }),\n {\n headers: {\n 'Accept-Language': i18n.language,\n },\n },\n )\n\n if (isResultStale()) {\n return null\n }\n\n if (request.status === 200) {\n const json: UserWithToken = await request.json()\n\n if (!acceptResult()) {\n return null\n }\n\n setLocalSession(json)\n tabSessionSync.broadcast({\n type: TAB_SESSION_EVENT_TYPES.REFRESHED,\n refreshStartedAt,\n session: json,\n })\n return json.user\n }\n\n if (handledUser) {\n const invalidateSession = () => {\n if (handledExpiration !== undefined) {\n tabSessionSync.broadcast({\n type: TAB_SESSION_EVENT_TYPES.EXPIRED,\n expiredTokenAt: handledExpiration,\n })\n }\n\n setLocalSession(null)\n redirectToInactivityRoute()\n }\n\n invalidateWhenIdle(invalidateSession)\n }\n } catch (e) {\n toast.error(`Refreshing token failed: ${e.message}`)\n }\n\n return null\n })\n },\n [\n apiRoute,\n authRequests,\n tabSessionSync,\n i18n.language,\n redirectToInactivityRoute,\n sessionTimers,\n setLocalSession,\n userSlug,\n ],\n )\n\n const refreshCookieAsync = useCallback(\n (): Promise<AuthenticatedUser | null> => refreshSession({ isActivityRefresh: false }),\n [refreshSession],\n )\n\n const logOutSession = useCallback(\n ({ collection }: { collection?: string }): Promise<void> => {\n return authRequests.logOut({\n clearSession: () => {\n authRequests.discardPendingResults()\n setLocalSession(null)\n },\n request: async () => {\n try {\n if (collection) {\n await requests.post(\n formatAdminURL({\n apiRoute,\n path: `/${collection}/logout`,\n }),\n )\n }\n } catch (_) {\n // Explicit logout always clears local state, even if server revocation fails.\n }\n },\n })\n },\n [apiRoute, authRequests, setLocalSession],\n )\n\n const logOut = useCallback(async () => {\n const logoutEvent = { type: TAB_SESSION_EVENT_TYPES.LOGGED_OUT } as const\n const logoutPublication = tabSessionSync.broadcast(logoutEvent)\n const collection = userRef.current?.collection\n\n await logOutSession({ collection })\n\n if (logoutPublication?.type === TAB_SESSION_EVENT_TYPES.LOGGED_OUT) {\n tabSessionSync.broadcastLogoutSettlement(logoutPublication)\n }\n\n return true\n }, [tabSessionSync, logOutSession])\n\n const refreshPermissions = useCallback(\n async ({ locale }: { locale?: string } = {}) => {\n const params = qs.stringify(\n {\n locale,\n },\n {\n addQueryPrefix: true,\n },\n )\n\n try {\n const request = await requests.get(\n formatAdminURL({\n apiRoute,\n path: `/access${params}`,\n }),\n {\n headers: {\n 'Accept-Language': i18n.language,\n },\n },\n )\n\n if (request.status === 200) {\n const json: SanitizedPermissions = await request.json()\n setPermissions(json)\n } else {\n throw new Error(`Fetching permissions failed with status code ${request.status}`)\n }\n } catch (e) {\n toast.error(`Refreshing permissions failed: ${e.message}`)\n }\n },\n [apiRoute, i18n],\n )\n\n const fetchFullUserResult = React.useCallback(\n ({\n isTabSessionEventStale,\n }: Partial<TabSessionReconciliationOptions> = {}): Promise<FetchFullUserResult> => {\n return authRequests.queue(async ({ acceptResult, isResultStale }) => {\n const isResponseStale = () => isResultStale() || Boolean(isTabSessionEventStale?.())\n\n if (isResponseStale()) {\n return { status: 'indeterminate' }\n }\n\n try {\n const request = await requests.get(\n formatAdminURL({\n apiRoute,\n path: `/${userSlug}/me`,\n }),\n {\n credentials: 'include',\n headers: {\n 'Accept-Language': i18n.language,\n },\n },\n )\n\n if (request.status !== 200) {\n return { status: 'indeterminate' }\n }\n\n const json: null | UserResponse = await request.json()\n\n if (isResponseStale()) {\n return { status: 'indeterminate' }\n }\n\n if (json?.user) {\n if (!acceptResult()) {\n return { status: 'indeterminate' }\n }\n\n setLocalSession(json)\n\n return {\n expirationMs:\n typeof json.exp === 'number' && Number.isFinite(json.exp)\n ? json.exp * 1000\n : sessionTimers.getCurrentExpirationMs(),\n status: 'authenticated',\n user: json.user,\n }\n }\n\n setLocalSession(null)\n\n return { status: 'unauthenticated' }\n } catch (e) {\n toast.error(`Fetching user failed: ${e.message}`)\n }\n\n return { status: 'indeterminate' }\n })\n },\n [apiRoute, authRequests, i18n.language, sessionTimers, setLocalSession, userSlug],\n )\n\n const fetchFullUser = React.useCallback(async (): Promise<AuthenticatedUser | null> => {\n const result = await fetchFullUserResult()\n\n return result.status === 'authenticated' ? result.user : null\n }, [fetchFullUserResult])\n\n const fetchFullUserEvent = useEffectEvent(fetchFullUser)\n\n useEffect(() => {\n async function fetchUserOnMount() {\n await fetchFullUserEvent()\n setFetchedUserOnMount(true)\n }\n\n void fetchUserOnMount()\n }, [])\n\n useEffect(() => {\n if (!user && autoLogin && !autoLogin.prefillOnly) {\n void fetchFullUserEvent()\n }\n }, [user, autoLogin])\n\n useEffect(\n () => () => {\n authRequests.discardPendingResults()\n },\n [authRequests],\n )\n\n if (!user && !fetchedUserOnMount) {\n return null\n }\n\n return (\n <Context\n value={{\n authSession,\n fetchFullUser,\n logOut,\n permissions,\n refreshCookie: sessionTimers.scheduleRefresh,\n refreshCookieAsync,\n refreshPermissions,\n setPermissions,\n setUser,\n token: tokenInMemory,\n user,\n }}\n >\n {children}\n </Context>\n )\n}\n\nexport const useAuth = <T = AuthenticatedUser,>(): AuthContext<T> => use(Context) as AuthContext<T>\n"],"mappings":"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","ignoreList":[]}
|