@sourceregistry/sveltekit-oidc 1.0.3 → 1.1.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/dist/server/cookies.js +9 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +57 -15
- package/dist/server/store.d.ts +2 -1
- package/dist/server/store.js +14 -0
- package/dist/server/types.d.ts +21 -4
- package/package.json +1 -1
package/dist/server/cookies.js
CHANGED
|
@@ -10,6 +10,15 @@ export function createOIDCCookieStore(cookieSecret, sessionCookieName, stateCook
|
|
|
10
10
|
clearSession(cookies) {
|
|
11
11
|
cookies.delete(sessionCookieName, cookieOptions);
|
|
12
12
|
},
|
|
13
|
+
readSessionReference(cookies) {
|
|
14
|
+
return parseSignedCookie(cookies.get(sessionCookieName), cookieSecret);
|
|
15
|
+
},
|
|
16
|
+
writeSessionReference(cookies, reference) {
|
|
17
|
+
cookies.set(sessionCookieName, serializeSignedCookie(reference, cookieSecret), cookieOptions);
|
|
18
|
+
},
|
|
19
|
+
clearSessionReference(cookies) {
|
|
20
|
+
cookies.delete(sessionCookieName, cookieOptions);
|
|
21
|
+
},
|
|
13
22
|
readState(cookies) {
|
|
14
23
|
return parseSignedCookie(cookies.get(stateCookieName), cookieSecret);
|
|
15
24
|
},
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OIDCOptions, OIDCInstance } from './types.js';
|
|
2
2
|
export type * from './types.js';
|
|
3
|
-
export { createInMemoryBackChannelLogoutStore } from './store.js';
|
|
3
|
+
export { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
4
4
|
export declare function createOIDC(options: OIDCOptions): OIDCInstance;
|
|
5
5
|
export declare const OpenIDConnect: typeof createOIDC;
|
package/dist/server/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { createOIDCCookieStore } from './cookies.js';
|
|
|
5
5
|
import { asAuthorizationHeader, createClientSecretJwtAssertion, createPrivateKeyJwtAssertion, fetchJson } from './jwt.js';
|
|
6
6
|
import { normalizeTokens, shouldRefresh } from './session.js';
|
|
7
7
|
import { absoluteUrl, base64UrlEncode, buildCookieOptions, collectGroups, createPKCEPair, normalizeIssuer, normalizeScope, parseProviderError, toPublicSession } from './utils.js';
|
|
8
|
-
export { createInMemoryBackChannelLogoutStore } from './store.js';
|
|
8
|
+
export { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
9
9
|
export function createOIDC(options) {
|
|
10
10
|
const cookieOptions = buildCookieOptions(options.cookieOptions);
|
|
11
11
|
const refreshToleranceSeconds = options.refreshToleranceSeconds ?? 30;
|
|
@@ -18,6 +18,45 @@ export function createOIDC(options) {
|
|
|
18
18
|
const cookieStore = createOIDCCookieStore(options.cookieSecret, sessionCookieName, stateCookieName, cookieOptions);
|
|
19
19
|
let metadataPromise;
|
|
20
20
|
let jwksPromise;
|
|
21
|
+
async function readPersistedSession(cookies) {
|
|
22
|
+
if (!options.sessionStore) {
|
|
23
|
+
const session = cookieStore.readSession(cookies);
|
|
24
|
+
return session ? { session } : null;
|
|
25
|
+
}
|
|
26
|
+
const reference = cookieStore.readSessionReference(cookies);
|
|
27
|
+
if (!reference?.id) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const session = await options.sessionStore.get(reference.id);
|
|
31
|
+
if (!session) {
|
|
32
|
+
cookieStore.clearSessionReference(cookies);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
id: reference.id,
|
|
37
|
+
session
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function writePersistedSession(cookies, session, sessionId) {
|
|
41
|
+
if (!options.sessionStore) {
|
|
42
|
+
cookieStore.writeSession(cookies, session);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const id = sessionId ?? base64UrlEncode(randomBytes(24));
|
|
46
|
+
await options.sessionStore.set(id, session);
|
|
47
|
+
cookieStore.writeSessionReference(cookies, { id });
|
|
48
|
+
}
|
|
49
|
+
async function clearPersistedSession(cookies, sessionId) {
|
|
50
|
+
if (!options.sessionStore) {
|
|
51
|
+
cookieStore.clearSession(cookies);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const id = sessionId ?? cookieStore.readSessionReference(cookies)?.id;
|
|
55
|
+
if (id) {
|
|
56
|
+
await options.sessionStore.delete(id);
|
|
57
|
+
}
|
|
58
|
+
cookieStore.clearSessionReference(cookies);
|
|
59
|
+
}
|
|
21
60
|
async function getMetadata() {
|
|
22
61
|
if (!metadataPromise) {
|
|
23
62
|
metadataPromise = (async () => {
|
|
@@ -49,7 +88,7 @@ export function createOIDC(options) {
|
|
|
49
88
|
if (!metadata.jwks_uri) {
|
|
50
89
|
throw error(500, { message: 'OIDC jwks_uri is required to validate id_token values' });
|
|
51
90
|
}
|
|
52
|
-
return fromWeb(metadata.jwks_uri);
|
|
91
|
+
return fromWeb(metadata.jwks_uri, { overrideEndpointCheck: true });
|
|
53
92
|
});
|
|
54
93
|
}
|
|
55
94
|
return jwksPromise;
|
|
@@ -198,12 +237,13 @@ export function createOIDC(options) {
|
|
|
198
237
|
}
|
|
199
238
|
return options.backChannelLogoutStore.isRevoked(session);
|
|
200
239
|
}
|
|
201
|
-
async function maybeRefreshSession(event,
|
|
240
|
+
async function maybeRefreshSession(event, persisted) {
|
|
241
|
+
const session = persisted?.session ?? null;
|
|
202
242
|
if (!session) {
|
|
203
243
|
return null;
|
|
204
244
|
}
|
|
205
245
|
if (await isRevoked(session)) {
|
|
206
|
-
|
|
246
|
+
await clearPersistedSession(event.cookies, persisted?.id);
|
|
207
247
|
return null;
|
|
208
248
|
}
|
|
209
249
|
if (!shouldRefresh(session, refreshToleranceSeconds)) {
|
|
@@ -235,16 +275,16 @@ export function createOIDC(options) {
|
|
|
235
275
|
isRefresh: true
|
|
236
276
|
})
|
|
237
277
|
: nextSession;
|
|
238
|
-
|
|
278
|
+
await writePersistedSession(event.cookies, finalSession, persisted?.id);
|
|
239
279
|
return finalSession;
|
|
240
280
|
}
|
|
241
281
|
catch {
|
|
242
|
-
|
|
282
|
+
await clearPersistedSession(event.cookies, persisted?.id);
|
|
243
283
|
return null;
|
|
244
284
|
}
|
|
245
285
|
}
|
|
246
286
|
async function getSession(event) {
|
|
247
|
-
return maybeRefreshSession(event,
|
|
287
|
+
return maybeRefreshSession(event, await readPersistedSession(event.cookies));
|
|
248
288
|
}
|
|
249
289
|
async function signIn(event, loginOptions = {}) {
|
|
250
290
|
const metadata = await getMetadata();
|
|
@@ -330,7 +370,7 @@ export function createOIDC(options) {
|
|
|
330
370
|
isRefresh: false
|
|
331
371
|
})
|
|
332
372
|
: session;
|
|
333
|
-
|
|
373
|
+
await writePersistedSession(event.cookies, finalSession);
|
|
334
374
|
return {
|
|
335
375
|
session: finalSession,
|
|
336
376
|
returnTo: stateCookie.returnTo
|
|
@@ -338,9 +378,10 @@ export function createOIDC(options) {
|
|
|
338
378
|
}
|
|
339
379
|
async function signOut(event, logoutOptions = {}) {
|
|
340
380
|
const metadata = await getMetadata();
|
|
341
|
-
const
|
|
381
|
+
const persisted = await readPersistedSession(event.cookies);
|
|
382
|
+
const session = persisted?.session ?? null;
|
|
342
383
|
cookieStore.clearState(event.cookies);
|
|
343
|
-
|
|
384
|
+
await clearPersistedSession(event.cookies, persisted?.id);
|
|
344
385
|
if (logoutOptions.clearSessionOnly || !metadata.end_session_endpoint) {
|
|
345
386
|
throw redirect(302, logoutOptions.postLogoutRedirectUri ??
|
|
346
387
|
options.defaultLogoutRedirect ??
|
|
@@ -386,8 +427,8 @@ export function createOIDC(options) {
|
|
|
386
427
|
});
|
|
387
428
|
return new Response(null, { status: 200 });
|
|
388
429
|
}
|
|
389
|
-
function requireAuth(event, returnTo) {
|
|
390
|
-
const session =
|
|
430
|
+
async function requireAuth(event, returnTo) {
|
|
431
|
+
const session = await getSession(event);
|
|
391
432
|
if (session) {
|
|
392
433
|
return session;
|
|
393
434
|
}
|
|
@@ -400,12 +441,13 @@ export function createOIDC(options) {
|
|
|
400
441
|
session,
|
|
401
442
|
user: session?.user,
|
|
402
443
|
claims: session?.claims,
|
|
403
|
-
requireAuth: () => {
|
|
444
|
+
requireAuth: async () => {
|
|
404
445
|
if (!session) {
|
|
405
446
|
throw error(401, { message: 'Authentication required' });
|
|
406
447
|
}
|
|
448
|
+
return session;
|
|
407
449
|
},
|
|
408
|
-
clearSession: () =>
|
|
450
|
+
clearSession: async () => clearPersistedSession(event.cookies)
|
|
409
451
|
};
|
|
410
452
|
return resolve(event);
|
|
411
453
|
};
|
|
@@ -499,7 +541,7 @@ export function createOIDC(options) {
|
|
|
499
541
|
backChannelLogoutHandler,
|
|
500
542
|
createActions,
|
|
501
543
|
requireAuth,
|
|
502
|
-
clearSession:
|
|
544
|
+
clearSession: async (cookies) => clearPersistedSession(cookies)
|
|
503
545
|
};
|
|
504
546
|
}
|
|
505
547
|
export const OpenIDConnect = createOIDC;
|
package/dist/server/store.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type { OIDCBackChannelLogoutStore } from './types.js';
|
|
1
|
+
import type { OIDCBackChannelLogoutStore, OIDCSessionStore } from './types.js';
|
|
2
2
|
export declare function createInMemoryBackChannelLogoutStore(): OIDCBackChannelLogoutStore;
|
|
3
|
+
export declare function createInMemorySessionStore(): OIDCSessionStore;
|
package/dist/server/store.js
CHANGED
|
@@ -16,3 +16,17 @@ export function createInMemoryBackChannelLogoutStore() {
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
+
export function createInMemorySessionStore() {
|
|
20
|
+
const sessions = new Map();
|
|
21
|
+
return {
|
|
22
|
+
async get(sessionId) {
|
|
23
|
+
return sessions.get(sessionId) ?? null;
|
|
24
|
+
},
|
|
25
|
+
async set(sessionId, session) {
|
|
26
|
+
sessions.set(sessionId, session);
|
|
27
|
+
},
|
|
28
|
+
async delete(sessionId) {
|
|
29
|
+
sessions.delete(sessionId);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
package/dist/server/types.d.ts
CHANGED
|
@@ -118,6 +118,11 @@ export type OIDCBackChannelLogoutStore = {
|
|
|
118
118
|
revoke(record: OIDCBackChannelLogoutRecord): MaybePromise<void>;
|
|
119
119
|
isRevoked(session: OIDCSession): MaybePromise<boolean>;
|
|
120
120
|
};
|
|
121
|
+
export type OIDCSessionStore = {
|
|
122
|
+
get(sessionId: string): MaybePromise<OIDCSession | null>;
|
|
123
|
+
set(sessionId: string, session: OIDCSession): MaybePromise<void>;
|
|
124
|
+
delete(sessionId: string): MaybePromise<void>;
|
|
125
|
+
};
|
|
121
126
|
export type OIDCSessionManagementConfig = {
|
|
122
127
|
clientId: string;
|
|
123
128
|
loginPath: string;
|
|
@@ -149,6 +154,7 @@ export type OIDCOptions = {
|
|
|
149
154
|
refreshToleranceSeconds?: number;
|
|
150
155
|
defaultLoginRedirect?: string;
|
|
151
156
|
defaultLogoutRedirect?: string;
|
|
157
|
+
sessionStore?: OIDCSessionStore;
|
|
152
158
|
backChannelLogoutStore?: OIDCBackChannelLogoutStore;
|
|
153
159
|
transformClaims?: (claims: OIDCUserClaims) => MaybePromise<OIDCUserClaims>;
|
|
154
160
|
transformUser?: (user: OIDCUserClaims | undefined, context: {
|
|
@@ -183,8 +189,8 @@ export type OIDCHandleLocals = {
|
|
|
183
189
|
session: OIDCSession | null;
|
|
184
190
|
user?: OIDCUserClaims;
|
|
185
191
|
claims?: OIDCUserClaims;
|
|
186
|
-
requireAuth: () =>
|
|
187
|
-
clearSession: () => void
|
|
192
|
+
requireAuth: () => Promise<OIDCSession>;
|
|
193
|
+
clearSession: () => Promise<void>;
|
|
188
194
|
};
|
|
189
195
|
export type OIDCStateCookie = {
|
|
190
196
|
state: string;
|
|
@@ -211,10 +217,21 @@ export type OIDCCookies = {
|
|
|
211
217
|
readSession(cookies: Cookies): OIDCSession | null;
|
|
212
218
|
writeSession(cookies: Cookies, session: OIDCSession): void;
|
|
213
219
|
clearSession(cookies: Cookies): void;
|
|
220
|
+
readSessionReference(cookies: Cookies): {
|
|
221
|
+
id: string;
|
|
222
|
+
} | null;
|
|
223
|
+
writeSessionReference(cookies: Cookies, reference: {
|
|
224
|
+
id: string;
|
|
225
|
+
}): void;
|
|
226
|
+
clearSessionReference(cookies: Cookies): void;
|
|
214
227
|
readState(cookies: Cookies): OIDCStateCookie | null;
|
|
215
228
|
writeState(cookies: Cookies, state: OIDCStateCookie): void;
|
|
216
229
|
clearState(cookies: Cookies): void;
|
|
217
230
|
};
|
|
231
|
+
export type OIDCPersistedSession = {
|
|
232
|
+
id?: string;
|
|
233
|
+
session: OIDCSession;
|
|
234
|
+
};
|
|
218
235
|
export type OIDCInstance = {
|
|
219
236
|
handle: Handle;
|
|
220
237
|
getMetadata: () => Promise<OIDCDiscoveryDocument>;
|
|
@@ -233,6 +250,6 @@ export type OIDCInstance = {
|
|
|
233
250
|
login: Action;
|
|
234
251
|
logout: Action;
|
|
235
252
|
}>;
|
|
236
|
-
requireAuth: (event: RequestEvent, returnTo?: string) => OIDCSession
|
|
237
|
-
clearSession: (cookies: Cookies) => void
|
|
253
|
+
requireAuth: (event: RequestEvent, returnTo?: string) => Promise<OIDCSession>;
|
|
254
|
+
clearSession: (cookies: Cookies) => Promise<void>;
|
|
238
255
|
};
|