@sourceregistry/sveltekit-oidc 1.6.7 → 1.6.9
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,7 @@
|
|
|
6
6
|
</script>
|
|
7
7
|
|
|
8
8
|
<script lang="ts" generics="TClaims extends OIDCUserClaims = OIDCUserClaims">
|
|
9
|
-
import {invalidateAll} from '$app/navigation';
|
|
9
|
+
import {invalidateAll, beforeNavigate} from '$app/navigation';
|
|
10
10
|
import {tick} from 'svelte';
|
|
11
11
|
import type {Snippet} from 'svelte';
|
|
12
12
|
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
let iframe = $state<HTMLIFrameElement | undefined>(undefined);
|
|
46
46
|
let status = $state<'authenticated' | 'unauthenticated' | 'expired' | 'revoked'>('unauthenticated');
|
|
47
|
+
let revalidating = $state(false);
|
|
47
48
|
let handledUnauthenticated = $state(false);
|
|
48
49
|
|
|
49
50
|
const metadata = $derived(config.metadata);
|
|
@@ -77,6 +78,9 @@
|
|
|
77
78
|
get status() {
|
|
78
79
|
return status;
|
|
79
80
|
},
|
|
81
|
+
get revalidating() {
|
|
82
|
+
return revalidating;
|
|
83
|
+
},
|
|
80
84
|
login: (returnTo?: string) => login(returnTo),
|
|
81
85
|
logout,
|
|
82
86
|
revalidate
|
|
@@ -110,7 +114,32 @@
|
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
async function revalidate() {
|
|
113
|
-
|
|
117
|
+
if (revalidating) return;
|
|
118
|
+
revalidating = true;
|
|
119
|
+
|
|
120
|
+
// If the server redirects to the login path during a background
|
|
121
|
+
// revalidation (e.g. session lost, HMR store reset), intercept the
|
|
122
|
+
// SvelteKit router navigation so we can handle it through
|
|
123
|
+
// handleRedirect instead of a jarring mid-page router transition.
|
|
124
|
+
let sessionExpiredDuringRevalidation = false;
|
|
125
|
+
const stopIntercept = beforeNavigate(({ to, cancel }) => {
|
|
126
|
+
if (to?.url.pathname.startsWith(resolvedLoginPath)) {
|
|
127
|
+
cancel();
|
|
128
|
+
sessionExpiredDuringRevalidation = true;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
await invalidateAll();
|
|
134
|
+
} finally {
|
|
135
|
+
stopIntercept();
|
|
136
|
+
revalidating = false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (sessionExpiredDuringRevalidation) {
|
|
140
|
+
status = 'expired';
|
|
141
|
+
void handleRedirect(redirectOnExpired);
|
|
142
|
+
}
|
|
114
143
|
}
|
|
115
144
|
|
|
116
145
|
async function handleRedirect(mode: RedirectMode) {
|
|
@@ -132,6 +161,10 @@
|
|
|
132
161
|
|
|
133
162
|
$effect(() => {
|
|
134
163
|
const isAuthenticated = Boolean(session?.isAuthenticated);
|
|
164
|
+
// Suppress authenticated→unauthenticated transition while a revalidation is
|
|
165
|
+
// in-flight — the effect re-runs once revalidating flips false with the
|
|
166
|
+
// final session state, preventing a mid-refresh flicker.
|
|
167
|
+
if (revalidating && !isAuthenticated) return;
|
|
135
168
|
status = isAuthenticated ? 'authenticated' : status === 'authenticated' ? 'unauthenticated' : status;
|
|
136
169
|
});
|
|
137
170
|
|
package/dist/client/context.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type OIDCClientContextValue<TClaims extends OIDCUserClaims = OIDCUserClai
|
|
|
10
10
|
groups: OIDCPublicSession<TClaims>['groups'];
|
|
11
11
|
metadata?: Pick<OIDCDiscoveryDocument, 'issuer' | 'check_session_iframe' | 'end_session_endpoint' | 'backchannel_logout_supported' | 'backchannel_logout_session_supported'>;
|
|
12
12
|
status: 'authenticated' | 'unauthenticated' | 'expired' | 'revoked';
|
|
13
|
+
revalidating: boolean;
|
|
13
14
|
login: (returnTo?: string) => void;
|
|
14
15
|
logout: (clearSessionOnly?: boolean) => Promise<void>;
|
|
15
16
|
revalidate: () => Promise<void>;
|
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
|
-
|
|
482
|
+
const locals = {
|
|
483
483
|
oidc: {
|
|
484
484
|
isAuthenticated: Boolean(session),
|
|
485
485
|
session,
|
|
@@ -494,6 +494,8 @@ export function createOIDC(options) {
|
|
|
494
494
|
clearSession: async () => clearPersistedSession(event.cookies)
|
|
495
495
|
}
|
|
496
496
|
};
|
|
497
|
+
event.locals.oidc = locals.oidc;
|
|
498
|
+
return locals;
|
|
497
499
|
}
|
|
498
500
|
function loginHandler(defaults = {}) {
|
|
499
501
|
return async (event) => {
|
package/dist/server/store.js
CHANGED
|
@@ -17,7 +17,10 @@ export function createInMemoryBackChannelLogoutStore() {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
export function createInMemorySessionStore() {
|
|
20
|
-
|
|
20
|
+
// Persist the Map on globalThis so Vite HMR module re-evaluations don't
|
|
21
|
+
// create a fresh store and orphan all live session cookies.
|
|
22
|
+
const g = globalThis;
|
|
23
|
+
const sessions = (g['__oidc_sessions__'] ??= new Map());
|
|
21
24
|
return {
|
|
22
25
|
async get(sessionId) {
|
|
23
26
|
return sessions.get(sessionId) ?? null;
|