@svadmin/sso 0.11.0 → 0.11.1
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/dist/auth-provider.js +40 -10
- package/dist/session-manager.d.ts +1 -0
- package/dist/session-manager.js +16 -1
- package/package.json +2 -2
package/dist/auth-provider.js
CHANGED
|
@@ -8,6 +8,35 @@ import { createAuthenticatedFetch as buildAuthenticatedFetch } from './authentic
|
|
|
8
8
|
import { createSSOAuthNetworkError, createSSOAuthResponseError, isTerminalSessionError, SSOAuthError, } from './errors.js';
|
|
9
9
|
import { createSessionManager, } from './session-manager.js';
|
|
10
10
|
const DEFAULT_STORAGE_KEY = 'svadmin_sso';
|
|
11
|
+
const REQUIRED_OIDC_ENDPOINTS = [
|
|
12
|
+
'authorization_endpoint',
|
|
13
|
+
'token_endpoint',
|
|
14
|
+
'userinfo_endpoint',
|
|
15
|
+
];
|
|
16
|
+
function readOIDCConfig(body) {
|
|
17
|
+
const discovery = typeof body === 'object' && body !== null && !Array.isArray(body)
|
|
18
|
+
? body
|
|
19
|
+
: {};
|
|
20
|
+
const missingEndpoints = REQUIRED_OIDC_ENDPOINTS.filter((endpoint) => {
|
|
21
|
+
const value = discovery[endpoint];
|
|
22
|
+
return typeof value !== 'string' || value.length === 0;
|
|
23
|
+
});
|
|
24
|
+
if (missingEndpoints.length > 0) {
|
|
25
|
+
throw new SSOAuthError(`OIDC discovery returned incomplete endpoints: missing ${missingEndpoints.join(', ')}`, 502, {
|
|
26
|
+
code: 'invalid_discovery_document',
|
|
27
|
+
body,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
authorization_endpoint: discovery.authorization_endpoint,
|
|
32
|
+
token_endpoint: discovery.token_endpoint,
|
|
33
|
+
userinfo_endpoint: discovery.userinfo_endpoint,
|
|
34
|
+
...(typeof discovery.end_session_endpoint === 'string'
|
|
35
|
+
&& discovery.end_session_endpoint.length > 0
|
|
36
|
+
? { end_session_endpoint: discovery.end_session_endpoint }
|
|
37
|
+
: {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
11
40
|
function decodeJwtPayload(token) {
|
|
12
41
|
if (!token)
|
|
13
42
|
return null;
|
|
@@ -205,15 +234,7 @@ export function createSSOAuthProvider(config) {
|
|
|
205
234
|
cause: error,
|
|
206
235
|
});
|
|
207
236
|
}
|
|
208
|
-
|
|
209
|
-
|| typeof discovered.token_endpoint !== 'string'
|
|
210
|
-
|| typeof discovered.userinfo_endpoint !== 'string') {
|
|
211
|
-
throw new SSOAuthError('OIDC discovery returned incomplete endpoints', 502, {
|
|
212
|
-
code: 'invalid_discovery_document',
|
|
213
|
-
body: discovered,
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
oidcConfig = discovered;
|
|
237
|
+
oidcConfig = readOIDCConfig(discovered);
|
|
217
238
|
return oidcConfig;
|
|
218
239
|
}
|
|
219
240
|
async function requestToken(endpoint, body, fallbackMessage) {
|
|
@@ -407,7 +428,16 @@ export function createSSOAuthProvider(config) {
|
|
|
407
428
|
};
|
|
408
429
|
},
|
|
409
430
|
async check() {
|
|
410
|
-
|
|
431
|
+
let existingSession = sessions.getSession();
|
|
432
|
+
if (!existingSession) {
|
|
433
|
+
try {
|
|
434
|
+
await sessions.clearInvalidSession();
|
|
435
|
+
existingSession = sessions.getSession();
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
return { authenticated: false, error: getErrorResult(error) };
|
|
439
|
+
}
|
|
440
|
+
}
|
|
411
441
|
if (typeof window === 'undefined') {
|
|
412
442
|
const now = Math.floor(Date.now() / 1000);
|
|
413
443
|
return existingSession && (existingSession.expires_at === undefined || existingSession.expires_at > now)
|
|
@@ -31,6 +31,7 @@ export interface TokenStorageLike {
|
|
|
31
31
|
}
|
|
32
32
|
export interface SessionManager {
|
|
33
33
|
getSession: () => SSOSession | null;
|
|
34
|
+
clearInvalidSession: () => Promise<void>;
|
|
34
35
|
getAuthGeneration: () => number;
|
|
35
36
|
saveSession: (session: SSOSession, event?: AuthStateChangeEvent) => void;
|
|
36
37
|
clearSession: () => void;
|
package/dist/session-manager.js
CHANGED
|
@@ -306,6 +306,17 @@ export function createSessionManager(options) {
|
|
|
306
306
|
});
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
|
+
function clearInvalidSession() {
|
|
310
|
+
const initialSnapshot = getSessionSnapshot();
|
|
311
|
+
if (initialSnapshot.raw === null || initialSnapshot.session)
|
|
312
|
+
return Promise.resolve();
|
|
313
|
+
return runAuthMutation(async () => {
|
|
314
|
+
const currentRaw = locallySignedOut ? null : options.storage.getItem(keys.tokens);
|
|
315
|
+
if (currentRaw === null || parseSession(currentRaw))
|
|
316
|
+
return;
|
|
317
|
+
clearTokenSession();
|
|
318
|
+
});
|
|
319
|
+
}
|
|
309
320
|
function resolveRefreshRace(expectedRaw) {
|
|
310
321
|
const currentRaw = locallySignedOut ? null : options.storage.getItem(keys.tokens);
|
|
311
322
|
if (currentRaw === expectedRaw)
|
|
@@ -432,8 +443,11 @@ export function createSessionManager(options) {
|
|
|
432
443
|
}
|
|
433
444
|
async function getAccessToken(accessOptions = {}) {
|
|
434
445
|
const snapshot = getSessionSnapshot();
|
|
435
|
-
if (!snapshot.raw || !snapshot.session)
|
|
446
|
+
if (!snapshot.raw || !snapshot.session) {
|
|
447
|
+
if (snapshot.raw)
|
|
448
|
+
await clearInvalidSession();
|
|
436
449
|
return null;
|
|
450
|
+
}
|
|
437
451
|
const { raw: initialRaw, session } = snapshot;
|
|
438
452
|
const minValiditySeconds = Math.max(0, accessOptions.minValiditySeconds ?? 0);
|
|
439
453
|
const now = Math.floor(Date.now() / 1000);
|
|
@@ -532,6 +546,7 @@ export function createSessionManager(options) {
|
|
|
532
546
|
scheduleRefresh(parseSession(lastObservedRaw));
|
|
533
547
|
return {
|
|
534
548
|
getSession,
|
|
549
|
+
clearInvalidSession,
|
|
535
550
|
getAuthGeneration: () => authGeneration,
|
|
536
551
|
saveSession,
|
|
537
552
|
clearSession,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svadmin/sso",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OIDC/OAuth2 SSO AuthProvider plugin for svadmin — supports Okta, Azure AD, Cognito, Keycloak, Google",
|
|
6
6
|
"license": "MIT",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dist"
|
|
33
33
|
],
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@svadmin/core": "^0.32.
|
|
35
|
+
"@svadmin/core": "^0.32.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"typescript": "^5.7.0"
|