@axa-fr/oidc-client 7.26.7 → 7.27.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 +2 -1
- package/dist/index.js +661 -591
- package/dist/index.umd.cjs +2 -2
- package/dist/initSession.d.ts +1 -1
- package/dist/initSession.d.ts.map +1 -1
- package/dist/initSession.spec.d.ts +2 -0
- package/dist/initSession.spec.d.ts.map +1 -0
- package/dist/initWorker.d.ts.map +1 -1
- package/dist/keepSession.d.ts.map +1 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/logout.d.ts.map +1 -1
- package/dist/oidc.d.ts.map +1 -1
- package/dist/renewTokens.d.ts.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/initSession.spec.ts +215 -0
- package/src/initSession.ts +21 -9
- package/src/initWorker.ts +71 -24
- package/src/keepSession.ts +6 -2
- package/src/login.ts +16 -3
- package/src/logout.ts +5 -1
- package/src/oidc.ts +10 -2
- package/src/renewTokens.ts +20 -4
- package/src/types.ts +1 -0
- package/src/version.ts +1 -1
package/src/initSession.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
export const initSession = (
|
|
1
|
+
export const initSession = (
|
|
2
|
+
configurationName,
|
|
3
|
+
storage = sessionStorage,
|
|
4
|
+
loginStateStorage?: Storage,
|
|
5
|
+
) => {
|
|
6
|
+
const loginStorage = loginStateStorage ?? storage;
|
|
7
|
+
|
|
2
8
|
const clearAsync = status => {
|
|
3
9
|
storage[`oidc.${configurationName}`] = JSON.stringify({ tokens: null, status });
|
|
4
10
|
delete storage[`oidc.${configurationName}.userInfo`];
|
|
11
|
+
if (loginStateStorage && loginStateStorage !== storage) {
|
|
12
|
+
delete loginStorage[`oidc.login.${configurationName}`];
|
|
13
|
+
delete loginStorage[`oidc.state.${configurationName}`];
|
|
14
|
+
delete loginStorage[`oidc.code_verifier.${configurationName}`];
|
|
15
|
+
delete loginStorage[`oidc.nonce.${configurationName}`];
|
|
16
|
+
}
|
|
5
17
|
return Promise.resolve();
|
|
6
18
|
};
|
|
7
19
|
|
|
@@ -27,7 +39,7 @@ export const initSession = (configurationName, storage = sessionStorage) => {
|
|
|
27
39
|
};
|
|
28
40
|
|
|
29
41
|
const setNonceAsync = nonce => {
|
|
30
|
-
|
|
42
|
+
loginStorage[`oidc.nonce.${configurationName}`] = nonce.nonce;
|
|
31
43
|
};
|
|
32
44
|
|
|
33
45
|
const setDemonstratingProofOfPossessionJwkAsync = (jwk: JsonWebKey) => {
|
|
@@ -40,7 +52,7 @@ export const initSession = (configurationName, storage = sessionStorage) => {
|
|
|
40
52
|
|
|
41
53
|
const getNonceAsync = async () => {
|
|
42
54
|
// @ts-ignore
|
|
43
|
-
return { nonce:
|
|
55
|
+
return { nonce: loginStorage[`oidc.nonce.${configurationName}`] };
|
|
44
56
|
};
|
|
45
57
|
|
|
46
58
|
const setDemonstratingProofOfPossessionNonce = async (dpopNonce: string) => {
|
|
@@ -61,10 +73,10 @@ export const initSession = (configurationName, storage = sessionStorage) => {
|
|
|
61
73
|
const getLoginParamsCache = {};
|
|
62
74
|
const setLoginParams = data => {
|
|
63
75
|
getLoginParamsCache[configurationName] = data;
|
|
64
|
-
|
|
76
|
+
loginStorage[`oidc.login.${configurationName}`] = JSON.stringify(data);
|
|
65
77
|
};
|
|
66
78
|
const getLoginParams = () => {
|
|
67
|
-
const dataString =
|
|
79
|
+
const dataString = loginStorage[`oidc.login.${configurationName}`];
|
|
68
80
|
|
|
69
81
|
if (!dataString) {
|
|
70
82
|
console.warn(
|
|
@@ -80,19 +92,19 @@ export const initSession = (configurationName, storage = sessionStorage) => {
|
|
|
80
92
|
};
|
|
81
93
|
|
|
82
94
|
const getStateAsync = async () => {
|
|
83
|
-
return
|
|
95
|
+
return loginStorage[`oidc.state.${configurationName}`];
|
|
84
96
|
};
|
|
85
97
|
|
|
86
98
|
const setStateAsync = async (state: string) => {
|
|
87
|
-
|
|
99
|
+
loginStorage[`oidc.state.${configurationName}`] = state;
|
|
88
100
|
};
|
|
89
101
|
|
|
90
102
|
const getCodeVerifierAsync = async () => {
|
|
91
|
-
return
|
|
103
|
+
return loginStorage[`oidc.code_verifier.${configurationName}`];
|
|
92
104
|
};
|
|
93
105
|
|
|
94
106
|
const setCodeVerifierAsync = async codeVerifier => {
|
|
95
|
-
|
|
107
|
+
loginStorage[`oidc.code_verifier.${configurationName}`] = codeVerifier;
|
|
96
108
|
};
|
|
97
109
|
|
|
98
110
|
return {
|
package/src/initWorker.ts
CHANGED
|
@@ -181,38 +181,56 @@ export const initWorkerAsync = async (
|
|
|
181
181
|
});
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
await registration.update();
|
|
187
|
-
} catch (ex) {
|
|
188
|
-
console.error(ex);
|
|
189
|
-
}
|
|
184
|
+
const versionMismatchKey = `oidc.sw.version_mismatch_reload.${configurationName}`;
|
|
190
185
|
|
|
191
|
-
|
|
192
|
-
registration.addEventListener('updatefound', () => {
|
|
193
|
-
const newSW = registration.installing;
|
|
186
|
+
const sendSkipWaiting = async () => {
|
|
194
187
|
stopKeepAlive();
|
|
188
|
+
console.log('New SW waiting – SKIP_WAITING');
|
|
189
|
+
try {
|
|
190
|
+
await sendMessageAsync(registration, { timeoutMs: 8000 })({
|
|
191
|
+
type: 'SKIP_WAITING',
|
|
192
|
+
configurationName,
|
|
193
|
+
data: null,
|
|
194
|
+
});
|
|
195
|
+
} catch (e) {
|
|
196
|
+
console.warn('SKIP_WAITING failed', e);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
195
199
|
|
|
196
|
-
|
|
200
|
+
const trackInstallingWorker = (newSW: ServiceWorker) => {
|
|
201
|
+
stopKeepAlive();
|
|
202
|
+
newSW.addEventListener('statechange', async () => {
|
|
197
203
|
if (newSW.state === 'installed' && navigator.serviceWorker.controller) {
|
|
198
|
-
|
|
199
|
-
console.log('New SW waiting – SKIP_WAITING');
|
|
200
|
-
|
|
201
|
-
try {
|
|
202
|
-
// Use MessageChannel to avoid “fire and forget” hangs
|
|
203
|
-
await sendMessageAsync(registration, { timeoutMs: 8000 })({
|
|
204
|
-
type: 'SKIP_WAITING',
|
|
205
|
-
configurationName,
|
|
206
|
-
data: null,
|
|
207
|
-
});
|
|
208
|
-
} catch (e) {
|
|
209
|
-
console.warn('SKIP_WAITING failed', e);
|
|
210
|
-
}
|
|
204
|
+
await sendSkipWaiting();
|
|
211
205
|
}
|
|
212
206
|
});
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// 1) Détection updatefound – registered BEFORE update() to avoid missing the event
|
|
210
|
+
registration.addEventListener('updatefound', () => {
|
|
211
|
+
const newSW = registration.installing;
|
|
212
|
+
if (newSW) {
|
|
213
|
+
trackInstallingWorker(newSW);
|
|
214
|
+
}
|
|
213
215
|
});
|
|
214
216
|
|
|
215
|
-
//
|
|
217
|
+
// Handle a SW that is already installing or waiting (e.g. when the listener above was
|
|
218
|
+
// registered after the updatefound event already fired in a previous call)
|
|
219
|
+
if (registration.installing) {
|
|
220
|
+
trackInstallingWorker(registration.installing);
|
|
221
|
+
} else if (registration.waiting && navigator.serviceWorker.controller) {
|
|
222
|
+
// A new SW is already waiting – activate it straight away
|
|
223
|
+
sendSkipWaiting();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// (Optional but useful on Safari) ask for update early
|
|
227
|
+
try {
|
|
228
|
+
await registration.update();
|
|
229
|
+
} catch (ex) {
|
|
230
|
+
console.error(ex);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// 2) Quand le SW actif change, on reload (once per session)
|
|
216
234
|
const reloadKey = `oidc.sw.controllerchange.reloaded.${configurationName}`;
|
|
217
235
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
218
236
|
try {
|
|
@@ -275,6 +293,35 @@ export const initWorkerAsync = async (
|
|
|
275
293
|
console.warn(
|
|
276
294
|
`Service worker ${serviceWorkerVersion} version mismatch with js client version ${codeVersion}, unregistering and reloading`,
|
|
277
295
|
);
|
|
296
|
+
|
|
297
|
+
const reloadCount = parseInt(sessionStorage.getItem(versionMismatchKey) ?? '0', 10);
|
|
298
|
+
if (reloadCount < 3) {
|
|
299
|
+
sessionStorage.setItem(versionMismatchKey, String(reloadCount + 1));
|
|
300
|
+
// If a new SW is already waiting, skip it into activation so controllerchange triggers reload
|
|
301
|
+
if (registration.waiting) {
|
|
302
|
+
await sendSkipWaiting();
|
|
303
|
+
} else {
|
|
304
|
+
// No waiting SW – force a fresh update and reload
|
|
305
|
+
stopKeepAlive();
|
|
306
|
+
try {
|
|
307
|
+
await registration.update();
|
|
308
|
+
} catch (ex) {
|
|
309
|
+
console.error(ex);
|
|
310
|
+
}
|
|
311
|
+
const isSuccess = await registration.unregister();
|
|
312
|
+
console.log(`Service worker unregistering ${isSuccess}`);
|
|
313
|
+
await sleepAsync({ milliseconds: 2000 });
|
|
314
|
+
window.location.reload();
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
console.error(
|
|
318
|
+
`Service worker version mismatch persists after ${reloadCount} attempt(s). Continuing with mismatched version.`,
|
|
319
|
+
);
|
|
320
|
+
sessionStorage.removeItem(versionMismatchKey);
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
// Version matches – clear any leftover mismatch counter
|
|
324
|
+
sessionStorage.removeItem(versionMismatchKey);
|
|
278
325
|
}
|
|
279
326
|
|
|
280
327
|
// @ts-ignore
|
package/src/keepSession.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { eventNames } from './events';
|
|
2
2
|
import { initSession } from './initSession';
|
|
3
3
|
import { initWorkerAsync } from './initWorker';
|
|
4
4
|
import Oidc from './oidc';
|
|
@@ -62,7 +62,11 @@ export const tryKeepSessionAsync = async (oidc: Oidc) => {
|
|
|
62
62
|
message: 'service worker is not supported by this browser',
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
|
-
const session = initSession(
|
|
65
|
+
const session = initSession(
|
|
66
|
+
oidc.configurationName,
|
|
67
|
+
configuration.storage ?? sessionStorage,
|
|
68
|
+
configuration.login_state_storage ?? configuration.storage ?? sessionStorage,
|
|
69
|
+
);
|
|
66
70
|
const { tokens } = await session.initAsync();
|
|
67
71
|
if (tokens) {
|
|
68
72
|
// @ts-ignore
|
package/src/login.ts
CHANGED
|
@@ -69,7 +69,11 @@ export const defaultLoginAsync =
|
|
|
69
69
|
serviceWorker.startKeepAliveServiceWorker();
|
|
70
70
|
storage = serviceWorker;
|
|
71
71
|
} else {
|
|
72
|
-
const session = initSession(
|
|
72
|
+
const session = initSession(
|
|
73
|
+
configurationName,
|
|
74
|
+
configuration.storage ?? sessionStorage,
|
|
75
|
+
configuration.login_state_storage ?? configuration.storage ?? sessionStorage,
|
|
76
|
+
);
|
|
73
77
|
session.setLoginParams({ callbackPath: url, extras: originExtras, scope: scope });
|
|
74
78
|
await session.setNonceAsync(nonce);
|
|
75
79
|
storage = session;
|
|
@@ -131,6 +135,7 @@ export const loginCallbackAsync =
|
|
|
131
135
|
const session = initSession(
|
|
132
136
|
oidc.configurationName,
|
|
133
137
|
configuration.storage ?? sessionStorage,
|
|
138
|
+
configuration.login_state_storage ?? configuration.storage ?? sessionStorage,
|
|
134
139
|
);
|
|
135
140
|
await session.setSessionStateAsync(sessionState);
|
|
136
141
|
nonceData = await session.getNonceAsync();
|
|
@@ -186,7 +191,11 @@ export const loginCallbackAsync =
|
|
|
186
191
|
const jwk = await generateJwkAsync(window)(
|
|
187
192
|
configuration.demonstrating_proof_of_possession_configuration.generateKeyAlgorithm,
|
|
188
193
|
);
|
|
189
|
-
const session = initSession(
|
|
194
|
+
const session = initSession(
|
|
195
|
+
oidc.configurationName,
|
|
196
|
+
configuration.storage,
|
|
197
|
+
configuration.login_state_storage ?? configuration.storage,
|
|
198
|
+
);
|
|
190
199
|
await session.setDemonstratingProofOfPossessionJwkAsync(jwk);
|
|
191
200
|
headersExtras['DPoP'] = await generateJwtDemonstratingProofOfPossessionAsync(window)(
|
|
192
201
|
configuration.demonstrating_proof_of_possession_configuration,
|
|
@@ -251,7 +260,11 @@ export const loginCallbackAsync =
|
|
|
251
260
|
);
|
|
252
261
|
}
|
|
253
262
|
} else {
|
|
254
|
-
const session = initSession(
|
|
263
|
+
const session = initSession(
|
|
264
|
+
oidc.configurationName,
|
|
265
|
+
configuration.storage,
|
|
266
|
+
configuration.login_state_storage ?? configuration.storage,
|
|
267
|
+
);
|
|
255
268
|
loginParams = session.getLoginParams();
|
|
256
269
|
if (demonstratingProofOfPossessionNonce) {
|
|
257
270
|
await session.setDemonstratingProofOfPossessionNonce(demonstratingProofOfPossessionNonce);
|
package/src/logout.ts
CHANGED
|
@@ -46,7 +46,11 @@ export const destroyAsync = oidc => async status => {
|
|
|
46
46
|
}
|
|
47
47
|
const serviceWorker = await initWorkerAsync(oidc.configuration, oidc.configurationName);
|
|
48
48
|
if (!serviceWorker) {
|
|
49
|
-
const session = initSession(
|
|
49
|
+
const session = initSession(
|
|
50
|
+
oidc.configurationName,
|
|
51
|
+
oidc.configuration.storage,
|
|
52
|
+
oidc.configuration.login_state_storage ?? oidc.configuration.storage,
|
|
53
|
+
);
|
|
50
54
|
await session.clearAsync(status);
|
|
51
55
|
} else {
|
|
52
56
|
await serviceWorker.clearAsync(status);
|
package/src/oidc.ts
CHANGED
|
@@ -348,7 +348,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
348
348
|
this.tokens = parsedTokens;
|
|
349
349
|
const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
|
|
350
350
|
if (!serviceWorker) {
|
|
351
|
-
const session = initSession(
|
|
351
|
+
const session = initSession(
|
|
352
|
+
this.configurationName,
|
|
353
|
+
this.configuration.storage,
|
|
354
|
+
this.configuration.login_state_storage ?? this.configuration.storage,
|
|
355
|
+
);
|
|
352
356
|
session.setTokens(parsedTokens);
|
|
353
357
|
}
|
|
354
358
|
this.publishEvent(Oidc.eventNames.token_acquired, parsedTokens);
|
|
@@ -388,7 +392,11 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
388
392
|
return `DPOP_SECURED_BY_OIDC_SERVICE_WORKER_${this.configurationName}#tabId=${getTabId(this.configurationName)}`;
|
|
389
393
|
}
|
|
390
394
|
|
|
391
|
-
const session = initSession(
|
|
395
|
+
const session = initSession(
|
|
396
|
+
this.configurationName,
|
|
397
|
+
configuration.storage,
|
|
398
|
+
configuration.login_state_storage ?? configuration.storage,
|
|
399
|
+
);
|
|
392
400
|
const jwk = await session.getDemonstratingProofOfPossessionJwkAsync();
|
|
393
401
|
const demonstratingProofOfPossessionNonce = session.getDemonstratingProofOfPossessionNonce();
|
|
394
402
|
|
package/src/renewTokens.ts
CHANGED
|
@@ -28,7 +28,11 @@ async function syncTokens(
|
|
|
28
28
|
|
|
29
29
|
const serviceWorker = await initWorkerAsync(oidc.configuration, oidc.configurationName);
|
|
30
30
|
if (!serviceWorker) {
|
|
31
|
-
const session = initSession(
|
|
31
|
+
const session = initSession(
|
|
32
|
+
oidc.configurationName,
|
|
33
|
+
oidc.configuration.storage,
|
|
34
|
+
oidc.configuration.login_state_storage ?? oidc.configuration.storage,
|
|
35
|
+
);
|
|
32
36
|
session.setTokens(oidc.tokens);
|
|
33
37
|
}
|
|
34
38
|
|
|
@@ -169,7 +173,11 @@ export const syncTokensInfoAsync =
|
|
|
169
173
|
}
|
|
170
174
|
nonce = await serviceWorker.getNonceAsync();
|
|
171
175
|
} else {
|
|
172
|
-
const session = initSession(
|
|
176
|
+
const session = initSession(
|
|
177
|
+
configurationName,
|
|
178
|
+
configuration.storage ?? sessionStorage,
|
|
179
|
+
configuration.login_state_storage ?? configuration.storage ?? sessionStorage,
|
|
180
|
+
);
|
|
173
181
|
const initAsyncResponse = await session.initAsync();
|
|
174
182
|
let { tokens } = initAsyncResponse;
|
|
175
183
|
const { status } = initAsyncResponse;
|
|
@@ -263,7 +271,11 @@ const synchroniseTokensAsync =
|
|
|
263
271
|
if (serviceWorker) {
|
|
264
272
|
loginParams = serviceWorker.getLoginParams();
|
|
265
273
|
} else {
|
|
266
|
-
const session = initSession(
|
|
274
|
+
const session = initSession(
|
|
275
|
+
oidc.configurationName,
|
|
276
|
+
configuration.storage,
|
|
277
|
+
configuration.login_state_storage ?? configuration.storage,
|
|
278
|
+
);
|
|
267
279
|
loginParams = session.getLoginParams();
|
|
268
280
|
}
|
|
269
281
|
const silentLoginInput = {};
|
|
@@ -454,7 +466,11 @@ const synchroniseTokensAsync =
|
|
|
454
466
|
tokenResponse.demonstratingProofOfPossessionNonce,
|
|
455
467
|
);
|
|
456
468
|
} else {
|
|
457
|
-
const session = initSession(
|
|
469
|
+
const session = initSession(
|
|
470
|
+
oidc.configurationName,
|
|
471
|
+
configuration.storage,
|
|
472
|
+
configuration.login_state_storage ?? configuration.storage,
|
|
473
|
+
);
|
|
458
474
|
await session.setDemonstratingProofOfPossessionNonce(
|
|
459
475
|
tokenResponse.demonstratingProofOfPossessionNonce,
|
|
460
476
|
);
|
package/src/types.ts
CHANGED
|
@@ -39,6 +39,7 @@ export type OidcConfiguration = {
|
|
|
39
39
|
extras?: StringMap;
|
|
40
40
|
token_request_extras?: StringMap;
|
|
41
41
|
storage?: Storage;
|
|
42
|
+
login_state_storage?: Storage;
|
|
42
43
|
monitor_session?: boolean;
|
|
43
44
|
token_renew_mode?: string;
|
|
44
45
|
logout_tokens_to_invalidate?: Array<LogoutToken>;
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '7.
|
|
1
|
+
export default '7.27.0';
|