@sourceregistry/sveltekit-oidc 1.6.13 → 1.7.0
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/README.md +11 -1
- package/dist/client/OIDCContext.svelte +45 -7
- package/dist/client/OIDCContext.svelte.d.ts +5 -0
- package/dist/client/context.d.ts +1 -0
- package/dist/server/index.js +44 -5
- package/dist/server/types.d.ts +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -147,9 +147,19 @@ export async function load(event) {
|
|
|
147
147
|
|
|
148
148
|
- local expiry redirects
|
|
149
149
|
- `check_session_iframe` polling when the provider advertises it
|
|
150
|
-
-
|
|
150
|
+
- targeted session revalidation when a token reaches its renewal window
|
|
151
|
+
- optional periodic session revalidation when `revalidateIntervalMs` is explicitly configured
|
|
151
152
|
- a client context for nested auth-aware components through `useOIDC()` / `getOIDCContext()`
|
|
152
153
|
|
|
154
|
+
`oidc.getPublicSession(event)` automatically registers the `oidc:session` dependency used by
|
|
155
|
+
`OIDCContext`, so the standard setup above does not re-run unrelated page loads. If you destructure
|
|
156
|
+
the load event, pass both `cookies` and `depends`: `oidc.getPublicSession({cookies, depends})`.
|
|
157
|
+
|
|
158
|
+
Periodic revalidation is disabled by default to avoid unnecessary page updates. Set
|
|
159
|
+
`revalidateIntervalMs` to a positive interval only when you need polling in addition to token-expiry
|
|
160
|
+
and provider session monitoring. Existing integrations that pass only `cookies` remain compatible;
|
|
161
|
+
their expiry-driven revalidation falls back to `invalidateAll()`.
|
|
162
|
+
|
|
153
163
|
Set `monitorSession={false}` when you want to keep the client context but leave remote session
|
|
154
164
|
revocation checks to your server-side guard or another mechanism. This disables
|
|
155
165
|
`check_session_iframe` polling without changing the provider metadata exposed through the context.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
8
|
<script lang="ts" generics="TClaims extends OIDCUserClaims = OIDCUserClaims">
|
|
9
|
-
import {
|
|
9
|
+
import {beforeNavigate, invalidate, invalidateAll} from '$app/navigation';
|
|
10
10
|
import {tick} from 'svelte';
|
|
11
11
|
import type {Snippet} from 'svelte';
|
|
12
12
|
|
|
@@ -14,18 +14,24 @@
|
|
|
14
14
|
|
|
15
15
|
type RedirectMode = 'login' | 'logout' | 'reload' | 'none';
|
|
16
16
|
|
|
17
|
+
type OIDCClientDebugEvent = {
|
|
18
|
+
type: string;
|
|
19
|
+
details?: Record<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
|
|
17
22
|
let {
|
|
18
23
|
session = null,
|
|
19
24
|
config,
|
|
20
25
|
loginPath,
|
|
21
|
-
logoutPath
|
|
26
|
+
logoutPath,
|
|
22
27
|
checkSessionIntervalMs = 5000,
|
|
23
28
|
monitorSession = true,
|
|
24
|
-
revalidateIntervalMs =
|
|
29
|
+
revalidateIntervalMs = 0,
|
|
25
30
|
renewalLeadTimeMs = 5000,
|
|
26
31
|
redirectOnExpired = 'login',
|
|
27
32
|
redirectOnRevoked = 'login',
|
|
28
33
|
redirectIfUnauthenticated = false,
|
|
34
|
+
onDebug,
|
|
29
35
|
children
|
|
30
36
|
}: {
|
|
31
37
|
session?: OIDCPublicSession<TClaims> | null;
|
|
@@ -39,6 +45,8 @@
|
|
|
39
45
|
redirectOnExpired?: RedirectMode;
|
|
40
46
|
redirectOnRevoked?: RedirectMode;
|
|
41
47
|
redirectIfUnauthenticated?: boolean;
|
|
48
|
+
/** Receives token-safe lifecycle events for diagnosing session changes. */
|
|
49
|
+
onDebug?: (event: OIDCClientDebugEvent) => void;
|
|
42
50
|
children?: Snippet;
|
|
43
51
|
} = $props();
|
|
44
52
|
|
|
@@ -48,8 +56,13 @@
|
|
|
48
56
|
let handledUnauthenticated = $state(false);
|
|
49
57
|
let sessionExpiredDuringRevalidation = false;
|
|
50
58
|
|
|
59
|
+
function debug(type: string, details?: Record<string, unknown>) {
|
|
60
|
+
onDebug?.({type, details});
|
|
61
|
+
}
|
|
62
|
+
|
|
51
63
|
const metadata = $derived(config.metadata);
|
|
52
64
|
const resolvedLoginPath = $derived(loginPath ?? config.loginPath ?? '/auth/login');
|
|
65
|
+
const resolvedLogoutPath = $derived(logoutPath ?? config.logoutPath ?? '/auth/logout');
|
|
53
66
|
const iframeUrl = $derived(
|
|
54
67
|
config.metadata.check_session_iframe ?? config.checkSessionIframe ?? undefined
|
|
55
68
|
);
|
|
@@ -73,6 +86,9 @@
|
|
|
73
86
|
get groups() {
|
|
74
87
|
return session?.groups ?? [];
|
|
75
88
|
},
|
|
89
|
+
get issuer() {
|
|
90
|
+
return config.issuer;
|
|
91
|
+
},
|
|
76
92
|
get metadata() {
|
|
77
93
|
return metadata;
|
|
78
94
|
},
|
|
@@ -93,6 +109,7 @@
|
|
|
93
109
|
// Only intercept login redirects while a background revalidation is active.
|
|
94
110
|
beforeNavigate(({to, cancel}) => {
|
|
95
111
|
if (revalidating && to?.url.pathname.startsWith(resolvedLoginPath)) {
|
|
112
|
+
debug('revalidation_redirected_to_login', {pathname: to.url.pathname});
|
|
96
113
|
cancel();
|
|
97
114
|
sessionExpiredDuringRevalidation = true;
|
|
98
115
|
}
|
|
@@ -104,10 +121,11 @@
|
|
|
104
121
|
|
|
105
122
|
async function logout(clearSessionOnly = false) {
|
|
106
123
|
if (clearSessionOnly) {
|
|
124
|
+
debug('local_session_logout_requested');
|
|
107
125
|
// Session-monitor events must clear only this application's session.
|
|
108
126
|
// Keep the flag in the URL because logoutHandler also supports callers
|
|
109
127
|
// that do not send a form body.
|
|
110
|
-
const url = new URL(
|
|
128
|
+
const url = new URL(resolvedLogoutPath, window.location.href);
|
|
111
129
|
url.searchParams.set('clearSessionOnly', '1');
|
|
112
130
|
|
|
113
131
|
await fetch(url, {
|
|
@@ -122,20 +140,25 @@
|
|
|
122
140
|
// session intact and allowing the app to immediately sign in again.
|
|
123
141
|
const form = document.createElement('form');
|
|
124
142
|
form.method = 'POST';
|
|
125
|
-
form.action =
|
|
143
|
+
form.action = resolvedLogoutPath;
|
|
126
144
|
form.style.display = 'none';
|
|
127
145
|
document.body.append(form);
|
|
128
146
|
form.submit();
|
|
129
147
|
}
|
|
130
148
|
|
|
131
149
|
function login(returnTo?: string) {
|
|
150
|
+
debug('login_redirect_requested', {returnTo: returnTo ?? `${window.location.pathname}${window.location.search}`});
|
|
132
151
|
// loginPath is a plain +server.ts redirect endpoint, not a routable
|
|
133
152
|
// page — use a full browser navigation, not SvelteKit's goto().
|
|
134
153
|
window.location.href = buildLoginUrl(returnTo);
|
|
135
154
|
}
|
|
136
155
|
|
|
137
156
|
async function revalidate() {
|
|
138
|
-
if (revalidating)
|
|
157
|
+
if (revalidating) {
|
|
158
|
+
debug('revalidation_skipped_in_flight');
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
debug('revalidation_started', {expiresAt: session?.expiresAt});
|
|
139
162
|
revalidating = true;
|
|
140
163
|
|
|
141
164
|
// If the server redirects to the login path during a background
|
|
@@ -144,14 +167,25 @@
|
|
|
144
167
|
sessionExpiredDuringRevalidation = false;
|
|
145
168
|
|
|
146
169
|
try {
|
|
147
|
-
|
|
170
|
+
if (session?.revalidationDependency) {
|
|
171
|
+
debug('revalidation_dependency_invalidated', {
|
|
172
|
+
dependency: session.revalidationDependency
|
|
173
|
+
});
|
|
174
|
+
await invalidate(session.revalidationDependency);
|
|
175
|
+
} else {
|
|
176
|
+
debug('revalidation_fallback_invalidated_all');
|
|
177
|
+
await invalidateAll();
|
|
178
|
+
}
|
|
148
179
|
} finally {
|
|
149
180
|
revalidating = false;
|
|
150
181
|
}
|
|
151
182
|
|
|
152
183
|
if (sessionExpiredDuringRevalidation) {
|
|
153
184
|
status = 'expired';
|
|
185
|
+
debug('revalidation_session_expired');
|
|
154
186
|
void handleRedirect(redirectOnExpired);
|
|
187
|
+
} else {
|
|
188
|
+
debug('revalidation_completed', {isAuthenticated: Boolean(session?.isAuthenticated), expiresAt: session?.expiresAt});
|
|
155
189
|
}
|
|
156
190
|
}
|
|
157
191
|
|
|
@@ -199,6 +233,7 @@
|
|
|
199
233
|
session.expiresAt * 1000 <= Date.now()
|
|
200
234
|
) {
|
|
201
235
|
status = 'expired';
|
|
236
|
+
debug('session_expired_after_failed_renewal', {expiresAt: session.expiresAt});
|
|
202
237
|
void handleRedirect(redirectOnExpired);
|
|
203
238
|
return;
|
|
204
239
|
}
|
|
@@ -208,6 +243,7 @@
|
|
|
208
243
|
const leadTimeMs = renewalAttemptedForExpiresAt === expiresAt ? 0 : renewalLeadTimeMs;
|
|
209
244
|
const timeoutMs = Math.max(0, expiresAt * 1000 - Date.now() - leadTimeMs);
|
|
210
245
|
const timer = window.setTimeout(async () => {
|
|
246
|
+
debug('token_renewal_due', {expiresAt});
|
|
211
247
|
// Silent revalidate first — server's maybeRefreshSession will refresh
|
|
212
248
|
// the token if a valid refresh_token exists. Only redirect if the
|
|
213
249
|
// session comes back unauthenticated after that.
|
|
@@ -216,6 +252,7 @@
|
|
|
216
252
|
await tick();
|
|
217
253
|
if (!session?.isAuthenticated) {
|
|
218
254
|
status = 'expired';
|
|
255
|
+
debug('token_renewal_left_session_unauthenticated');
|
|
219
256
|
void handleRedirect(redirectOnExpired);
|
|
220
257
|
}
|
|
221
258
|
}, timeoutMs);
|
|
@@ -268,6 +305,7 @@
|
|
|
268
305
|
return;
|
|
269
306
|
}
|
|
270
307
|
if (event.data === 'changed' || event.data === 'error') {
|
|
308
|
+
debug('iframe_session_event', {result: event.data, origin: event.origin});
|
|
271
309
|
status = 'revoked';
|
|
272
310
|
void logout(true).then(() => handleRedirect(redirectOnRevoked));
|
|
273
311
|
}
|
|
@@ -13,6 +13,11 @@ declare function $$render<TClaims extends OIDCUserClaims = OIDCUserClaims>(): {
|
|
|
13
13
|
redirectOnExpired?: "none" | "login" | "logout" | "reload";
|
|
14
14
|
redirectOnRevoked?: "none" | "login" | "logout" | "reload";
|
|
15
15
|
redirectIfUnauthenticated?: boolean;
|
|
16
|
+
/** Receives token-safe lifecycle events for diagnosing session changes. */
|
|
17
|
+
onDebug?: (event: {
|
|
18
|
+
type: string;
|
|
19
|
+
details?: Record<string, unknown>;
|
|
20
|
+
}) => void;
|
|
16
21
|
children?: Snippet;
|
|
17
22
|
};
|
|
18
23
|
exports: {};
|
package/dist/client/context.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type OIDCClientContextValue<TClaims extends OIDCUserClaims = OIDCUserClai
|
|
|
8
8
|
user: OIDCPublicSession<TClaims>['user'];
|
|
9
9
|
claims: OIDCPublicSession<TClaims>['claims'];
|
|
10
10
|
groups: OIDCPublicSession<TClaims>['groups'];
|
|
11
|
+
issuer: string;
|
|
11
12
|
metadata?: Pick<OIDCDiscoveryDocument, 'issuer' | 'check_session_iframe' | 'end_session_endpoint' | 'backchannel_logout_supported' | 'backchannel_logout_session_supported'>;
|
|
12
13
|
status: 'authenticated' | 'unauthenticated' | 'expired' | 'revoked';
|
|
13
14
|
revalidating: boolean;
|
package/dist/server/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { isSessionExpired, normalizeTokens, shouldRefresh } from './session.js';
|
|
|
7
7
|
import { absoluteUrl, base64UrlEncode, buildCookieOptions, collectGroups, createPKCEPair, internalRedirectPath, normalizeIssuer, normalizeScope, parseProviderError, toPublicSession, validateIdTokenClaims, validateUserInfoSubject } from './utils.js';
|
|
8
8
|
import { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
9
9
|
export { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
10
|
+
const OIDC_SESSION_REVALIDATION_DEPENDENCY = 'oidc:session';
|
|
10
11
|
function buildLogger(logger) {
|
|
11
12
|
const noop = () => {
|
|
12
13
|
};
|
|
@@ -46,6 +47,7 @@ export function createOIDC(options) {
|
|
|
46
47
|
const stateCookieName = options.stateCookieName ?? 'oidc_auth_state';
|
|
47
48
|
const defaultScope = normalizeScope(options.scope);
|
|
48
49
|
const loginPath = options.loginPath ?? '/auth/login';
|
|
50
|
+
const logoutPath = options.logoutPath ?? '/auth/logout';
|
|
49
51
|
const redirectPath = options.redirectPath ?? '/auth/callback';
|
|
50
52
|
const clientAuthMethod = options.clientAuthMethod ?? (options.clientSecret ? 'client_secret_basic' : 'none');
|
|
51
53
|
const fetchImpl = options.fetch ?? fetch;
|
|
@@ -59,10 +61,12 @@ export function createOIDC(options) {
|
|
|
59
61
|
}
|
|
60
62
|
const reference = cookieStore.readSessionReference(cookies);
|
|
61
63
|
if (!reference?.id) {
|
|
64
|
+
log.debug('No OIDC session reference cookie is present');
|
|
62
65
|
return null;
|
|
63
66
|
}
|
|
64
67
|
const session = await sessionStore.get(reference.id);
|
|
65
68
|
if (!session) {
|
|
69
|
+
log.debug('OIDC session reference has no matching persisted session');
|
|
66
70
|
cookieStore.clearSessionReference(cookies);
|
|
67
71
|
return null;
|
|
68
72
|
}
|
|
@@ -278,10 +282,24 @@ export function createOIDC(options) {
|
|
|
278
282
|
return null;
|
|
279
283
|
}
|
|
280
284
|
if (isSessionExpired(session, sessionMaxAgeSeconds)) {
|
|
285
|
+
const now = Math.floor(Date.now() / 1000);
|
|
286
|
+
log.debug('OIDC session expired — clearing session', {
|
|
287
|
+
reason: session.createdAt + sessionMaxAgeSeconds <= now
|
|
288
|
+
? 'session_max_age'
|
|
289
|
+
: 'access_token_expired_without_refresh_token',
|
|
290
|
+
createdAt: session.createdAt,
|
|
291
|
+
expiresAt: session.tokens.expiresAt,
|
|
292
|
+
refreshExpiresAt: session.tokens.refreshExpiresAt,
|
|
293
|
+
hasRefreshToken: Boolean(session.tokens.refreshToken)
|
|
294
|
+
});
|
|
281
295
|
await clearPersistedSession(cookies, persisted?.id);
|
|
282
296
|
return null;
|
|
283
297
|
}
|
|
284
298
|
if (await isRevoked(session)) {
|
|
299
|
+
log.debug('OIDC session was revoked by back-channel logout — clearing session', {
|
|
300
|
+
hasSid: Boolean(session.sid),
|
|
301
|
+
hasSubject: Boolean(session.sub)
|
|
302
|
+
});
|
|
285
303
|
await clearPersistedSession(cookies, persisted?.id);
|
|
286
304
|
return null;
|
|
287
305
|
}
|
|
@@ -289,6 +307,10 @@ export function createOIDC(options) {
|
|
|
289
307
|
return session;
|
|
290
308
|
}
|
|
291
309
|
try {
|
|
310
|
+
log.debug('Refreshing OIDC session tokens', {
|
|
311
|
+
expiresAt: session.tokens.expiresAt,
|
|
312
|
+
refreshExpiresAt: session.tokens.refreshExpiresAt
|
|
313
|
+
});
|
|
292
314
|
const tokenResponse = await refreshTokens(session.tokens.refreshToken);
|
|
293
315
|
const claims = tokenResponse.id_token
|
|
294
316
|
? await validateIdToken(tokenResponse.id_token, session.nonce)
|
|
@@ -320,6 +342,11 @@ export function createOIDC(options) {
|
|
|
320
342
|
})
|
|
321
343
|
: nextSession;
|
|
322
344
|
await writePersistedSession(cookies, finalSession, persisted?.id);
|
|
345
|
+
log.debug('OIDC session tokens refreshed', {
|
|
346
|
+
expiresAt: finalSession.tokens.expiresAt,
|
|
347
|
+
refreshExpiresAt: finalSession.tokens.refreshExpiresAt,
|
|
348
|
+
hasRefreshToken: Boolean(finalSession.tokens.refreshToken)
|
|
349
|
+
});
|
|
323
350
|
return finalSession;
|
|
324
351
|
}
|
|
325
352
|
catch (err) {
|
|
@@ -329,7 +356,11 @@ export function createOIDC(options) {
|
|
|
329
356
|
}
|
|
330
357
|
}
|
|
331
358
|
async function getSession(event) {
|
|
332
|
-
|
|
359
|
+
const session = await maybeRefreshSession(event.cookies, await readPersistedSession(event.cookies));
|
|
360
|
+
if (!session || !options.enrichSession) {
|
|
361
|
+
return session;
|
|
362
|
+
}
|
|
363
|
+
return options.enrichSession(session, { event: event });
|
|
333
364
|
}
|
|
334
365
|
async function signIn(event, loginOptions = {}) {
|
|
335
366
|
const metadata = await getMetadata();
|
|
@@ -440,6 +471,9 @@ export function createOIDC(options) {
|
|
|
440
471
|
if (session?.tokens.idToken) {
|
|
441
472
|
url.searchParams.set('id_token_hint', session.tokens.idToken);
|
|
442
473
|
}
|
|
474
|
+
// The provider needs client context to validate the post-logout URI
|
|
475
|
+
// even when the local session (and therefore id_token_hint) is gone.
|
|
476
|
+
url.searchParams.set('client_id', options.clientId);
|
|
443
477
|
url.searchParams.set('post_logout_redirect_uri', absoluteUrl(event, postLogoutRedirectPath));
|
|
444
478
|
if (logoutOptions.state) {
|
|
445
479
|
url.searchParams.set('state', logoutOptions.state);
|
|
@@ -530,9 +564,6 @@ export function createOIDC(options) {
|
|
|
530
564
|
}
|
|
531
565
|
function logoutHandler(defaults = {}) {
|
|
532
566
|
return async (event) => {
|
|
533
|
-
if (event.request.method !== 'POST') {
|
|
534
|
-
throw error(405, { message: 'Logout requires POST' });
|
|
535
|
-
}
|
|
536
567
|
const form = await event.request.formData().catch(() => null);
|
|
537
568
|
const postLogoutRedirectUri = event.url.searchParams.get('postLogoutRedirectUri') ??
|
|
538
569
|
form?.get('postLogoutRedirectUri')?.toString() ??
|
|
@@ -570,7 +601,9 @@ export function createOIDC(options) {
|
|
|
570
601
|
const metadata = await getMetadata();
|
|
571
602
|
return {
|
|
572
603
|
clientId: options.clientId,
|
|
604
|
+
issuer: metadata.issuer,
|
|
573
605
|
loginPath,
|
|
606
|
+
logoutPath,
|
|
574
607
|
redirectPath,
|
|
575
608
|
metadata: {
|
|
576
609
|
issuer: metadata.issuer,
|
|
@@ -590,7 +623,13 @@ export function createOIDC(options) {
|
|
|
590
623
|
hook,
|
|
591
624
|
getMetadata,
|
|
592
625
|
getSession,
|
|
593
|
-
getPublicSession: async (event) =>
|
|
626
|
+
getPublicSession: async (event) => {
|
|
627
|
+
event.depends?.(OIDC_SESSION_REVALIDATION_DEPENDENCY);
|
|
628
|
+
const session = toPublicSession(await getSession(event));
|
|
629
|
+
return session && event.depends
|
|
630
|
+
? { ...session, revalidationDependency: OIDC_SESSION_REVALIDATION_DEPENDENCY }
|
|
631
|
+
: session;
|
|
632
|
+
},
|
|
594
633
|
getSessionManagementConfig,
|
|
595
634
|
login: signIn,
|
|
596
635
|
logout: signOut,
|
package/dist/server/types.d.ts
CHANGED
|
@@ -82,6 +82,8 @@ export type OIDCPublicSession<TClaims extends OIDCUserClaims = OIDCUserClaims> =
|
|
|
82
82
|
sessionState?: string;
|
|
83
83
|
sid?: string;
|
|
84
84
|
sub?: string;
|
|
85
|
+
/** SvelteKit dependency registered by getPublicSession for targeted client revalidation. */
|
|
86
|
+
revalidationDependency?: string;
|
|
85
87
|
};
|
|
86
88
|
export type OIDCBackChannelLogoutClaims = Record<string, unknown> & {
|
|
87
89
|
iss: string;
|
|
@@ -126,7 +128,9 @@ export type OIDCSessionStore<TClaims extends OIDCUserClaims = OIDCUserClaims, TS
|
|
|
126
128
|
};
|
|
127
129
|
export type OIDCSessionManagementConfig = {
|
|
128
130
|
clientId: string;
|
|
131
|
+
issuer: string;
|
|
129
132
|
loginPath: string;
|
|
133
|
+
logoutPath: string;
|
|
130
134
|
redirectPath: string;
|
|
131
135
|
metadata: Pick<OIDCDiscoveryDocument, 'issuer' | 'check_session_iframe' | 'end_session_endpoint' | 'backchannel_logout_supported' | 'backchannel_logout_session_supported'>;
|
|
132
136
|
checkSessionIframe?: string;
|
|
@@ -149,6 +153,7 @@ export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessio
|
|
|
149
153
|
clientSecretJwt?: OIDCClientSecretJwtOptions;
|
|
150
154
|
privateKeyJwt?: OIDCPrivateKeyJwtOptions;
|
|
151
155
|
loginPath?: string;
|
|
156
|
+
logoutPath?: string;
|
|
152
157
|
redirectPath?: string;
|
|
153
158
|
postLogoutRedirectUri?: string;
|
|
154
159
|
scope?: string | string[];
|
|
@@ -177,6 +182,18 @@ export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessio
|
|
|
177
182
|
user?: TClaims;
|
|
178
183
|
isRefresh: boolean;
|
|
179
184
|
}) => MaybePromise<TSession>;
|
|
185
|
+
/**
|
|
186
|
+
* Runs on every `getSession` read (and therefore every `getPublicSession`,
|
|
187
|
+
* `hook()`-provided `requireAuth`, and the instance-level `requireAuth`) —
|
|
188
|
+
* unlike `transformSession`, which only fires on session creation and token
|
|
189
|
+
* refresh. Use this to keep data your app owns outside the token (e.g. roles
|
|
190
|
+
* or memberships stored in your own database) fresh without waiting for a
|
|
191
|
+
* refresh. Only invoked when a session is present; the result is not persisted
|
|
192
|
+
* back to the session store.
|
|
193
|
+
*/
|
|
194
|
+
enrichSession?: (session: TSession, context: {
|
|
195
|
+
event?: MinimalRequestEvent;
|
|
196
|
+
}) => MaybePromise<TSession>;
|
|
180
197
|
endpoints?: Partial<OIDCDiscoveryDocument>;
|
|
181
198
|
logger?: OIDCLogger | false;
|
|
182
199
|
/**
|
|
@@ -271,6 +288,7 @@ export type OIDCInstance<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessi
|
|
|
271
288
|
}) => Promise<TSession | null>;
|
|
272
289
|
getPublicSession: (event: {
|
|
273
290
|
cookies: Cookies;
|
|
291
|
+
depends?: (dependency: string) => void;
|
|
274
292
|
}) => Promise<OIDCPublicSession<TClaims> | null>;
|
|
275
293
|
getSessionManagementConfig: () => Promise<OIDCSessionManagementConfig>;
|
|
276
294
|
login: (event: MinimalRequestEvent, loginOptions?: OIDCLoginOptions) => Promise<never>;
|