@sourceregistry/sveltekit-oidc 1.1.0 → 1.2.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 +73 -1
- package/dist/client/OIDCContext.svelte +8 -4
- package/dist/client/OIDCContext.svelte.d.ts +34 -15
- package/dist/client/context.d.ts +9 -9
- package/dist/server/cookies.d.ts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +14 -5
- package/dist/server/session.d.ts +2 -2
- package/dist/server/store.d.ts +3 -3
- package/dist/server/types.d.ts +43 -41
- package/dist/server/utils.d.ts +2 -2
- package/package.json +16 -16
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@ export const oidc = createOIDC({
|
|
|
33
33
|
loginPath: '/auth/login',
|
|
34
34
|
redirectPath: '/auth/callback',
|
|
35
35
|
scope: ['openid', 'profile', 'email', 'offline_access'],
|
|
36
|
+
clockSkewSeconds: 30,
|
|
36
37
|
fetchUserInfo: true,
|
|
37
38
|
backChannelLogoutStore: createInMemoryBackChannelLogoutStore(),
|
|
38
39
|
transformSession(session) {
|
|
@@ -159,6 +160,76 @@ export async function load(event) {
|
|
|
159
160
|
- periodic `invalidateAll()` revalidation so revoked server sessions are detected
|
|
160
161
|
- a client context for nested auth-aware components through `useOIDC()` / `getOIDCContext()`
|
|
161
162
|
|
|
163
|
+
## Typed Custom Claims
|
|
164
|
+
|
|
165
|
+
`createOIDC` infers a `TClaims` type from whatever `transformClaims` / `transformUser` / `transformSession` return, and threads it through the session, `event.locals.oidc`, `OIDCPublicSession`, and the client context — no casts needed.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
// src/lib/server/auth.ts
|
|
169
|
+
export const oidc = createOIDC({
|
|
170
|
+
issuer: 'https://your-idp.example.com',
|
|
171
|
+
clientId: process.env.OIDC_CLIENT_ID!,
|
|
172
|
+
cookieSecret: process.env.OIDC_COOKIE_SECRET!,
|
|
173
|
+
transformClaims: (claims) => ({
|
|
174
|
+
...claims,
|
|
175
|
+
roles: (claims.roles as string[]) ?? [],
|
|
176
|
+
tenant: claims.tenant as string | undefined
|
|
177
|
+
})
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Extract the inferred type with `OIDCInferClaims` and apply it to `App.Locals` so `event.locals.oidc` is typed everywhere:
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
// src/app.d.ts
|
|
185
|
+
import type { OIDCHandleLocals, OIDCInferClaims } from 'sveltekit-oidc/server';
|
|
186
|
+
import { oidc } from '$lib/server/auth';
|
|
187
|
+
|
|
188
|
+
export type AppClaims = OIDCInferClaims<typeof oidc>;
|
|
189
|
+
|
|
190
|
+
declare global {
|
|
191
|
+
namespace App {
|
|
192
|
+
interface Locals {
|
|
193
|
+
oidc?: OIDCHandleLocals<AppClaims>;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export {};
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Now `event.locals.oidc?.claims?.roles` is `string[]` and `?.tenant` is `string | undefined` in every hook, load function, and action.
|
|
202
|
+
|
|
203
|
+
`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)`, it's already typed `OIDCPublicSession<AppClaims> | null`, so the inference flows through automatically:
|
|
204
|
+
|
|
205
|
+
```html
|
|
206
|
+
<!-- src/routes/+layout.svelte -->
|
|
207
|
+
<script lang="ts">
|
|
208
|
+
import { OIDCContext } from 'sveltekit-oidc';
|
|
209
|
+
let { data, children } = $props();
|
|
210
|
+
</script>
|
|
211
|
+
|
|
212
|
+
<OIDCContext session={data.session} config={data.sessionManagement}>
|
|
213
|
+
{@render children()}
|
|
214
|
+
</OIDCContext>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
```html
|
|
218
|
+
<!-- src/lib/Account.svelte -->
|
|
219
|
+
<script lang="ts">
|
|
220
|
+
import { useOIDC } from 'sveltekit-oidc';
|
|
221
|
+
import type { AppClaims } from '../../app.d.ts';
|
|
222
|
+
|
|
223
|
+
const oidc = useOIDC<AppClaims>();
|
|
224
|
+
</script>
|
|
225
|
+
|
|
226
|
+
{#if oidc.isAuthenticated}
|
|
227
|
+
<p>Roles: {oidc.claims?.roles.join(', ')}</p>
|
|
228
|
+
{/if}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
If `transformClaims` (and friends) are omitted, `TClaims` defaults to `OIDCUserClaims` — existing setups keep working unchanged.
|
|
232
|
+
|
|
162
233
|
## Example App
|
|
163
234
|
|
|
164
235
|
This repository now includes a runnable example under [src/routes](C:/Users/alexa/WebstormProjects/github.com/SourceRegistry/sveltekit-oidc/src/routes) and [src/hooks.server.ts](C:/Users/alexa/WebstormProjects/github.com/SourceRegistry/sveltekit-oidc/src/hooks.server.ts).
|
|
@@ -175,10 +246,11 @@ Set these environment variables to enable it:
|
|
|
175
246
|
## Notes
|
|
176
247
|
|
|
177
248
|
- `cookieSecret` should be a strong random secret and must stay stable across instances.
|
|
249
|
+
- `clockSkewSeconds` defaults to `30` and tolerates small clock drift between your app and the identity provider.
|
|
178
250
|
- `createInMemoryBackChannelLogoutStore()` is suitable for local development or single-instance deployments. Use Redis, SQL, or another shared store for production.
|
|
179
251
|
- The library validates `id_token` and `logout_token` values through `@sourceregistry/node-jwt` and provider JWKS metadata.
|
|
180
252
|
- `groups` are normalized onto the session from `groups` and `roles` claims when present.
|
|
181
253
|
- Use `transformClaims`, `transformUser`, and `transformSession` to project provider-specific claims into your own session shape.
|
|
182
254
|
- `check_session_iframe` monitoring only runs when the provider advertises that endpoint and the session includes `session_state`.
|
|
183
255
|
- Refresh token handling is automatic when a valid refresh token is present.
|
|
184
|
-
- `event.locals.oidc` is attached by the hook
|
|
256
|
+
- `event.locals.oidc` is attached by the hook and typed via `OIDCHandleLocals<TClaims>`; see [Typed Custom Claims](#typed-custom-claims) for wiring your own claim shapes through `app.d.ts`.
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
<script lang="ts">
|
|
1
|
+
<script lang="ts" generics="TClaims extends OIDCUserClaims = OIDCUserClaims">
|
|
2
2
|
import { goto, invalidateAll } from '$app/navigation';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
|
|
5
5
|
import { setOIDCContext } from './context.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
OIDCPublicSession,
|
|
8
|
+
OIDCSessionManagementConfig,
|
|
9
|
+
OIDCUserClaims
|
|
10
|
+
} from '../server/index.js';
|
|
7
11
|
|
|
8
12
|
type RedirectMode = 'login' | 'logout' | 'reload' | 'none';
|
|
9
13
|
|
|
@@ -19,7 +23,7 @@
|
|
|
19
23
|
redirectIfUnauthenticated = false,
|
|
20
24
|
children
|
|
21
25
|
}: {
|
|
22
|
-
session?: OIDCPublicSession | null;
|
|
26
|
+
session?: OIDCPublicSession<TClaims> | null;
|
|
23
27
|
config: OIDCSessionManagementConfig;
|
|
24
28
|
loginPath?: string;
|
|
25
29
|
logoutPath?: string;
|
|
@@ -44,7 +48,7 @@
|
|
|
44
48
|
Boolean(session?.isAuthenticated && session?.sessionState && iframeUrl)
|
|
45
49
|
);
|
|
46
50
|
|
|
47
|
-
const context = setOIDCContext({
|
|
51
|
+
const context = setOIDCContext<TClaims>({
|
|
48
52
|
get isAuthenticated() {
|
|
49
53
|
return Boolean(session?.isAuthenticated);
|
|
50
54
|
},
|
|
@@ -1,18 +1,37 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { OIDCPublicSession, OIDCSessionManagementConfig } from '../server/index.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
2
|
+
import type { OIDCPublicSession, OIDCSessionManagementConfig, OIDCUserClaims } from '../server/index.js';
|
|
3
|
+
declare function $$render<TClaims extends OIDCUserClaims = OIDCUserClaims>(): {
|
|
4
|
+
props: {
|
|
5
|
+
session?: OIDCPublicSession<TClaims> | null;
|
|
6
|
+
config: OIDCSessionManagementConfig;
|
|
7
|
+
loginPath?: string;
|
|
8
|
+
logoutPath?: string;
|
|
9
|
+
checkSessionIntervalMs?: number;
|
|
10
|
+
revalidateIntervalMs?: number;
|
|
11
|
+
redirectOnExpired?: "none" | "login" | "logout" | "reload";
|
|
12
|
+
redirectOnRevoked?: "none" | "login" | "logout" | "reload";
|
|
13
|
+
redirectIfUnauthenticated?: boolean;
|
|
14
|
+
children?: Snippet;
|
|
15
|
+
};
|
|
16
|
+
exports: {};
|
|
17
|
+
bindings: "";
|
|
18
|
+
slots: {};
|
|
19
|
+
events: {};
|
|
15
20
|
};
|
|
16
|
-
declare
|
|
17
|
-
|
|
21
|
+
declare class __sveltets_Render<TClaims extends OIDCUserClaims = OIDCUserClaims> {
|
|
22
|
+
props(): ReturnType<typeof $$render<TClaims>>['props'];
|
|
23
|
+
events(): ReturnType<typeof $$render<TClaims>>['events'];
|
|
24
|
+
slots(): ReturnType<typeof $$render<TClaims>>['slots'];
|
|
25
|
+
bindings(): "";
|
|
26
|
+
exports(): {};
|
|
27
|
+
}
|
|
28
|
+
interface $$IsomorphicComponent {
|
|
29
|
+
new <TClaims extends OIDCUserClaims = OIDCUserClaims>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TClaims>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TClaims>['props']>, ReturnType<__sveltets_Render<TClaims>['events']>, ReturnType<__sveltets_Render<TClaims>['slots']>> & {
|
|
30
|
+
$$bindings?: ReturnType<__sveltets_Render<TClaims>['bindings']>;
|
|
31
|
+
} & ReturnType<__sveltets_Render<TClaims>['exports']>;
|
|
32
|
+
<TClaims extends OIDCUserClaims = OIDCUserClaims>(internal: unknown, props: ReturnType<__sveltets_Render<TClaims>['props']> & {}): ReturnType<__sveltets_Render<TClaims>['exports']>;
|
|
33
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
34
|
+
}
|
|
35
|
+
declare const OIDCContext: $$IsomorphicComponent;
|
|
36
|
+
type OIDCContext<TClaims extends OIDCUserClaims = OIDCUserClaims> = InstanceType<typeof OIDCContext<TClaims>>;
|
|
18
37
|
export default OIDCContext;
|
package/dist/client/context.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { OIDCDiscoveryDocument, OIDCPublicSession } from '../server/index.js';
|
|
2
|
-
export type OIDCClientContextValue = {
|
|
1
|
+
import type { OIDCDiscoveryDocument, OIDCPublicSession, OIDCUserClaims } from '../server/index.js';
|
|
2
|
+
export type OIDCClientContextValue<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
3
3
|
isAuthenticated: boolean;
|
|
4
|
-
session: OIDCPublicSession | null;
|
|
5
|
-
user: OIDCPublicSession['user'];
|
|
6
|
-
claims: OIDCPublicSession['claims'];
|
|
7
|
-
groups: OIDCPublicSession['groups'];
|
|
4
|
+
session: OIDCPublicSession<TClaims> | null;
|
|
5
|
+
user: OIDCPublicSession<TClaims>['user'];
|
|
6
|
+
claims: OIDCPublicSession<TClaims>['claims'];
|
|
7
|
+
groups: OIDCPublicSession<TClaims>['groups'];
|
|
8
8
|
metadata?: Pick<OIDCDiscoveryDocument, 'issuer' | 'check_session_iframe' | 'end_session_endpoint' | 'backchannel_logout_supported' | 'backchannel_logout_session_supported'>;
|
|
9
9
|
status: 'authenticated' | 'unauthenticated' | 'expired' | 'revoked';
|
|
10
10
|
login: (returnTo?: string) => void;
|
|
11
11
|
logout: (clearSessionOnly?: boolean) => Promise<void>;
|
|
12
12
|
revalidate: () => Promise<void>;
|
|
13
13
|
};
|
|
14
|
-
export declare function setOIDCContext(value: OIDCClientContextValue): OIDCClientContextValue
|
|
15
|
-
export declare function getOIDCContext(): OIDCClientContextValue
|
|
16
|
-
export declare function useOIDC(): OIDCClientContextValue
|
|
14
|
+
export declare function setOIDCContext<TClaims extends OIDCUserClaims = OIDCUserClaims>(value: OIDCClientContextValue<TClaims>): OIDCClientContextValue<TClaims>;
|
|
15
|
+
export declare function getOIDCContext<TClaims extends OIDCUserClaims = OIDCUserClaims>(): OIDCClientContextValue<TClaims>;
|
|
16
|
+
export declare function useOIDC<TClaims extends OIDCUserClaims = OIDCUserClaims>(): OIDCClientContextValue<TClaims>;
|
package/dist/server/cookies.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { CookieOptions, OIDCCookies } from './types.js';
|
|
2
|
-
export declare function createOIDCCookieStore(cookieSecret: string, sessionCookieName: string, stateCookieName: string, cookieOptions: CookieOptions): OIDCCookies
|
|
1
|
+
import type { CookieOptions, OIDCCookies, OIDCUserClaims } from './types.js';
|
|
2
|
+
export declare function createOIDCCookieStore<TClaims extends OIDCUserClaims = OIDCUserClaims>(cookieSecret: string, sessionCookieName: string, stateCookieName: string, cookieOptions: CookieOptions): OIDCCookies<TClaims>;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { OIDCOptions, OIDCInstance } from './types.js';
|
|
1
|
+
import type { OIDCOptions, OIDCInstance, OIDCUserClaims } from './types.js';
|
|
2
2
|
export type * from './types.js';
|
|
3
3
|
export { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
4
|
-
export declare function createOIDC(options: OIDCOptions): OIDCInstance
|
|
4
|
+
export declare function createOIDC<TClaims extends OIDCUserClaims = OIDCUserClaims>(options: OIDCOptions<TClaims>): OIDCInstance<TClaims>;
|
|
5
5
|
export declare const OpenIDConnect: typeof createOIDC;
|
package/dist/server/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { absoluteUrl, base64UrlEncode, buildCookieOptions, collectGroups, create
|
|
|
8
8
|
export { createInMemoryBackChannelLogoutStore, createInMemorySessionStore } from './store.js';
|
|
9
9
|
export function createOIDC(options) {
|
|
10
10
|
const cookieOptions = buildCookieOptions(options.cookieOptions);
|
|
11
|
+
const clockSkewSeconds = options.clockSkewSeconds ?? 30;
|
|
11
12
|
const refreshToleranceSeconds = options.refreshToleranceSeconds ?? 30;
|
|
12
13
|
const sessionCookieName = options.sessionCookieName ?? 'oidc_session';
|
|
13
14
|
const stateCookieName = options.stateCookieName ?? 'oidc_auth_state';
|
|
@@ -195,9 +196,12 @@ export function createOIDC(options) {
|
|
|
195
196
|
const claims = await verifyJwtWithJwks(idToken, {
|
|
196
197
|
issuer: metadata.issuer,
|
|
197
198
|
audience: options.clientId,
|
|
198
|
-
algorithms: metadata.id_token_signing_alg_values_supported
|
|
199
|
+
algorithms: metadata.id_token_signing_alg_values_supported,
|
|
200
|
+
clockSkew: clockSkewSeconds
|
|
199
201
|
});
|
|
200
|
-
const transformedClaims = options.transformClaims
|
|
202
|
+
const transformedClaims = options.transformClaims
|
|
203
|
+
? await options.transformClaims(claims)
|
|
204
|
+
: claims;
|
|
201
205
|
if (transformedClaims.nonce !== nonce) {
|
|
202
206
|
throw error(401, { message: 'Invalid id_token nonce' });
|
|
203
207
|
}
|
|
@@ -207,7 +211,8 @@ export function createOIDC(options) {
|
|
|
207
211
|
const metadata = await getMetadata();
|
|
208
212
|
const claims = await verifyJwtWithJwks(logoutToken, {
|
|
209
213
|
issuer: metadata.issuer,
|
|
210
|
-
audience: options.clientId
|
|
214
|
+
audience: options.clientId,
|
|
215
|
+
clockSkew: clockSkewSeconds
|
|
211
216
|
});
|
|
212
217
|
if (!claims.events?.['http://schemas.openid.net/event/backchannel-logout']) {
|
|
213
218
|
throw error(400, { message: 'Invalid logout_token events claim' });
|
|
@@ -255,7 +260,9 @@ export function createOIDC(options) {
|
|
|
255
260
|
? await validateIdToken(tokenResponse.id_token, session.nonce)
|
|
256
261
|
: session.claims;
|
|
257
262
|
const rawUser = options.fetchUserInfo !== false ? await fetchUserInfo(tokenResponse.access_token) : session.user;
|
|
258
|
-
const user = options.transformUser
|
|
263
|
+
const user = options.transformUser
|
|
264
|
+
? await options.transformUser(rawUser, { claims })
|
|
265
|
+
: rawUser;
|
|
259
266
|
const nextSession = {
|
|
260
267
|
...session,
|
|
261
268
|
sub: claims?.sub ?? session.sub,
|
|
@@ -344,7 +351,9 @@ export function createOIDC(options) {
|
|
|
344
351
|
const rawUser = options.fetchUserInfo === false
|
|
345
352
|
? undefined
|
|
346
353
|
: await fetchUserInfo(tokenResponse.access_token).catch(() => undefined);
|
|
347
|
-
const user = options.transformUser
|
|
354
|
+
const user = options.transformUser
|
|
355
|
+
? await options.transformUser(rawUser, { claims })
|
|
356
|
+
: rawUser;
|
|
348
357
|
const metadata = await getMetadata();
|
|
349
358
|
const now = Math.floor(Date.now() / 1000);
|
|
350
359
|
const session = {
|
package/dist/server/session.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { OIDCSession, OIDCSessionTokens, OIDCTokenResponse } from './types.js';
|
|
1
|
+
import type { OIDCSession, OIDCSessionTokens, OIDCTokenResponse, OIDCUserClaims } from './types.js';
|
|
2
2
|
export declare function normalizeTokens(tokenResponse: OIDCTokenResponse, defaultScope: string[], existing?: OIDCSessionTokens, now?: number): OIDCSessionTokens;
|
|
3
|
-
export declare function shouldRefresh(session: OIDCSession
|
|
3
|
+
export declare function shouldRefresh<TClaims extends OIDCUserClaims = OIDCUserClaims>(session: OIDCSession<TClaims>, refreshToleranceSeconds: number, now?: number): boolean;
|
package/dist/server/store.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { OIDCBackChannelLogoutStore, OIDCSessionStore } from './types.js';
|
|
2
|
-
export declare function createInMemoryBackChannelLogoutStore(): OIDCBackChannelLogoutStore
|
|
3
|
-
export declare function createInMemorySessionStore(): OIDCSessionStore
|
|
1
|
+
import type { OIDCBackChannelLogoutStore, OIDCSessionStore, OIDCUserClaims } from './types.js';
|
|
2
|
+
export declare function createInMemoryBackChannelLogoutStore<TClaims extends OIDCUserClaims = OIDCUserClaims>(): OIDCBackChannelLogoutStore<TClaims>;
|
|
3
|
+
export declare function createInMemorySessionStore<TClaims extends OIDCUserClaims = OIDCUserClaims>(): OIDCSessionStore<TClaims>;
|
package/dist/server/types.d.ts
CHANGED
|
@@ -56,7 +56,7 @@ export type OIDCUserClaims = Record<string, unknown> & {
|
|
|
56
56
|
nbf?: number;
|
|
57
57
|
nonce?: string;
|
|
58
58
|
};
|
|
59
|
-
export type OIDCSession = {
|
|
59
|
+
export type OIDCSession<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
60
60
|
issuer: string;
|
|
61
61
|
clientId: string;
|
|
62
62
|
nonce?: string;
|
|
@@ -64,16 +64,16 @@ export type OIDCSession = {
|
|
|
64
64
|
sid?: string;
|
|
65
65
|
sessionState?: string;
|
|
66
66
|
groups: string[];
|
|
67
|
-
user?:
|
|
68
|
-
claims?:
|
|
67
|
+
user?: TClaims;
|
|
68
|
+
claims?: TClaims;
|
|
69
69
|
tokens: OIDCSessionTokens;
|
|
70
70
|
createdAt: number;
|
|
71
71
|
refreshedAt: number;
|
|
72
72
|
};
|
|
73
|
-
export type OIDCPublicSession = {
|
|
73
|
+
export type OIDCPublicSession<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
74
74
|
isAuthenticated: boolean;
|
|
75
|
-
user?:
|
|
76
|
-
claims?:
|
|
75
|
+
user?: TClaims;
|
|
76
|
+
claims?: TClaims;
|
|
77
77
|
groups: string[];
|
|
78
78
|
scope: string[];
|
|
79
79
|
expiresAt?: number;
|
|
@@ -114,13 +114,13 @@ export type OIDCBackChannelLogoutRecord = {
|
|
|
114
114
|
jti: string;
|
|
115
115
|
iat: number;
|
|
116
116
|
};
|
|
117
|
-
export type OIDCBackChannelLogoutStore = {
|
|
117
|
+
export type OIDCBackChannelLogoutStore<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
118
118
|
revoke(record: OIDCBackChannelLogoutRecord): MaybePromise<void>;
|
|
119
|
-
isRevoked(session: OIDCSession): MaybePromise<boolean>;
|
|
119
|
+
isRevoked(session: OIDCSession<TClaims>): MaybePromise<boolean>;
|
|
120
120
|
};
|
|
121
|
-
export type OIDCSessionStore = {
|
|
122
|
-
get(sessionId: string): MaybePromise<OIDCSession | null>;
|
|
123
|
-
set(sessionId: string, session: OIDCSession): MaybePromise<void>;
|
|
121
|
+
export type OIDCSessionStore<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
122
|
+
get(sessionId: string): MaybePromise<OIDCSession<TClaims> | null>;
|
|
123
|
+
set(sessionId: string, session: OIDCSession<TClaims>): MaybePromise<void>;
|
|
124
124
|
delete(sessionId: string): MaybePromise<void>;
|
|
125
125
|
};
|
|
126
126
|
export type OIDCSessionManagementConfig = {
|
|
@@ -133,7 +133,7 @@ export type OIDCSessionManagementConfig = {
|
|
|
133
133
|
backChannelLogoutSupported: boolean;
|
|
134
134
|
backChannelLogoutSessionSupported: boolean;
|
|
135
135
|
};
|
|
136
|
-
export type OIDCOptions = {
|
|
136
|
+
export type OIDCOptions<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
137
137
|
issuer?: string;
|
|
138
138
|
discoveryUrl?: string;
|
|
139
139
|
clientId: string;
|
|
@@ -151,22 +151,23 @@ export type OIDCOptions = {
|
|
|
151
151
|
stateCookieName?: string;
|
|
152
152
|
cookieSecret: string;
|
|
153
153
|
cookieOptions?: Partial<CookieOptions>;
|
|
154
|
+
clockSkewSeconds?: number;
|
|
154
155
|
refreshToleranceSeconds?: number;
|
|
155
156
|
defaultLoginRedirect?: string;
|
|
156
157
|
defaultLogoutRedirect?: string;
|
|
157
|
-
sessionStore?: OIDCSessionStore
|
|
158
|
-
backChannelLogoutStore?: OIDCBackChannelLogoutStore
|
|
159
|
-
transformClaims?: (claims: OIDCUserClaims) => MaybePromise<
|
|
158
|
+
sessionStore?: OIDCSessionStore<TClaims>;
|
|
159
|
+
backChannelLogoutStore?: OIDCBackChannelLogoutStore<TClaims>;
|
|
160
|
+
transformClaims?: (claims: OIDCUserClaims) => MaybePromise<TClaims>;
|
|
160
161
|
transformUser?: (user: OIDCUserClaims | undefined, context: {
|
|
161
|
-
claims?:
|
|
162
|
-
}) => MaybePromise<
|
|
163
|
-
transformSession?: (session: OIDCSession
|
|
162
|
+
claims?: TClaims;
|
|
163
|
+
}) => MaybePromise<TClaims | undefined>;
|
|
164
|
+
transformSession?: (session: OIDCSession<TClaims>, context: {
|
|
164
165
|
event?: RequestEvent;
|
|
165
166
|
tokenResponse?: OIDCTokenResponse;
|
|
166
|
-
claims?:
|
|
167
|
-
user?:
|
|
167
|
+
claims?: TClaims;
|
|
168
|
+
user?: TClaims;
|
|
168
169
|
isRefresh: boolean;
|
|
169
|
-
}) => MaybePromise<OIDCSession
|
|
170
|
+
}) => MaybePromise<OIDCSession<TClaims>>;
|
|
170
171
|
endpoints?: Partial<OIDCDiscoveryDocument>;
|
|
171
172
|
};
|
|
172
173
|
export type OIDCLoginOptions = {
|
|
@@ -180,16 +181,16 @@ export type OIDCLogoutOptions = {
|
|
|
180
181
|
state?: string;
|
|
181
182
|
clearSessionOnly?: boolean;
|
|
182
183
|
};
|
|
183
|
-
export type OIDCCallbackResult = {
|
|
184
|
-
session: OIDCSession
|
|
184
|
+
export type OIDCCallbackResult<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
185
|
+
session: OIDCSession<TClaims>;
|
|
185
186
|
returnTo: string;
|
|
186
187
|
};
|
|
187
|
-
export type OIDCHandleLocals = {
|
|
188
|
+
export type OIDCHandleLocals<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
188
189
|
isAuthenticated: boolean;
|
|
189
|
-
session: OIDCSession | null;
|
|
190
|
-
user?:
|
|
191
|
-
claims?:
|
|
192
|
-
requireAuth: () => Promise<OIDCSession
|
|
190
|
+
session: OIDCSession<TClaims> | null;
|
|
191
|
+
user?: TClaims;
|
|
192
|
+
claims?: TClaims;
|
|
193
|
+
requireAuth: () => Promise<OIDCSession<TClaims>>;
|
|
193
194
|
clearSession: () => Promise<void>;
|
|
194
195
|
};
|
|
195
196
|
export type OIDCStateCookie = {
|
|
@@ -199,8 +200,8 @@ export type OIDCStateCookie = {
|
|
|
199
200
|
returnTo: string;
|
|
200
201
|
createdAt: number;
|
|
201
202
|
};
|
|
202
|
-
export type OIDCCallbackHandlerOptions = {
|
|
203
|
-
onsuccess?: (event: RequestEvent, result: OIDCCallbackResult) => MaybePromise<Response | void>;
|
|
203
|
+
export type OIDCCallbackHandlerOptions<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
204
|
+
onsuccess?: (event: RequestEvent, result: OIDCCallbackResult<TClaims>) => MaybePromise<Response | void>;
|
|
204
205
|
onfailure?: (event: RequestEvent, err: unknown) => MaybePromise<Response | void>;
|
|
205
206
|
redirectTo?: string;
|
|
206
207
|
};
|
|
@@ -213,9 +214,9 @@ export type OIDCClientAssertionOptions = {
|
|
|
213
214
|
clientId: string;
|
|
214
215
|
clientSecret?: string;
|
|
215
216
|
};
|
|
216
|
-
export type OIDCCookies = {
|
|
217
|
-
readSession(cookies: Cookies): OIDCSession | null;
|
|
218
|
-
writeSession(cookies: Cookies, session: OIDCSession): void;
|
|
217
|
+
export type OIDCCookies<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
218
|
+
readSession(cookies: Cookies): OIDCSession<TClaims> | null;
|
|
219
|
+
writeSession(cookies: Cookies, session: OIDCSession<TClaims>): void;
|
|
219
220
|
clearSession(cookies: Cookies): void;
|
|
220
221
|
readSessionReference(cookies: Cookies): {
|
|
221
222
|
id: string;
|
|
@@ -228,28 +229,29 @@ export type OIDCCookies = {
|
|
|
228
229
|
writeState(cookies: Cookies, state: OIDCStateCookie): void;
|
|
229
230
|
clearState(cookies: Cookies): void;
|
|
230
231
|
};
|
|
231
|
-
export type OIDCPersistedSession = {
|
|
232
|
+
export type OIDCPersistedSession<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
232
233
|
id?: string;
|
|
233
|
-
session: OIDCSession
|
|
234
|
+
session: OIDCSession<TClaims>;
|
|
234
235
|
};
|
|
235
|
-
export type OIDCInstance = {
|
|
236
|
+
export type OIDCInstance<TClaims extends OIDCUserClaims = OIDCUserClaims> = {
|
|
236
237
|
handle: Handle;
|
|
237
238
|
getMetadata: () => Promise<OIDCDiscoveryDocument>;
|
|
238
|
-
getSession: (event: RequestEvent) => Promise<OIDCSession | null>;
|
|
239
|
-
getPublicSession: (event: RequestEvent) => Promise<OIDCPublicSession | null>;
|
|
239
|
+
getSession: (event: RequestEvent) => Promise<OIDCSession<TClaims> | null>;
|
|
240
|
+
getPublicSession: (event: RequestEvent) => Promise<OIDCPublicSession<TClaims> | null>;
|
|
240
241
|
getSessionManagementConfig: () => Promise<OIDCSessionManagementConfig>;
|
|
241
242
|
login: (event: RequestEvent, loginOptions?: OIDCLoginOptions) => Promise<never>;
|
|
242
243
|
logout: (event: RequestEvent, logoutOptions?: OIDCLogoutOptions) => Promise<never>;
|
|
243
|
-
handleCallback: (event: RequestEvent) => Promise<OIDCCallbackResult
|
|
244
|
+
handleCallback: (event: RequestEvent) => Promise<OIDCCallbackResult<TClaims>>;
|
|
244
245
|
handleBackChannelLogout: (event: RequestEvent) => Promise<Response>;
|
|
245
246
|
loginHandler: (defaults?: OIDCLoginOptions) => RequestHandler;
|
|
246
|
-
callbackHandler: (handlerOptions?: OIDCCallbackHandlerOptions) => RequestHandler;
|
|
247
|
+
callbackHandler: (handlerOptions?: OIDCCallbackHandlerOptions<TClaims>) => RequestHandler;
|
|
247
248
|
logoutHandler: (defaults?: OIDCLogoutOptions) => RequestHandler;
|
|
248
249
|
backChannelLogoutHandler: () => RequestHandler;
|
|
249
250
|
createActions: (actionOptions?: OIDCActionOptions) => Readonly<{
|
|
250
251
|
login: Action;
|
|
251
252
|
logout: Action;
|
|
252
253
|
}>;
|
|
253
|
-
requireAuth: (event: RequestEvent, returnTo?: string) => Promise<OIDCSession
|
|
254
|
+
requireAuth: (event: RequestEvent, returnTo?: string) => Promise<OIDCSession<TClaims>>;
|
|
254
255
|
clearSession: (cookies: Cookies) => Promise<void>;
|
|
255
256
|
};
|
|
257
|
+
export type OIDCInferClaims<T> = T extends OIDCInstance<infer TClaims> ? TClaims : OIDCUserClaims;
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare function createPKCEPair(length?: number): {
|
|
|
8
8
|
export declare function normalizeIssuer(issuer: string): string;
|
|
9
9
|
export declare function normalizeScope(scope?: string[]): string[];
|
|
10
10
|
export declare function normalizeStringArray(value: unknown): string[];
|
|
11
|
-
export declare function collectGroups(...sources: Array<
|
|
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;
|
|
13
13
|
export declare function verifySignedValue(value: string, secret: string): string | null;
|
|
14
14
|
export declare function serializeSignedCookie(payload: unknown, secret: string): string;
|
|
@@ -16,4 +16,4 @@ export declare function parseSignedCookie<T>(value: string | undefined, secret:
|
|
|
16
16
|
export declare function buildCookieOptions(options?: Partial<CookieOptions>): CookieOptions;
|
|
17
17
|
export declare function parseProviderError(event: RequestEvent): null;
|
|
18
18
|
export declare function absoluteUrl(event: RequestEvent, pathOrUrl: string): string;
|
|
19
|
-
export declare function toPublicSession(session: OIDCSession | null): OIDCPublicSession | null;
|
|
19
|
+
export declare function toPublicSession<TClaims extends OIDCUserClaims = OIDCUserClaims>(session: OIDCSession<TClaims> | null): OIDCPublicSession<TClaims> | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sourceregistry/sveltekit-oidc",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "OIDC authentication helpers for SvelteKit applications.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"scripts": {
|
|
@@ -57,22 +57,22 @@
|
|
|
57
57
|
"svelte": "^5.0.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@sveltejs/adapter-auto": "^7.0.
|
|
61
|
-
"@sveltejs/kit": "^2.
|
|
62
|
-
"@sveltejs/package": "^2.5.
|
|
63
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
64
|
-
"@types/node": "^25.
|
|
60
|
+
"@sveltejs/adapter-auto": "^7.0.1",
|
|
61
|
+
"@sveltejs/kit": "^2.63.1",
|
|
62
|
+
"@sveltejs/package": "^2.5.8",
|
|
63
|
+
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
64
|
+
"@types/node": "^25.9.2",
|
|
65
65
|
"@semantic-release/changelog": "^6.0.3",
|
|
66
66
|
"@semantic-release/git": "^10.0.1",
|
|
67
|
-
"publint": "^0.3.
|
|
68
|
-
"svelte": "^5.
|
|
69
|
-
"svelte-check": "^4.
|
|
70
|
-
"typescript": "^
|
|
71
|
-
"vite": "^
|
|
72
|
-
"@vitest/coverage-v8": "^4.1.
|
|
73
|
-
"vitest": "^4.1.
|
|
74
|
-
"@sourceregistry/semantic-release-jsr": "^1.
|
|
75
|
-
"typedoc": "^0.28.
|
|
67
|
+
"publint": "^0.3.21",
|
|
68
|
+
"svelte": "^5.56.3",
|
|
69
|
+
"svelte-check": "^4.6.0",
|
|
70
|
+
"typescript": "^6.0.3",
|
|
71
|
+
"vite": "^8.0.16",
|
|
72
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
73
|
+
"vitest": "^4.1.8",
|
|
74
|
+
"@sourceregistry/semantic-release-jsr": "^1.1.1",
|
|
75
|
+
"typedoc": "^0.28.19"
|
|
76
76
|
},
|
|
77
77
|
"keywords": [
|
|
78
78
|
"sveltekit",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"oauth"
|
|
84
84
|
],
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@sourceregistry/node-jwt": "^1.5.
|
|
86
|
+
"@sourceregistry/node-jwt": "^1.5.10"
|
|
87
87
|
},
|
|
88
88
|
"release": {
|
|
89
89
|
"branches": [
|