@sourceregistry/sveltekit-oidc 1.6.5 → 1.6.7
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.
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
8
|
<script lang="ts" generics="TClaims extends OIDCUserClaims = OIDCUserClaims">
|
|
9
|
-
import {
|
|
9
|
+
import {invalidateAll} from '$app/navigation';
|
|
10
|
+
import {tick} from 'svelte';
|
|
10
11
|
import type {Snippet} from 'svelte';
|
|
11
12
|
|
|
12
13
|
import {setOIDCContext} from './context.js';
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
checkSessionIntervalMs = 5000,
|
|
22
23
|
monitorSession = true,
|
|
23
24
|
revalidateIntervalMs = 30000,
|
|
25
|
+
renewalLeadTimeMs = 5000,
|
|
24
26
|
redirectOnExpired = 'login',
|
|
25
27
|
redirectOnRevoked = 'login',
|
|
26
28
|
redirectIfUnauthenticated = false,
|
|
@@ -33,6 +35,7 @@
|
|
|
33
35
|
checkSessionIntervalMs?: number;
|
|
34
36
|
monitorSession?: boolean;
|
|
35
37
|
revalidateIntervalMs?: number;
|
|
38
|
+
renewalLeadTimeMs?: number;
|
|
36
39
|
redirectOnExpired?: RedirectMode;
|
|
37
40
|
redirectOnRevoked?: RedirectMode;
|
|
38
41
|
redirectIfUnauthenticated?: boolean;
|
|
@@ -101,7 +104,9 @@
|
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
function login(returnTo?: string) {
|
|
104
|
-
|
|
107
|
+
// loginPath is a plain +server.ts redirect endpoint, not a routable
|
|
108
|
+
// page — use a full browser navigation, not SvelteKit's goto().
|
|
109
|
+
window.location.href = buildLoginUrl(returnTo);
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
async function revalidate() {
|
|
@@ -130,17 +135,39 @@
|
|
|
130
135
|
status = isAuthenticated ? 'authenticated' : status === 'authenticated' ? 'unauthenticated' : status;
|
|
131
136
|
});
|
|
132
137
|
|
|
138
|
+
let lastExpiresAt: number | undefined;
|
|
139
|
+
let renewalAttemptedForExpiresAt: number | undefined;
|
|
140
|
+
|
|
133
141
|
$effect(() => {
|
|
134
142
|
if (!session?.isAuthenticated || !session.expiresAt) {
|
|
135
143
|
return;
|
|
136
144
|
}
|
|
137
145
|
|
|
138
|
-
|
|
146
|
+
// If a prior revalidate already came back with the same (still-past)
|
|
147
|
+
// expiresAt, the server couldn't refresh the token (e.g. no refresh
|
|
148
|
+
// token available) — retrying immediately forever would spin-loop.
|
|
149
|
+
// Treat that as a hard expiry instead of rescheduling.
|
|
150
|
+
if (
|
|
151
|
+
lastExpiresAt !== undefined &&
|
|
152
|
+
session.expiresAt <= lastExpiresAt &&
|
|
153
|
+
session.expiresAt * 1000 <= Date.now()
|
|
154
|
+
) {
|
|
155
|
+
status = 'expired';
|
|
156
|
+
void handleRedirect(redirectOnExpired);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
lastExpiresAt = session.expiresAt;
|
|
160
|
+
|
|
161
|
+
const expiresAt = session.expiresAt;
|
|
162
|
+
const leadTimeMs = renewalAttemptedForExpiresAt === expiresAt ? 0 : renewalLeadTimeMs;
|
|
163
|
+
const timeoutMs = Math.max(0, expiresAt * 1000 - Date.now() - leadTimeMs);
|
|
139
164
|
const timer = window.setTimeout(async () => {
|
|
140
165
|
// Silent revalidate first — server's maybeRefreshSession will refresh
|
|
141
166
|
// the token if a valid refresh_token exists. Only redirect if the
|
|
142
167
|
// session comes back unauthenticated after that.
|
|
168
|
+
renewalAttemptedForExpiresAt = expiresAt;
|
|
143
169
|
await revalidate();
|
|
170
|
+
await tick();
|
|
144
171
|
if (!session?.isAuthenticated) {
|
|
145
172
|
status = 'expired';
|
|
146
173
|
void handleRedirect(redirectOnExpired);
|
|
@@ -9,6 +9,7 @@ declare function $$render<TClaims extends OIDCUserClaims = OIDCUserClaims>(): {
|
|
|
9
9
|
checkSessionIntervalMs?: number;
|
|
10
10
|
monitorSession?: boolean;
|
|
11
11
|
revalidateIntervalMs?: number;
|
|
12
|
+
renewalLeadTimeMs?: number;
|
|
12
13
|
redirectOnExpired?: "none" | "login" | "logout" | "reload";
|
|
13
14
|
redirectOnRevoked?: "none" | "login" | "logout" | "reload";
|
|
14
15
|
redirectIfUnauthenticated?: boolean;
|
package/dist/server/index.js
CHANGED
|
@@ -479,7 +479,7 @@ export function createOIDC(options) {
|
|
|
479
479
|
};
|
|
480
480
|
async function hook(event) {
|
|
481
481
|
const session = await getSession(event);
|
|
482
|
-
return {
|
|
482
|
+
return event.locals.oidc = {
|
|
483
483
|
oidc: {
|
|
484
484
|
isAuthenticated: Boolean(session),
|
|
485
485
|
session,
|
|
@@ -506,9 +506,8 @@ export function createOIDC(options) {
|
|
|
506
506
|
try {
|
|
507
507
|
const result = await handleCallback(event);
|
|
508
508
|
const response = await handlerOptions.onsuccess?.(event, result);
|
|
509
|
-
if (response)
|
|
509
|
+
if (response)
|
|
510
510
|
return response;
|
|
511
|
-
}
|
|
512
511
|
throw redirect(302, internalRedirectPath(event, handlerOptions.redirectTo ?? result.returnTo, '/'));
|
|
513
512
|
}
|
|
514
513
|
catch (err) {
|
package/dist/server/jwt.js
CHANGED
|
@@ -5,8 +5,9 @@ import { base64UrlEncode } from './utils.js';
|
|
|
5
5
|
export async function fetchJson(url, init) {
|
|
6
6
|
const response = await fetch(url, init);
|
|
7
7
|
if (!response.ok) {
|
|
8
|
+
const body = await response.text().catch(() => '');
|
|
8
9
|
throw error(response.status, {
|
|
9
|
-
message: `OIDC request failed for '${url}' with status ${response.status}`
|
|
10
|
+
message: `OIDC request failed for '${url}' with status ${response.status}: ${body}`
|
|
10
11
|
});
|
|
11
12
|
}
|
|
12
13
|
return (await response.json());
|
package/dist/server/types.d.ts
CHANGED
|
@@ -244,12 +244,17 @@ export type OIDCInstance<TClaims extends OIDCUserClaims = OIDCUserClaims, TSessi
|
|
|
244
244
|
handle: Handle;
|
|
245
245
|
hook: (event: {
|
|
246
246
|
cookies: RequestEvent['cookies'];
|
|
247
|
+
locals: App.Locals;
|
|
247
248
|
}) => Promise<{
|
|
248
249
|
oidc: OIDCHandleLocals<TClaims, TSession>;
|
|
249
250
|
}>;
|
|
250
251
|
getMetadata: () => Promise<OIDCDiscoveryDocument>;
|
|
251
|
-
getSession: (event:
|
|
252
|
-
|
|
252
|
+
getSession: (event: {
|
|
253
|
+
cookies: RequestEvent['cookies'];
|
|
254
|
+
}) => Promise<TSession | null>;
|
|
255
|
+
getPublicSession: (event: {
|
|
256
|
+
cookies: RequestEvent['cookies'];
|
|
257
|
+
}) => Promise<OIDCPublicSession<TClaims> | null>;
|
|
253
258
|
getSessionManagementConfig: () => Promise<OIDCSessionManagementConfig>;
|
|
254
259
|
login: (event: RequestEvent, loginOptions?: OIDCLoginOptions) => Promise<never>;
|
|
255
260
|
logout: (event: RequestEvent, logoutOptions?: OIDCLogoutOptions) => Promise<never>;
|