@sourceregistry/sveltekit-oidc 1.3.1 → 1.5.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 +32 -44
- package/dist/client/context.d.ts +7 -3
- package/dist/client/index.d.ts +1 -1
- package/dist/server/index.js +41 -12
- package/dist/server/types.d.ts +12 -4
- package/dist/server/utils.d.ts +1 -1
- package/dist/server/utils.js +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,17 +12,14 @@ OIDC authentication helpers for SvelteKit with:
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
14
14
|
```sh
|
|
15
|
-
npm install sveltekit-oidc
|
|
15
|
+
npm install @sourceregistry/sveltekit-oidc
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Server Setup
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
21
|
// src/lib/server/auth.ts
|
|
22
|
-
import {
|
|
23
|
-
createInMemoryBackChannelLogoutStore,
|
|
24
|
-
createOIDC
|
|
25
|
-
} from 'sveltekit-oidc/server';
|
|
22
|
+
import { createOIDC } from '@sourceregistry/sveltekit-oidc/server';
|
|
26
23
|
|
|
27
24
|
export const oidc = createOIDC({
|
|
28
25
|
issuer: 'https://your-idp.example.com',
|
|
@@ -32,22 +29,8 @@ export const oidc = createOIDC({
|
|
|
32
29
|
clientAuthMethod: 'client_secret_basic',
|
|
33
30
|
loginPath: '/auth/login',
|
|
34
31
|
redirectPath: '/auth/callback',
|
|
35
|
-
scope:
|
|
36
|
-
|
|
37
|
-
fetchUserInfo: true,
|
|
38
|
-
backChannelLogoutStore: createInMemoryBackChannelLogoutStore(),
|
|
39
|
-
transformSession(session) {
|
|
40
|
-
return {
|
|
41
|
-
...session,
|
|
42
|
-
groups: session.groups,
|
|
43
|
-
user: session.user
|
|
44
|
-
? {
|
|
45
|
-
...session.user,
|
|
46
|
-
groups: session.groups
|
|
47
|
-
}
|
|
48
|
-
: session.user
|
|
49
|
-
};
|
|
50
|
-
},
|
|
32
|
+
scope: 'openid profile email offline_access',
|
|
33
|
+
backChannelLogoutStore: 'memory',
|
|
51
34
|
cookieOptions: {
|
|
52
35
|
secure: process.env.NODE_ENV === 'production'
|
|
53
36
|
}
|
|
@@ -121,7 +104,7 @@ export async function load(event) {
|
|
|
121
104
|
|
|
122
105
|
```html
|
|
123
106
|
<script lang="ts">
|
|
124
|
-
import { OIDCContext } from 'sveltekit-oidc';
|
|
107
|
+
import { OIDCContext } from '@sourceregistry/sveltekit-oidc';
|
|
125
108
|
let { data } = $props();
|
|
126
109
|
</script>
|
|
127
110
|
|
|
@@ -139,7 +122,7 @@ export async function load(event) {
|
|
|
139
122
|
```html
|
|
140
123
|
<!-- src/lib/Account.svelte -->
|
|
141
124
|
<script lang="ts">
|
|
142
|
-
import { useOIDC } from 'sveltekit-oidc';
|
|
125
|
+
import { useOIDC } from '@sourceregistry/sveltekit-oidc';
|
|
143
126
|
|
|
144
127
|
const oidc = useOIDC();
|
|
145
128
|
</script>
|
|
@@ -183,19 +166,17 @@ export const oidc = createOIDC({
|
|
|
183
166
|
});
|
|
184
167
|
```
|
|
185
168
|
|
|
186
|
-
|
|
169
|
+
Wire `App.Locals` so `event.locals.oidc` is fully typed everywhere — `OIDCLocals` infers everything directly from the instance:
|
|
187
170
|
|
|
188
171
|
```ts
|
|
189
172
|
// src/app.d.ts
|
|
190
|
-
import type {
|
|
173
|
+
import type { OIDCLocals } from '@sourceregistry/sveltekit-oidc/server';
|
|
191
174
|
import { oidc } from '$lib/server/auth';
|
|
192
175
|
|
|
193
|
-
export type AppClaims = OIDCInferClaims<typeof oidc>;
|
|
194
|
-
|
|
195
176
|
declare global {
|
|
196
177
|
namespace App {
|
|
197
178
|
interface Locals {
|
|
198
|
-
oidc?:
|
|
179
|
+
oidc?: OIDCLocals<typeof oidc>;
|
|
199
180
|
}
|
|
200
181
|
}
|
|
201
182
|
}
|
|
@@ -203,14 +184,14 @@ declare global {
|
|
|
203
184
|
export {};
|
|
204
185
|
```
|
|
205
186
|
|
|
206
|
-
Now `event.locals.oidc?.claims?.roles` is `string[]` and `?.tenant` is `string | undefined` in every hook, load function, and action.
|
|
187
|
+
Now `event.locals.oidc?.claims?.roles` is `string[]` and `?.tenant` is `string | undefined` in every hook, load function, and action — no separate type aliases needed.
|
|
207
188
|
|
|
208
|
-
`OIDCContext` is a generic component, but Svelte doesn't support passing explicit type arguments in markup — `TClaims` is inferred from the `session` prop instead. Since `data.session` comes from `oidc.getPublicSession(event)`,
|
|
189
|
+
`OIDCContext` is a generic component, but Svelte doesn't support passing explicit type arguments in markup — `TClaims` is inferred from the `session` prop instead. Since `data.session` comes from `oidc.getPublicSession(event)`, the type flows through automatically:
|
|
209
190
|
|
|
210
191
|
```html
|
|
211
192
|
<!-- src/routes/+layout.svelte -->
|
|
212
193
|
<script lang="ts">
|
|
213
|
-
import { OIDCContext } from 'sveltekit-oidc';
|
|
194
|
+
import { OIDCContext } from '@sourceregistry/sveltekit-oidc';
|
|
214
195
|
let { data, children } = $props();
|
|
215
196
|
</script>
|
|
216
197
|
|
|
@@ -222,14 +203,13 @@ Now `event.locals.oidc?.claims?.roles` is `string[]` and `?.tenant` is `string |
|
|
|
222
203
|
```html
|
|
223
204
|
<!-- src/lib/Account.svelte -->
|
|
224
205
|
<script lang="ts">
|
|
225
|
-
import { useOIDC } from 'sveltekit-oidc';
|
|
226
|
-
import type { AppClaims } from '../../app.d.ts';
|
|
206
|
+
import { useOIDC } from '@sourceregistry/sveltekit-oidc';
|
|
227
207
|
|
|
228
|
-
const
|
|
208
|
+
const auth = useOIDC(); // TClaims inferred from App.Locals.oidc
|
|
229
209
|
</script>
|
|
230
210
|
|
|
231
|
-
{#if
|
|
232
|
-
<p>Roles: {
|
|
211
|
+
{#if auth.isAuthenticated}
|
|
212
|
+
<p>Roles: {auth.claims?.roles.join(', ')}</p>
|
|
233
213
|
{/if}
|
|
234
214
|
```
|
|
235
215
|
|
|
@@ -241,8 +221,9 @@ Backend apps commonly stash application-specific data on the session itself (e.g
|
|
|
241
221
|
|
|
242
222
|
```ts
|
|
243
223
|
// src/lib/server/auth.ts
|
|
244
|
-
import { createOIDC, type OIDCSession } from 'sveltekit-oidc/server';
|
|
224
|
+
import { createOIDC, type OIDCSession, type OIDCUserClaims } from '@sourceregistry/sveltekit-oidc/server';
|
|
245
225
|
|
|
226
|
+
type AppClaims = OIDCUserClaims & { tenant?: string };
|
|
246
227
|
type AppSession = OIDCSession<AppClaims> & {
|
|
247
228
|
tenantId: string;
|
|
248
229
|
permissions: string[];
|
|
@@ -261,20 +242,17 @@ export const oidc = createOIDC({
|
|
|
261
242
|
});
|
|
262
243
|
```
|
|
263
244
|
|
|
264
|
-
|
|
245
|
+
`app.d.ts` stays a one-liner — `OIDCLocals` picks up both `TClaims` and `TSession` from the instance:
|
|
265
246
|
|
|
266
247
|
```ts
|
|
267
248
|
// src/app.d.ts
|
|
268
|
-
import type {
|
|
249
|
+
import type { OIDCLocals } from '@sourceregistry/sveltekit-oidc/server';
|
|
269
250
|
import { oidc } from '$lib/server/auth';
|
|
270
251
|
|
|
271
|
-
export type AppClaims = OIDCInferClaims<typeof oidc>;
|
|
272
|
-
export type AppSession = OIDCInferSession<typeof oidc>;
|
|
273
|
-
|
|
274
252
|
declare global {
|
|
275
253
|
namespace App {
|
|
276
254
|
interface Locals {
|
|
277
|
-
oidc?:
|
|
255
|
+
oidc?: OIDCLocals<typeof oidc>;
|
|
278
256
|
}
|
|
279
257
|
}
|
|
280
258
|
}
|
|
@@ -284,6 +262,16 @@ export {};
|
|
|
284
262
|
|
|
285
263
|
Now `event.locals.oidc?.session?.tenantId` is `string` and `?.permissions` is `string[]` everywhere — and `oidc.requireAuth(event)` / `handleCallback`'s `onsuccess` resolve to `AppSession` directly.
|
|
286
264
|
|
|
265
|
+
Use `OIDCInferClaims` / `OIDCInferSession` when you need the types explicitly in non-Svelte code (utility functions, API helpers, etc.):
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
import type { OIDCInferClaims, OIDCInferSession } from '@sourceregistry/sveltekit-oidc/server';
|
|
269
|
+
import type { oidc } from '$lib/server/auth';
|
|
270
|
+
|
|
271
|
+
type AppClaims = OIDCInferClaims<typeof oidc>;
|
|
272
|
+
type AppSession = OIDCInferSession<typeof oidc>;
|
|
273
|
+
```
|
|
274
|
+
|
|
287
275
|
If `transformSession` is omitted, `TSession` defaults to `OIDCSession<TClaims>` — existing setups keep working unchanged.
|
|
288
276
|
|
|
289
277
|
## Example App
|
|
@@ -309,4 +297,4 @@ Set these environment variables to enable it:
|
|
|
309
297
|
- Use `transformClaims`, `transformUser`, and `transformSession` to project provider-specific claims into your own session shape.
|
|
310
298
|
- `check_session_iframe` monitoring only runs when `monitorSession` is enabled, the provider advertises that endpoint, and the session includes `session_state`.
|
|
311
299
|
- Refresh token handling is automatic when a valid refresh token is present.
|
|
312
|
-
- `event.locals.oidc` is attached by the hook
|
|
300
|
+
- `event.locals.oidc` is attached by the hook; wire it in `app.d.ts` with `OIDCLocals<typeof oidc>` — see [Typed Custom Claims](#typed-custom-claims).
|
package/dist/client/context.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type { OIDCDiscoveryDocument, OIDCPublicSession, OIDCUserClaims } from '../server/index.js';
|
|
1
|
+
import type { OIDCDiscoveryDocument, OIDCHandleLocals, OIDCPublicSession, OIDCUserClaims } from '../server/index.js';
|
|
2
|
+
type LocalsClaims = App.Locals extends {
|
|
3
|
+
oidc?: OIDCHandleLocals<infer C, any>;
|
|
4
|
+
} ? C : OIDCUserClaims;
|
|
2
5
|
export type OIDCClientContextValue<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
3
6
|
isAuthenticated: boolean;
|
|
4
7
|
session: OIDCPublicSession<TClaims> | null;
|
|
@@ -12,5 +15,6 @@ export type OIDCClientContextValue<TClaims extends OIDCUserClaims = OIDCUserClai
|
|
|
12
15
|
revalidate: () => Promise<void>;
|
|
13
16
|
};
|
|
14
17
|
export declare function setOIDCContext<TClaims extends OIDCUserClaims = OIDCUserClaims>(value: OIDCClientContextValue<TClaims>): OIDCClientContextValue<TClaims>;
|
|
15
|
-
export declare function getOIDCContext<TClaims extends OIDCUserClaims =
|
|
16
|
-
export declare function useOIDC<TClaims extends OIDCUserClaims =
|
|
18
|
+
export declare function getOIDCContext<TClaims extends OIDCUserClaims = LocalsClaims>(): OIDCClientContextValue<TClaims>;
|
|
19
|
+
export declare function useOIDC<TClaims extends OIDCUserClaims = LocalsClaims>(): OIDCClientContextValue<TClaims>;
|
|
20
|
+
export {};
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { default as OIDCContext } from './OIDCContext.svelte';
|
|
2
2
|
export { getOIDCContext, useOIDC } from './context.js';
|
|
3
|
-
export type { OIDCPublicSession, OIDCSessionManagementConfig, OIDCUserClaims } from '../server/index.js';
|
|
3
|
+
export type { OIDCInferClaims, OIDCInferSession, OIDCLocals, OIDCPublicSession, OIDCSessionManagementConfig, OIDCUserClaims } from '../server/index.js';
|
package/dist/server/index.js
CHANGED
|
@@ -6,7 +6,34 @@ import { asAuthorizationHeader, createClientSecretJwtAssertion, createPrivateKey
|
|
|
6
6
|
import { normalizeTokens, shouldRefresh } from './session.js';
|
|
7
7
|
import { absoluteUrl, base64UrlEncode, buildCookieOptions, collectGroups, createPKCEPair, normalizeIssuer, normalizeScope, parseProviderError, toPublicSession } from './utils.js';
|
|
8
8
|
export { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
9
|
+
import { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
10
|
+
function buildLogger(logger) {
|
|
11
|
+
const noop = () => { };
|
|
12
|
+
if (logger === false)
|
|
13
|
+
return { debug: noop, info: noop, warn: noop, error: noop };
|
|
14
|
+
if (logger)
|
|
15
|
+
return {
|
|
16
|
+
debug: (...a) => logger.debug?.(...a),
|
|
17
|
+
info: (...a) => logger.info?.(...a),
|
|
18
|
+
warn: (...a) => logger.warn?.(...a),
|
|
19
|
+
error: (...a) => logger.error?.(...a),
|
|
20
|
+
};
|
|
21
|
+
const p = '[sveltekit-oidc]';
|
|
22
|
+
return {
|
|
23
|
+
debug: (...a) => console.debug(p, ...a),
|
|
24
|
+
info: (...a) => console.info(p, ...a),
|
|
25
|
+
warn: (...a) => console.warn(p, ...a),
|
|
26
|
+
error: (...a) => console.error(p, ...a),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
9
29
|
export function createOIDC(options) {
|
|
30
|
+
const log = buildLogger(options.logger);
|
|
31
|
+
const sessionStore = options.sessionStore === 'memory'
|
|
32
|
+
? createInMemorySessionStore()
|
|
33
|
+
: options.sessionStore;
|
|
34
|
+
const backChannelLogoutStore = options.backChannelLogoutStore === 'memory'
|
|
35
|
+
? createInMemoryBackChannelLogoutStore()
|
|
36
|
+
: options.backChannelLogoutStore;
|
|
10
37
|
const cookieOptions = buildCookieOptions(options.cookieOptions);
|
|
11
38
|
const clockSkewSeconds = options.clockSkewSeconds ?? 30;
|
|
12
39
|
const refreshToleranceSeconds = options.refreshToleranceSeconds ?? 30;
|
|
@@ -20,7 +47,7 @@ export function createOIDC(options) {
|
|
|
20
47
|
let metadataPromise;
|
|
21
48
|
let jwksPromise;
|
|
22
49
|
async function readPersistedSession(cookies) {
|
|
23
|
-
if (!
|
|
50
|
+
if (!sessionStore) {
|
|
24
51
|
const session = cookieStore.readSession(cookies);
|
|
25
52
|
return session ? { session } : null;
|
|
26
53
|
}
|
|
@@ -28,7 +55,7 @@ export function createOIDC(options) {
|
|
|
28
55
|
if (!reference?.id) {
|
|
29
56
|
return null;
|
|
30
57
|
}
|
|
31
|
-
const session = await
|
|
58
|
+
const session = await sessionStore.get(reference.id);
|
|
32
59
|
if (!session) {
|
|
33
60
|
cookieStore.clearSessionReference(cookies);
|
|
34
61
|
return null;
|
|
@@ -39,22 +66,22 @@ export function createOIDC(options) {
|
|
|
39
66
|
};
|
|
40
67
|
}
|
|
41
68
|
async function writePersistedSession(cookies, session, sessionId) {
|
|
42
|
-
if (!
|
|
69
|
+
if (!sessionStore) {
|
|
43
70
|
cookieStore.writeSession(cookies, session);
|
|
44
71
|
return;
|
|
45
72
|
}
|
|
46
73
|
const id = sessionId ?? base64UrlEncode(randomBytes(24));
|
|
47
|
-
await
|
|
74
|
+
await sessionStore.set(id, session);
|
|
48
75
|
cookieStore.writeSessionReference(cookies, { id });
|
|
49
76
|
}
|
|
50
77
|
async function clearPersistedSession(cookies, sessionId) {
|
|
51
|
-
if (!
|
|
78
|
+
if (!sessionStore) {
|
|
52
79
|
cookieStore.clearSession(cookies);
|
|
53
80
|
return;
|
|
54
81
|
}
|
|
55
82
|
const id = sessionId ?? cookieStore.readSessionReference(cookies)?.id;
|
|
56
83
|
if (id) {
|
|
57
|
-
await
|
|
84
|
+
await sessionStore.delete(id);
|
|
58
85
|
}
|
|
59
86
|
cookieStore.clearSessionReference(cookies);
|
|
60
87
|
}
|
|
@@ -237,10 +264,10 @@ export function createOIDC(options) {
|
|
|
237
264
|
});
|
|
238
265
|
}
|
|
239
266
|
async function isRevoked(session) {
|
|
240
|
-
if (!session || !
|
|
267
|
+
if (!session || !backChannelLogoutStore) {
|
|
241
268
|
return false;
|
|
242
269
|
}
|
|
243
|
-
return
|
|
270
|
+
return backChannelLogoutStore.isRevoked(session);
|
|
244
271
|
}
|
|
245
272
|
async function maybeRefreshSession(event, persisted) {
|
|
246
273
|
const session = persisted?.session ?? null;
|
|
@@ -285,7 +312,8 @@ export function createOIDC(options) {
|
|
|
285
312
|
await writePersistedSession(event.cookies, finalSession, persisted?.id);
|
|
286
313
|
return finalSession;
|
|
287
314
|
}
|
|
288
|
-
catch {
|
|
315
|
+
catch (err) {
|
|
316
|
+
log.error('Token refresh failed — clearing session', err);
|
|
289
317
|
await clearPersistedSession(event.cookies, persisted?.id);
|
|
290
318
|
return null;
|
|
291
319
|
}
|
|
@@ -337,7 +365,8 @@ export function createOIDC(options) {
|
|
|
337
365
|
const code = event.url.searchParams.get('code');
|
|
338
366
|
if (!stateCookie || !state || !code || stateCookie.state !== state) {
|
|
339
367
|
cookieStore.clearState(event.cookies);
|
|
340
|
-
|
|
368
|
+
log.warn('Invalid or expired callback state — restarting login flow');
|
|
369
|
+
return signIn(event);
|
|
341
370
|
}
|
|
342
371
|
cookieStore.clearState(event.cookies);
|
|
343
372
|
const tokenResponse = await exchangeCode({
|
|
@@ -415,7 +444,7 @@ export function createOIDC(options) {
|
|
|
415
444
|
if (!metadata.backchannel_logout_supported) {
|
|
416
445
|
throw error(400, { message: 'Provider does not advertise back-channel logout support' });
|
|
417
446
|
}
|
|
418
|
-
if (!
|
|
447
|
+
if (!backChannelLogoutStore) {
|
|
419
448
|
throw error(500, {
|
|
420
449
|
message: 'backChannelLogoutStore is required for back-channel logout with cookie sessions'
|
|
421
450
|
});
|
|
@@ -426,7 +455,7 @@ export function createOIDC(options) {
|
|
|
426
455
|
throw error(400, { message: 'logout_token is required' });
|
|
427
456
|
}
|
|
428
457
|
const claims = await validateBackChannelLogoutToken(logoutToken);
|
|
429
|
-
await
|
|
458
|
+
await backChannelLogoutStore.revoke({
|
|
430
459
|
issuer: claims.iss,
|
|
431
460
|
clientId: options.clientId,
|
|
432
461
|
sid: claims.sid,
|
package/dist/server/types.d.ts
CHANGED
|
@@ -133,6 +133,12 @@ export type OIDCSessionManagementConfig = {
|
|
|
133
133
|
backChannelLogoutSupported: boolean;
|
|
134
134
|
backChannelLogoutSessionSupported: boolean;
|
|
135
135
|
};
|
|
136
|
+
export type OIDCLogger = {
|
|
137
|
+
debug?: (...args: unknown[]) => void;
|
|
138
|
+
info?: (...args: unknown[]) => void;
|
|
139
|
+
warn?: (...args: unknown[]) => void;
|
|
140
|
+
error?: (...args: unknown[]) => void;
|
|
141
|
+
};
|
|
136
142
|
export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims, TSession extends OIDCSession<TClaims> = OIDCSession<TClaims>> = {
|
|
137
143
|
issuer?: string;
|
|
138
144
|
discoveryUrl?: string;
|
|
@@ -144,7 +150,7 @@ export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessio
|
|
|
144
150
|
loginPath?: string;
|
|
145
151
|
redirectPath?: string;
|
|
146
152
|
postLogoutRedirectUri?: string;
|
|
147
|
-
scope?: string[];
|
|
153
|
+
scope?: string | string[];
|
|
148
154
|
audience?: string;
|
|
149
155
|
fetchUserInfo?: boolean;
|
|
150
156
|
sessionCookieName?: string;
|
|
@@ -155,8 +161,8 @@ export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessio
|
|
|
155
161
|
refreshToleranceSeconds?: number;
|
|
156
162
|
defaultLoginRedirect?: string;
|
|
157
163
|
defaultLogoutRedirect?: string;
|
|
158
|
-
sessionStore?: OIDCSessionStore<TClaims, TSession
|
|
159
|
-
backChannelLogoutStore?: OIDCBackChannelLogoutStore<TClaims, TSession
|
|
164
|
+
sessionStore?: OIDCSessionStore<TClaims, TSession> | 'memory';
|
|
165
|
+
backChannelLogoutStore?: OIDCBackChannelLogoutStore<TClaims, TSession> | 'memory';
|
|
160
166
|
transformClaims?: (claims: OIDCUserClaims) => MaybePromise<TClaims>;
|
|
161
167
|
transformUser?: (user: OIDCUserClaims | undefined, context: {
|
|
162
168
|
claims?: TClaims;
|
|
@@ -169,11 +175,12 @@ export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessio
|
|
|
169
175
|
isRefresh: boolean;
|
|
170
176
|
}) => MaybePromise<TSession>;
|
|
171
177
|
endpoints?: Partial<OIDCDiscoveryDocument>;
|
|
178
|
+
logger?: OIDCLogger | false;
|
|
172
179
|
};
|
|
173
180
|
export type OIDCLoginOptions = {
|
|
174
181
|
returnTo?: string;
|
|
175
182
|
prompt?: 'login' | 'consent' | 'none' | 'select_account';
|
|
176
|
-
scope?: string[];
|
|
183
|
+
scope?: string | string[];
|
|
177
184
|
extraParams?: Record<string, string>;
|
|
178
185
|
};
|
|
179
186
|
export type OIDCLogoutOptions = {
|
|
@@ -256,3 +263,4 @@ export type OIDCInstance<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessi
|
|
|
256
263
|
};
|
|
257
264
|
export type OIDCInferClaims<T> = T extends OIDCInstance<infer TClaims> ? TClaims : OIDCUserClaims;
|
|
258
265
|
export type OIDCInferSession<T> = T extends OIDCInstance<infer _TClaims, infer TSession> ? TSession : OIDCSession<OIDCUserClaims>;
|
|
266
|
+
export type OIDCLocals<T extends OIDCInstance<any, any>> = OIDCHandleLocals<OIDCInferClaims<T>, OIDCInferSession<T>>;
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare function createPKCEPair(length?: number): {
|
|
|
6
6
|
challenge: string;
|
|
7
7
|
};
|
|
8
8
|
export declare function normalizeIssuer(issuer: string): string;
|
|
9
|
-
export declare function normalizeScope(scope?: string[]): string[];
|
|
9
|
+
export declare function normalizeScope(scope?: string | string[]): string[];
|
|
10
10
|
export declare function normalizeStringArray(value: unknown): string[];
|
|
11
11
|
export declare function collectGroups<TClaims extends OIDCUserClaims = OIDCUserClaims>(...sources: Array<TClaims | undefined>): string[];
|
|
12
12
|
export declare function createSignedValue(value: string, secret: string): string;
|
package/dist/server/utils.js
CHANGED
|
@@ -13,7 +13,10 @@ export function normalizeIssuer(issuer) {
|
|
|
13
13
|
return issuer.endsWith('/') ? issuer.slice(0, -1) : issuer;
|
|
14
14
|
}
|
|
15
15
|
export function normalizeScope(scope) {
|
|
16
|
-
|
|
16
|
+
if (!scope)
|
|
17
|
+
return ['openid', 'profile', 'email'];
|
|
18
|
+
const arr = typeof scope === 'string' ? scope.trim().split(/\s+/) : scope;
|
|
19
|
+
return arr.length ? [...new Set(arr)] : ['openid', 'profile', 'email'];
|
|
17
20
|
}
|
|
18
21
|
export function normalizeStringArray(value) {
|
|
19
22
|
if (!value)
|