@sourceregistry/sveltekit-oidc 1.7.0 → 2.0.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 +155 -226
- package/dist/client/OIDCContext.svelte +5 -8
- package/dist/client/OIDCContext.svelte.d.ts +13 -13
- package/dist/client/context.d.ts +10 -11
- package/dist/client/index.d.ts +1 -1
- package/dist/server/cookies.d.ts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +154 -108
- package/dist/server/store.d.ts +3 -3
- package/dist/server/types.d.ts +75 -66
- package/dist/server/utils.d.ts +1 -1
- package/dist/server/utils.js +6 -11
- package/package.json +1 -1
package/dist/server/types.d.ts
CHANGED
|
@@ -57,7 +57,8 @@ export type OIDCUserClaims = Record<string, unknown> & {
|
|
|
57
57
|
nbf?: number;
|
|
58
58
|
nonce?: string;
|
|
59
59
|
};
|
|
60
|
-
export type
|
|
60
|
+
export type OIDCSessionReason = 'login' | 'refresh';
|
|
61
|
+
export type OIDCSession<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
61
62
|
issuer: string;
|
|
62
63
|
clientId: string;
|
|
63
64
|
nonce?: string;
|
|
@@ -65,16 +66,19 @@ export type OIDCSession<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
|
65
66
|
sid?: string;
|
|
66
67
|
sessionState?: string;
|
|
67
68
|
groups: string[];
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
/** Validated claims from the ID token. */
|
|
70
|
+
idTokenClaims: OIDCUserClaims;
|
|
71
|
+
/** Raw response from the UserInfo endpoint, when requested. */
|
|
72
|
+
userInfo?: OIDCUserClaims;
|
|
73
|
+
/** Application-facing identity resolved from the validated provider data. */
|
|
74
|
+
identity: TIdentity;
|
|
70
75
|
tokens: OIDCSessionTokens;
|
|
71
76
|
createdAt: number;
|
|
72
77
|
refreshedAt: number;
|
|
73
78
|
};
|
|
74
|
-
export type OIDCPublicSession<
|
|
79
|
+
export type OIDCPublicSession<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
75
80
|
isAuthenticated: boolean;
|
|
76
|
-
|
|
77
|
-
claims?: TClaims;
|
|
81
|
+
identity: TIdentity;
|
|
78
82
|
groups: string[];
|
|
79
83
|
scope: string[];
|
|
80
84
|
expiresAt?: number;
|
|
@@ -82,7 +86,7 @@ export type OIDCPublicSession<TClaims extends OIDCUserClaims = OIDCUserClaims> =
|
|
|
82
86
|
sessionState?: string;
|
|
83
87
|
sid?: string;
|
|
84
88
|
sub?: string;
|
|
85
|
-
/** SvelteKit dependency registered
|
|
89
|
+
/** SvelteKit dependency registered during public projection for targeted client revalidation. */
|
|
86
90
|
revalidationDependency?: string;
|
|
87
91
|
};
|
|
88
92
|
export type OIDCBackChannelLogoutClaims = Record<string, unknown> & {
|
|
@@ -117,13 +121,13 @@ export type OIDCBackChannelLogoutRecord = {
|
|
|
117
121
|
jti: string;
|
|
118
122
|
iat: number;
|
|
119
123
|
};
|
|
120
|
-
export type OIDCBackChannelLogoutStore<
|
|
124
|
+
export type OIDCBackChannelLogoutStore<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
121
125
|
revoke(record: OIDCBackChannelLogoutRecord): MaybePromise<void>;
|
|
122
|
-
isRevoked(session:
|
|
126
|
+
isRevoked(session: OIDCSession<TIdentity>): MaybePromise<boolean>;
|
|
123
127
|
};
|
|
124
|
-
export type OIDCSessionStore<
|
|
125
|
-
get(sessionId: string): MaybePromise<
|
|
126
|
-
set(sessionId: string, session:
|
|
128
|
+
export type OIDCSessionStore<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
129
|
+
get(sessionId: string): MaybePromise<OIDCSession<TIdentity> | null>;
|
|
130
|
+
set(sessionId: string, session: OIDCSession<TIdentity>): MaybePromise<void>;
|
|
127
131
|
delete(sessionId: string): MaybePromise<void>;
|
|
128
132
|
};
|
|
129
133
|
export type OIDCSessionManagementConfig = {
|
|
@@ -144,7 +148,7 @@ export type OIDCLogger = {
|
|
|
144
148
|
warn?: (...args: unknown[]) => void;
|
|
145
149
|
error?: (...args: unknown[]) => void;
|
|
146
150
|
};
|
|
147
|
-
export type OIDCOptions<
|
|
151
|
+
export type OIDCOptions<TIdentity extends OIDCUserClaims = OIDCUserClaims, TRequestData = undefined> = {
|
|
148
152
|
issuer?: string;
|
|
149
153
|
discoveryUrl?: string;
|
|
150
154
|
clientId: string;
|
|
@@ -169,31 +173,39 @@ export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessio
|
|
|
169
173
|
sessionMaxAgeSeconds?: number;
|
|
170
174
|
defaultLoginRedirect?: string;
|
|
171
175
|
defaultLogoutRedirect?: string;
|
|
172
|
-
sessionStore?: OIDCSessionStore<
|
|
173
|
-
backChannelLogoutStore?: OIDCBackChannelLogoutStore<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
sessionStore?: OIDCSessionStore<TIdentity> | 'memory';
|
|
177
|
+
backChannelLogoutStore?: OIDCBackChannelLogoutStore<TIdentity> | 'memory';
|
|
178
|
+
/** Resolves application identity after provider data validation on login and refresh. */
|
|
179
|
+
resolveIdentity?: (context: {
|
|
180
|
+
idTokenClaims: OIDCUserClaims;
|
|
181
|
+
userInfo?: OIDCUserClaims;
|
|
182
|
+
reason: OIDCSessionReason;
|
|
183
|
+
}) => MaybePromise<TIdentity>;
|
|
184
|
+
/** Runs immediately before a login or refreshed session is persisted. */
|
|
185
|
+
beforeSessionPersist?: (context: {
|
|
186
|
+
session: OIDCSession<TIdentity>;
|
|
187
|
+
reason: OIDCSessionReason;
|
|
179
188
|
event?: MinimalRequestEvent;
|
|
180
|
-
tokenResponse
|
|
181
|
-
|
|
182
|
-
user?: TClaims;
|
|
183
|
-
isRefresh: boolean;
|
|
184
|
-
}) => MaybePromise<TSession>;
|
|
189
|
+
tokenResponse: OIDCTokenResponse;
|
|
190
|
+
}) => MaybePromise<void>;
|
|
185
191
|
/**
|
|
186
|
-
*
|
|
187
|
-
* `
|
|
188
|
-
*
|
|
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.
|
|
192
|
+
* Loads application-owned data once for each authenticated request handled by
|
|
193
|
+
* `handle`. The result is exposed as `event.locals.oidc.data` and is never
|
|
194
|
+
* persisted in the OIDC session.
|
|
193
195
|
*/
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
196
|
+
loadRequestData?: (context: {
|
|
197
|
+
session: OIDCSession<TIdentity>;
|
|
198
|
+
event: MinimalRequestEvent;
|
|
199
|
+
}) => MaybePromise<TRequestData>;
|
|
200
|
+
/**
|
|
201
|
+
* Creates the browser-safe session from persisted authentication and
|
|
202
|
+
* request-only application data. Runs only when a public session is requested.
|
|
203
|
+
*/
|
|
204
|
+
createPublicSession?: (context: {
|
|
205
|
+
session: OIDCSession<TIdentity>;
|
|
206
|
+
data: TRequestData | null;
|
|
207
|
+
base: OIDCPublicSession<TIdentity>;
|
|
208
|
+
}) => OIDCPublicSession<TIdentity>;
|
|
197
209
|
endpoints?: Partial<OIDCDiscoveryDocument>;
|
|
198
210
|
logger?: OIDCLogger | false;
|
|
199
211
|
/**
|
|
@@ -215,16 +227,16 @@ export type OIDCLogoutOptions = {
|
|
|
215
227
|
state?: string;
|
|
216
228
|
clearSessionOnly?: boolean;
|
|
217
229
|
};
|
|
218
|
-
export type OIDCCallbackResult<
|
|
219
|
-
session:
|
|
230
|
+
export type OIDCCallbackResult<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
231
|
+
session: OIDCSession<TIdentity>;
|
|
220
232
|
returnTo: string;
|
|
221
233
|
};
|
|
222
|
-
export type OIDCHandleLocals<
|
|
234
|
+
export type OIDCHandleLocals<TIdentity extends OIDCUserClaims = OIDCUserClaims, TRequestData = undefined> = {
|
|
223
235
|
isAuthenticated: boolean;
|
|
224
|
-
session:
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
requireAuth: () => Promise<
|
|
236
|
+
session: OIDCSession<TIdentity> | null;
|
|
237
|
+
identity?: TIdentity;
|
|
238
|
+
data: TRequestData | null;
|
|
239
|
+
requireAuth: () => Promise<OIDCSession<TIdentity>>;
|
|
228
240
|
clearSession: () => Promise<void>;
|
|
229
241
|
};
|
|
230
242
|
export type OIDCStateCookie = {
|
|
@@ -241,8 +253,8 @@ export type MinimalRequestEvent = {
|
|
|
241
253
|
locals: App.Locals;
|
|
242
254
|
};
|
|
243
255
|
export type MinimalRequestHandler<T extends MinimalRequestEvent> = (event: T) => MaybePromise<Response>;
|
|
244
|
-
export type OIDCCallbackHandlerOptions<
|
|
245
|
-
onsuccess?: <T extends MinimalRequestEvent = RequestEvent>(event: T, result: OIDCCallbackResult<
|
|
256
|
+
export type OIDCCallbackHandlerOptions<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
257
|
+
onsuccess?: <T extends MinimalRequestEvent = RequestEvent>(event: T, result: OIDCCallbackResult<TIdentity>) => MaybePromise<Response | void>;
|
|
246
258
|
onfailure?: <T extends MinimalRequestEvent = RequestEvent>(event: T, err: unknown) => MaybePromise<Response | void>;
|
|
247
259
|
redirectTo?: string;
|
|
248
260
|
};
|
|
@@ -255,9 +267,9 @@ export type OIDCClientAssertionOptions = {
|
|
|
255
267
|
clientId: string;
|
|
256
268
|
clientSecret?: string;
|
|
257
269
|
};
|
|
258
|
-
export type OIDCCookies<
|
|
259
|
-
readSession(cookies: Cookies):
|
|
260
|
-
writeSession(cookies: Cookies, session:
|
|
270
|
+
export type OIDCCookies<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
271
|
+
readSession(cookies: Cookies): OIDCSession<TIdentity> | null;
|
|
272
|
+
writeSession(cookies: Cookies, session: OIDCSession<TIdentity>): void;
|
|
261
273
|
clearSession(cookies: Cookies): void;
|
|
262
274
|
readSessionReference(cookies: Cookies): {
|
|
263
275
|
id: string;
|
|
@@ -270,33 +282,29 @@ export type OIDCCookies<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessio
|
|
|
270
282
|
writeState(cookies: Cookies, state: OIDCStateCookie): void;
|
|
271
283
|
clearState(cookies: Cookies): void;
|
|
272
284
|
};
|
|
273
|
-
export type OIDCPersistedSession<
|
|
285
|
+
export type OIDCPersistedSession<TIdentity extends OIDCUserClaims = OIDCUserClaims> = {
|
|
274
286
|
id?: string;
|
|
275
|
-
session:
|
|
287
|
+
session: OIDCSession<TIdentity>;
|
|
276
288
|
};
|
|
277
|
-
export type OIDCInstance<
|
|
289
|
+
export type OIDCInstance<TIdentity extends OIDCUserClaims = OIDCUserClaims, TRequestData = undefined> = {
|
|
278
290
|
handle: Handle;
|
|
279
|
-
|
|
280
|
-
cookies: Cookies;
|
|
281
|
-
locals: App.Locals;
|
|
282
|
-
}) => Promise<{
|
|
283
|
-
oidc: OIDCHandleLocals<TClaims, TSession>;
|
|
284
|
-
}>;
|
|
291
|
+
createRequestContext: (event: MinimalRequestEvent) => Promise<OIDCHandleLocals<TIdentity, TRequestData>>;
|
|
285
292
|
getMetadata: () => Promise<OIDCDiscoveryDocument>;
|
|
286
293
|
getSession: (event: {
|
|
287
294
|
cookies: Cookies;
|
|
288
|
-
}) => Promise<
|
|
289
|
-
getPublicSession: (event: {
|
|
290
|
-
cookies: Cookies;
|
|
295
|
+
}) => Promise<OIDCSession<TIdentity> | null>;
|
|
296
|
+
getPublicSession: (event: MinimalRequestEvent & {
|
|
291
297
|
depends?: (dependency: string) => void;
|
|
292
|
-
}) => Promise<OIDCPublicSession<
|
|
298
|
+
}) => Promise<OIDCPublicSession<TIdentity> | null>;
|
|
299
|
+
/** Projects an already-loaded request context without repeating any server work. */
|
|
300
|
+
toPublicSession: (context: OIDCHandleLocals<TIdentity, TRequestData> | null | undefined, depends?: (dependency: string) => void) => OIDCPublicSession<TIdentity> | null;
|
|
293
301
|
getSessionManagementConfig: () => Promise<OIDCSessionManagementConfig>;
|
|
294
302
|
login: (event: MinimalRequestEvent, loginOptions?: OIDCLoginOptions) => Promise<never>;
|
|
295
303
|
logout: (event: MinimalRequestEvent, logoutOptions?: OIDCLogoutOptions) => Promise<never>;
|
|
296
|
-
handleCallback: (event: MinimalRequestEvent) => Promise<OIDCCallbackResult<
|
|
304
|
+
handleCallback: (event: MinimalRequestEvent) => Promise<OIDCCallbackResult<TIdentity>>;
|
|
297
305
|
handleBackChannelLogout: (event: MinimalRequestEvent) => Promise<Response>;
|
|
298
306
|
loginHandler: <T extends MinimalRequestEvent = RequestEvent>(defaults?: OIDCLoginOptions) => MinimalRequestHandler<T>;
|
|
299
|
-
callbackHandler: <T extends MinimalRequestEvent = RequestEvent>(handlerOptions?: OIDCCallbackHandlerOptions<
|
|
307
|
+
callbackHandler: <T extends MinimalRequestEvent = RequestEvent>(handlerOptions?: OIDCCallbackHandlerOptions<TIdentity>) => MinimalRequestHandler<T>;
|
|
300
308
|
logoutHandler: <T extends MinimalRequestEvent = RequestEvent>(defaults?: OIDCLogoutOptions) => MinimalRequestHandler<T>;
|
|
301
309
|
backChannelLogoutHandler: <T extends MinimalRequestEvent = RequestEvent>() => MinimalRequestHandler<T>;
|
|
302
310
|
createActions: (actionOptions?: OIDCActionOptions) => Readonly<{
|
|
@@ -306,9 +314,10 @@ export type OIDCInstance<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessi
|
|
|
306
314
|
requireAuth: (event: {
|
|
307
315
|
cookies: Cookies;
|
|
308
316
|
url: URL;
|
|
309
|
-
}, returnTo?: string) => Promise<
|
|
317
|
+
}, returnTo?: string) => Promise<OIDCSession<TIdentity>>;
|
|
310
318
|
clearSession: (cookies: Cookies) => Promise<void>;
|
|
311
319
|
};
|
|
312
|
-
export type
|
|
313
|
-
export type
|
|
314
|
-
export type
|
|
320
|
+
export type OIDCInferIdentity<T> = T extends OIDCInstance<infer TIdentity, any> ? TIdentity : OIDCUserClaims;
|
|
321
|
+
export type OIDCInferRequestData<T> = T extends OIDCInstance<any, infer TRequestData> ? TRequestData : undefined;
|
|
322
|
+
export type OIDCInferSession<T> = OIDCSession<OIDCInferIdentity<T>>;
|
|
323
|
+
export type OIDCLocals<T extends OIDCInstance<any, any>> = OIDCHandleLocals<OIDCInferIdentity<T>, OIDCInferRequestData<T>>;
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -24,4 +24,4 @@ export declare function internalRedirectPath(event: {
|
|
|
24
24
|
}, pathOrUrl: string | undefined, fallback?: string): string;
|
|
25
25
|
export declare function validateIdTokenClaims(claims: OIDCUserClaims, nonce: string): void;
|
|
26
26
|
export declare function validateUserInfoSubject(claims: OIDCUserClaims, user: OIDCUserClaims | undefined): void;
|
|
27
|
-
export declare function toPublicSession<
|
|
27
|
+
export declare function toPublicSession<TIdentity extends OIDCUserClaims = OIDCUserClaims>(session: OIDCSession<TIdentity> | null): OIDCPublicSession<TIdentity> | null;
|
package/dist/server/utils.js
CHANGED
|
@@ -57,10 +57,7 @@ function cookieEncryptionKey(secret) {
|
|
|
57
57
|
export function serializeSignedCookie(payload, secret) {
|
|
58
58
|
const iv = randomBytes(12);
|
|
59
59
|
const cipher = createCipheriv('aes-256-gcm', cookieEncryptionKey(secret), iv);
|
|
60
|
-
const ciphertext = Buffer.concat([
|
|
61
|
-
cipher.update(JSON.stringify(payload), 'utf8'),
|
|
62
|
-
cipher.final()
|
|
63
|
-
]);
|
|
60
|
+
const ciphertext = Buffer.concat([cipher.update(JSON.stringify(payload), 'utf8'), cipher.final()]);
|
|
64
61
|
const tag = cipher.getAuthTag();
|
|
65
62
|
return `v2.${iv.toString('base64url')}.${tag.toString('base64url')}.${ciphertext.toString('base64url')}`;
|
|
66
63
|
}
|
|
@@ -74,10 +71,7 @@ export function parseSignedCookie(value, secret) {
|
|
|
74
71
|
const [, iv, tag, ciphertext] = parts;
|
|
75
72
|
const decipher = createDecipheriv('aes-256-gcm', cookieEncryptionKey(secret), Buffer.from(iv, 'base64url'));
|
|
76
73
|
decipher.setAuthTag(Buffer.from(tag, 'base64url'));
|
|
77
|
-
const plaintext = Buffer.concat([
|
|
78
|
-
decipher.update(Buffer.from(ciphertext, 'base64url')),
|
|
79
|
-
decipher.final()
|
|
80
|
-
]);
|
|
74
|
+
const plaintext = Buffer.concat([decipher.update(Buffer.from(ciphertext, 'base64url')), decipher.final()]);
|
|
81
75
|
return JSON.parse(plaintext.toString('utf8'));
|
|
82
76
|
}
|
|
83
77
|
catch {
|
|
@@ -135,7 +129,9 @@ export function validateIdTokenClaims(claims, nonce) {
|
|
|
135
129
|
}
|
|
136
130
|
export function validateUserInfoSubject(claims, user) {
|
|
137
131
|
if (user && user.sub !== claims.sub) {
|
|
138
|
-
throw error(401, {
|
|
132
|
+
throw error(401, {
|
|
133
|
+
message: 'UserInfo subject does not match id_token subject'
|
|
134
|
+
});
|
|
139
135
|
}
|
|
140
136
|
}
|
|
141
137
|
export function toPublicSession(session) {
|
|
@@ -143,8 +139,7 @@ export function toPublicSession(session) {
|
|
|
143
139
|
return null;
|
|
144
140
|
return {
|
|
145
141
|
isAuthenticated: true,
|
|
146
|
-
|
|
147
|
-
claims: session.claims,
|
|
142
|
+
identity: session.identity,
|
|
148
143
|
groups: session.groups,
|
|
149
144
|
scope: session.tokens.scope,
|
|
150
145
|
expiresAt: session.tokens.expiresAt,
|