@axa-fr/oidc-client 7.22.18 → 7.22.19
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 +31 -39
- package/bin/copy-service-worker-files.mjs +24 -17
- package/dist/OidcTrustedDomains.js +14 -12
- package/dist/cache.d.ts.map +1 -1
- package/dist/checkSession.d.ts +1 -1
- package/dist/checkSession.d.ts.map +1 -1
- package/dist/checkSessionIFrame.d.ts.map +1 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/fetch.d.ts +2 -1
- package/dist/fetch.d.ts.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +935 -601
- package/dist/index.umd.cjs +2 -2
- package/dist/initSession.d.ts +1 -1
- package/dist/initSession.d.ts.map +1 -1
- package/dist/initWorker.d.ts +2 -2
- package/dist/initWorker.d.ts.map +1 -1
- package/dist/initWorkerOption.d.ts.map +1 -1
- package/dist/jwt.d.ts +2 -2
- package/dist/jwt.d.ts.map +1 -1
- package/dist/keepSession.d.ts.map +1 -1
- package/dist/location.d.ts.map +1 -1
- package/dist/login.d.ts +1 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/logout.d.ts +1 -1
- package/dist/logout.d.ts.map +1 -1
- package/dist/oidc.d.ts +1 -1
- package/dist/oidc.d.ts.map +1 -1
- package/dist/oidcClient.d.ts +2 -2
- package/dist/oidcClient.d.ts.map +1 -1
- package/dist/parseTokens.d.ts.map +1 -1
- package/dist/renewTokens.d.ts.map +1 -1
- package/dist/requests.d.ts +1 -1
- package/dist/requests.d.ts.map +1 -1
- package/dist/silentLogin.d.ts.map +1 -1
- package/dist/timer.d.ts.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/user.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/cache.ts +21 -18
- package/src/checkSession.ts +89 -54
- package/src/checkSessionIFrame.ts +70 -69
- package/src/crypto.ts +27 -25
- package/src/events.ts +28 -28
- package/src/fetch.ts +40 -21
- package/src/index.ts +6 -17
- package/src/iniWorker.spec.ts +26 -16
- package/src/initSession.ts +115 -113
- package/src/initWorker.ts +299 -212
- package/src/initWorkerOption.ts +121 -114
- package/src/jwt.ts +150 -136
- package/src/keepSession.ts +100 -81
- package/src/location.ts +24 -26
- package/src/login.ts +246 -189
- package/src/logout.spec.ts +131 -76
- package/src/logout.ts +130 -115
- package/src/oidc.ts +426 -337
- package/src/oidcClient.ts +129 -105
- package/src/parseTokens.spec.ts +198 -179
- package/src/parseTokens.ts +221 -186
- package/src/renewTokens.ts +397 -284
- package/src/requests.spec.ts +5 -7
- package/src/requests.ts +142 -114
- package/src/route-utils.spec.ts +17 -19
- package/src/route-utils.ts +29 -26
- package/src/silentLogin.ts +145 -127
- package/src/timer.ts +10 -11
- package/src/types.ts +56 -46
- package/src/user.ts +17 -12
- package/src/version.ts +1 -1
package/src/cache.ts
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
const fetchFromIssuerCache = {};
|
|
2
2
|
|
|
3
3
|
export const getFromCache = (localStorageKey, storage = window.sessionStorage, timeCacheSecond) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
const oneHourMinisecond = 1000 * timeCacheSecond;
|
|
13
|
-
// @ts-ignore
|
|
14
|
-
if (fetchFromIssuerCache[localStorageKey] && (fetchFromIssuerCache[localStorageKey].timestamp + oneHourMinisecond) > Date.now()) {
|
|
15
|
-
return fetchFromIssuerCache[localStorageKey].result;
|
|
4
|
+
if (!fetchFromIssuerCache[localStorageKey]) {
|
|
5
|
+
if (storage) {
|
|
6
|
+
const cacheJson = storage.getItem(localStorageKey);
|
|
7
|
+
if (cacheJson) {
|
|
8
|
+
fetchFromIssuerCache[localStorageKey] = JSON.parse(cacheJson);
|
|
9
|
+
}
|
|
16
10
|
}
|
|
17
|
-
|
|
11
|
+
}
|
|
12
|
+
const oneHourMinisecond = 1000 * timeCacheSecond;
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
if (
|
|
15
|
+
fetchFromIssuerCache[localStorageKey] &&
|
|
16
|
+
fetchFromIssuerCache[localStorageKey].timestamp + oneHourMinisecond > Date.now()
|
|
17
|
+
) {
|
|
18
|
+
return fetchFromIssuerCache[localStorageKey].result;
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export const setCache = (localStorageKey, result, storage = window.sessionStorage) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const timestamp = Date.now();
|
|
25
|
+
fetchFromIssuerCache[localStorageKey] = { result, timestamp };
|
|
26
|
+
if (storage) {
|
|
27
|
+
storage.setItem(localStorageKey, JSON.stringify({ result, timestamp }));
|
|
28
|
+
}
|
|
26
29
|
};
|
package/src/checkSession.ts
CHANGED
|
@@ -1,64 +1,99 @@
|
|
|
1
1
|
import { CheckSessionIFrame } from './checkSessionIFrame.js';
|
|
2
|
+
import Oidc from './oidc';
|
|
2
3
|
import { _silentLoginAsync, SilentLoginResponse } from './silentLogin.js';
|
|
3
4
|
import { OidcConfiguration } from './types.js';
|
|
4
|
-
import Oidc from "./oidc";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
export const startCheckSessionAsync =
|
|
7
|
+
(oidc: Oidc, oidcDatabase: any, configuration: OidcConfiguration) =>
|
|
8
|
+
(checkSessionIFrameUri, clientId, sessionState, isSilentSignin = false) => {
|
|
9
|
+
const silentLoginAsync = (
|
|
10
|
+
extras,
|
|
11
|
+
state = undefined,
|
|
12
|
+
scope = undefined,
|
|
13
|
+
): Promise<SilentLoginResponse> => {
|
|
14
|
+
return _silentLoginAsync(oidc.configurationName, configuration, oidc.publishEvent.bind(oidc))(
|
|
15
|
+
extras,
|
|
16
|
+
state,
|
|
17
|
+
scope,
|
|
18
|
+
);
|
|
10
19
|
};
|
|
11
20
|
|
|
12
21
|
return new Promise<CheckSessionIFrame>((resolve, reject): void => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
if (
|
|
23
|
+
configuration.silent_login_uri &&
|
|
24
|
+
configuration.silent_redirect_uri &&
|
|
25
|
+
configuration.monitor_session &&
|
|
26
|
+
checkSessionIFrameUri &&
|
|
27
|
+
sessionState &&
|
|
28
|
+
!isSilentSignin
|
|
29
|
+
) {
|
|
30
|
+
const checkSessionCallback = () => {
|
|
31
|
+
oidc.checkSessionIFrame.stop();
|
|
32
|
+
const tokens = oidc.tokens;
|
|
33
|
+
if (tokens === null) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const idToken = tokens.idToken;
|
|
37
|
+
const idTokenPayload = tokens.idTokenPayload;
|
|
38
|
+
return silentLoginAsync({
|
|
39
|
+
prompt: 'none',
|
|
40
|
+
id_token_hint: idToken,
|
|
41
|
+
scope: configuration.scope || 'openid',
|
|
42
|
+
})
|
|
43
|
+
.then(silentSigninResponse => {
|
|
44
|
+
if (silentSigninResponse.error) {
|
|
45
|
+
throw new Error(silentSigninResponse.error);
|
|
46
|
+
}
|
|
47
|
+
const iFrameIdTokenPayload = silentSigninResponse.tokens.idTokenPayload;
|
|
48
|
+
if (idTokenPayload.sub === iFrameIdTokenPayload.sub) {
|
|
49
|
+
const sessionState = silentSigninResponse.sessionState;
|
|
50
|
+
oidc.checkSessionIFrame.start(silentSigninResponse.sessionState);
|
|
51
|
+
if (idTokenPayload.sid === iFrameIdTokenPayload.sid) {
|
|
52
|
+
console.debug(
|
|
53
|
+
'SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:',
|
|
54
|
+
sessionState,
|
|
55
|
+
);
|
|
56
|
+
} else {
|
|
57
|
+
console.debug(
|
|
58
|
+
'SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:',
|
|
59
|
+
sessionState,
|
|
60
|
+
);
|
|
19
61
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} else {
|
|
37
|
-
console.debug('SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:', sessionState);
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
console.debug('SessionMonitor._callback: Different subject signed into OP:', iFrameIdTokenPayload.sub);
|
|
41
|
-
}
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
43
|
-
}).catch(async (e) => {
|
|
44
|
-
console.warn('SessionMonitor._callback: Silent login failed, logging out other tabs:', e);
|
|
45
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
46
|
-
for (const [key, oidc] of Object.entries(oidcDatabase)) {
|
|
47
|
-
// @ts-ignore
|
|
48
|
-
await oidc.logoutOtherTabAsync(configuration.client_id, idTokenPayload.sub);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
oidc.checkSessionIFrame = new CheckSessionIFrame(checkSessionCallback, clientId, checkSessionIFrameUri);
|
|
54
|
-
oidc.checkSessionIFrame.load().then(() => {
|
|
55
|
-
oidc.checkSessionIFrame.start(sessionState);
|
|
56
|
-
resolve(oidc.checkSessionIFrame);
|
|
57
|
-
}).catch((e) => {
|
|
58
|
-
reject(e);
|
|
62
|
+
} else {
|
|
63
|
+
console.debug(
|
|
64
|
+
'SessionMonitor._callback: Different subject signed into OP:',
|
|
65
|
+
iFrameIdTokenPayload.sub,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
.catch(async e => {
|
|
70
|
+
console.warn(
|
|
71
|
+
'SessionMonitor._callback: Silent login failed, logging out other tabs:',
|
|
72
|
+
e,
|
|
73
|
+
);
|
|
74
|
+
for (const [, oidc] of Object.entries(oidcDatabase)) {
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
await oidc.logoutOtherTabAsync(configuration.client_id, idTokenPayload.sub);
|
|
77
|
+
}
|
|
59
78
|
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
oidc.checkSessionIFrame = new CheckSessionIFrame(
|
|
82
|
+
checkSessionCallback,
|
|
83
|
+
clientId,
|
|
84
|
+
checkSessionIFrameUri,
|
|
85
|
+
);
|
|
86
|
+
oidc.checkSessionIFrame
|
|
87
|
+
.load()
|
|
88
|
+
.then(() => {
|
|
89
|
+
oidc.checkSessionIFrame.start(sessionState);
|
|
90
|
+
resolve(oidc.checkSessionIFrame);
|
|
91
|
+
})
|
|
92
|
+
.catch(e => {
|
|
93
|
+
reject(e);
|
|
94
|
+
});
|
|
95
|
+
} else {
|
|
96
|
+
resolve(null);
|
|
97
|
+
}
|
|
63
98
|
});
|
|
64
|
-
};
|
|
99
|
+
};
|
|
@@ -3,81 +3,82 @@ const DefaultInterval = 2000;
|
|
|
3
3
|
const Log = console;
|
|
4
4
|
|
|
5
5
|
export class CheckSessionIFrame {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
6
|
+
private readonly _client_id: any;
|
|
7
|
+
private readonly _callback: any;
|
|
8
|
+
private _url: any;
|
|
9
|
+
private readonly _interval: number;
|
|
10
|
+
private readonly _stopOnError: boolean;
|
|
11
|
+
private readonly _frame_origin: string;
|
|
12
|
+
private readonly _frame: HTMLIFrameElement;
|
|
13
|
+
private _boundMessageEvent: any;
|
|
14
|
+
private _timer: number;
|
|
15
|
+
constructor(callback, client_id, url, interval = DefaultInterval, stopOnError = true) {
|
|
16
|
+
this._callback = callback;
|
|
17
|
+
this._client_id = client_id;
|
|
18
|
+
this._url = url;
|
|
19
|
+
this._interval = interval || DefaultInterval;
|
|
20
|
+
this._stopOnError = stopOnError;
|
|
21
|
+
const idx = url.indexOf('/', url.indexOf('//') + 2);
|
|
22
|
+
this._frame_origin = url.substring(0, idx);
|
|
23
|
+
this._frame = window.document.createElement('iframe');
|
|
24
|
+
this._frame.style.visibility = 'hidden';
|
|
25
|
+
this._frame.style.position = 'absolute';
|
|
26
|
+
this._frame.style.display = 'none';
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
this._frame.width = 0;
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
this._frame.height = 0;
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
this._frame.src = url;
|
|
33
|
+
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
load() {
|
|
36
|
+
return new Promise<void>(resolve => {
|
|
37
|
+
this._frame.onload = () => {
|
|
38
|
+
resolve();
|
|
39
|
+
};
|
|
40
|
+
window.document.body.appendChild(this._frame);
|
|
41
|
+
this._boundMessageEvent = this._message.bind(this);
|
|
42
|
+
window.addEventListener('message', this._boundMessageEvent, false);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (this._stopOnError) {
|
|
53
|
-
this.stop();
|
|
54
|
-
}
|
|
55
|
-
} else if (e.data === 'changed') {
|
|
56
|
-
Log.debug(e);
|
|
57
|
-
Log.debug('CheckSessionIFrame: changed message from check session op iframe');
|
|
58
|
-
this.stop();
|
|
59
|
-
this._callback();
|
|
60
|
-
} else {
|
|
61
|
-
Log.debug('CheckSessionIFrame: ' + e.data + ' message from check session op iframe');
|
|
62
|
-
}
|
|
46
|
+
_message(e) {
|
|
47
|
+
if (e.origin === this._frame_origin && e.source === this._frame.contentWindow) {
|
|
48
|
+
if (e.data === 'error') {
|
|
49
|
+
Log.error('CheckSessionIFrame: error message from check session op iframe');
|
|
50
|
+
if (this._stopOnError) {
|
|
51
|
+
this.stop();
|
|
63
52
|
}
|
|
53
|
+
} else if (e.data === 'changed') {
|
|
54
|
+
Log.debug(e);
|
|
55
|
+
Log.debug('CheckSessionIFrame: changed message from check session op iframe');
|
|
56
|
+
this.stop();
|
|
57
|
+
this._callback();
|
|
58
|
+
} else {
|
|
59
|
+
Log.debug('CheckSessionIFrame: ' + e.data + ' message from check session op iframe');
|
|
60
|
+
}
|
|
64
61
|
}
|
|
62
|
+
}
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
64
|
+
start(session_state) {
|
|
65
|
+
Log.debug('CheckSessionIFrame.start :' + session_state);
|
|
66
|
+
this.stop();
|
|
67
|
+
const send = () => {
|
|
68
|
+
this._frame.contentWindow.postMessage(
|
|
69
|
+
this._client_id + ' ' + session_state,
|
|
70
|
+
this._frame_origin,
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
send();
|
|
74
|
+
this._timer = window.setInterval(send, this._interval);
|
|
75
|
+
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
77
|
+
stop() {
|
|
78
|
+
if (this._timer) {
|
|
79
|
+
Log.debug('CheckSessionIFrame.stop');
|
|
80
|
+
window.clearInterval(this._timer);
|
|
81
|
+
this._timer = null;
|
|
82
82
|
}
|
|
83
|
+
}
|
|
83
84
|
}
|
package/src/crypto.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {uint8ToUrlBase64} from
|
|
2
|
-
|
|
1
|
+
import { uint8ToUrlBase64 } from './jwt';
|
|
3
2
|
|
|
4
3
|
const cryptoInfo = () => {
|
|
5
4
|
const hasCrypto = typeof window !== 'undefined' && !!(window.crypto as any);
|
|
@@ -18,18 +17,18 @@ const bufferToString = (buffer: Uint8Array) => {
|
|
|
18
17
|
};
|
|
19
18
|
|
|
20
19
|
export const generateRandom = (size: number) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
20
|
+
const buffer = new Uint8Array(size);
|
|
21
|
+
const { hasCrypto } = cryptoInfo();
|
|
22
|
+
if (hasCrypto) {
|
|
23
|
+
window.crypto.getRandomValues(buffer);
|
|
24
|
+
} else {
|
|
25
|
+
// fall back to Math.random() if nothing else is available
|
|
26
|
+
for (let i = 0; i < size; i += 1) {
|
|
27
|
+
buffer[i] = (Math.random() * charset.length) | 0;
|
|
30
28
|
}
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
}
|
|
30
|
+
return bufferToString(buffer);
|
|
31
|
+
};
|
|
33
32
|
|
|
34
33
|
export function textEncodeLite(str: string) {
|
|
35
34
|
const buf = new ArrayBuffer(str.length);
|
|
@@ -41,22 +40,25 @@ export function textEncodeLite(str: string) {
|
|
|
41
40
|
return bufView;
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
export function base64urlOfHashOfASCIIEncodingAsync(code: string):Promise<string> {
|
|
43
|
+
export function base64urlOfHashOfASCIIEncodingAsync(code: string): Promise<string> {
|
|
45
44
|
return new Promise((resolve, reject) => {
|
|
46
|
-
crypto.subtle.digest('SHA-256', textEncodeLite(code)).then(
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
crypto.subtle.digest('SHA-256', textEncodeLite(code)).then(
|
|
46
|
+
buffer => {
|
|
47
|
+
return resolve(uint8ToUrlBase64(new Uint8Array(buffer)));
|
|
48
|
+
},
|
|
49
|
+
error => reject(error),
|
|
50
|
+
);
|
|
49
51
|
});
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
export const deriveChallengeAsync = (code: string): Promise<string> => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
if (code.length < 43 || code.length > 128) {
|
|
56
|
+
return Promise.reject(new Error('Invalid code length.'));
|
|
57
|
+
}
|
|
58
|
+
const { hasSubtleCrypto } = cryptoInfo();
|
|
59
|
+
if (!hasSubtleCrypto) {
|
|
60
|
+
return Promise.reject(new Error('window.crypto.subtle is unavailable.'));
|
|
61
|
+
}
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
return base64urlOfHashOfASCIIEncodingAsync(code);
|
|
62
64
|
};
|
package/src/events.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
export const eventNames = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
2
|
+
service_worker_not_supported_by_browser: 'service_worker_not_supported_by_browser',
|
|
3
|
+
token_aquired: 'token_aquired',
|
|
4
|
+
logout_from_another_tab: 'logout_from_another_tab',
|
|
5
|
+
logout_from_same_tab: 'logout_from_same_tab',
|
|
6
|
+
token_renewed: 'token_renewed',
|
|
7
|
+
token_timer: 'token_timer',
|
|
8
|
+
loginAsync_begin: 'loginAsync_begin',
|
|
9
|
+
loginAsync_error: 'loginAsync_error',
|
|
10
|
+
loginCallbackAsync_begin: 'loginCallbackAsync_begin',
|
|
11
|
+
loginCallbackAsync_end: 'loginCallbackAsync_end',
|
|
12
|
+
loginCallbackAsync_error: 'loginCallbackAsync_error',
|
|
13
|
+
refreshTokensAsync_begin: 'refreshTokensAsync_begin',
|
|
14
|
+
refreshTokensAsync: 'refreshTokensAsync',
|
|
15
|
+
refreshTokensAsync_end: 'refreshTokensAsync_end',
|
|
16
|
+
refreshTokensAsync_error: 'refreshTokensAsync_error',
|
|
17
|
+
refreshTokensAsync_silent_error: 'refreshTokensAsync_silent_error',
|
|
18
|
+
tryKeepExistingSessionAsync_begin: 'tryKeepExistingSessionAsync_begin',
|
|
19
|
+
tryKeepExistingSessionAsync_end: 'tryKeepExistingSessionAsync_end',
|
|
20
|
+
tryKeepExistingSessionAsync_error: 'tryKeepExistingSessionAsync_error',
|
|
21
|
+
silentLoginAsync_begin: 'silentLoginAsync_begin',
|
|
22
|
+
silentLoginAsync: 'silentLoginAsync',
|
|
23
|
+
silentLoginAsync_end: 'silentLoginAsync_end',
|
|
24
|
+
silentLoginAsync_error: 'silentLoginAsync_error',
|
|
25
|
+
syncTokensAsync_begin: 'syncTokensAsync_begin',
|
|
26
|
+
syncTokensAsync_lock_not_available: 'syncTokensAsync_lock_not_available',
|
|
27
|
+
syncTokensAsync_end: 'syncTokensAsync_end',
|
|
28
|
+
syncTokensAsync_error: 'syncTokensAsync_error',
|
|
29
|
+
tokensInvalidAndWaitingActionsToRefresh: 'tokensInvalidAndWaitingActionsToRefresh',
|
|
30
30
|
};
|
package/src/fetch.ts
CHANGED
|
@@ -1,37 +1,56 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import Oidc from './oidc';
|
|
2
|
+
import {getValidTokenAsync, OidcToken, Tokens} from './parseTokens';
|
|
3
|
+
import {Fetch, StringMap, TokenAutomaticRenewMode} from './types';
|
|
4
4
|
|
|
5
5
|
// @ts-ignore
|
|
6
|
-
export const fetchWithTokens =
|
|
6
|
+
export const fetchWithTokens =
|
|
7
|
+
(
|
|
8
|
+
fetch: Fetch,
|
|
9
|
+
oidc: Oidc | null,
|
|
10
|
+
demonstrating_proof_of_possession: boolean = false,
|
|
11
|
+
): Fetch =>
|
|
12
|
+
async (...params: Parameters<Fetch>): Promise<Response> => {
|
|
7
13
|
const [url, options, ...rest] = params;
|
|
8
14
|
const optionTmp = options ? { ...options } : { method: 'GET' };
|
|
9
15
|
let headers = new Headers();
|
|
10
16
|
if (optionTmp.headers) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
headers = !(optionTmp.headers instanceof Headers)
|
|
18
|
+
? new Headers(optionTmp.headers)
|
|
19
|
+
: optionTmp.headers;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const oidcToken : OidcToken = {
|
|
23
|
+
tokens: oidc.tokens,
|
|
24
|
+
configuration: { token_automatic_renew_mode: oidc.configuration.token_automatic_renew_mode },
|
|
25
|
+
renewTokensAsync: oidc.renewTokensAsync.bind(oidc),
|
|
14
26
|
}
|
|
15
|
-
const oidc = oidcClient;
|
|
16
27
|
|
|
17
28
|
// @ts-ignore
|
|
18
|
-
const getValidToken = await getValidTokenAsync(
|
|
29
|
+
const getValidToken = await getValidTokenAsync(oidcToken);
|
|
19
30
|
const accessToken = getValidToken?.tokens?.accessToken;
|
|
20
31
|
if (!headers.has('Accept')) {
|
|
21
|
-
|
|
32
|
+
headers.set('Accept', 'application/json');
|
|
22
33
|
}
|
|
23
34
|
if (accessToken) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
optionTmp.
|
|
33
|
-
|
|
35
|
+
if (
|
|
36
|
+
oidc.configuration.demonstrating_proof_of_possession &&
|
|
37
|
+
demonstrating_proof_of_possession
|
|
38
|
+
) {
|
|
39
|
+
const demonstrationOdProofOfPossession =
|
|
40
|
+
await oidc.generateDemonstrationOfProofOfPossessionAsync(
|
|
41
|
+
accessToken,
|
|
42
|
+
url.toString(),
|
|
43
|
+
optionTmp.method,
|
|
44
|
+
);
|
|
45
|
+
headers.set('Authorization', `PoP ${accessToken}`);
|
|
46
|
+
headers.set('DPoP', demonstrationOdProofOfPossession);
|
|
47
|
+
} else {
|
|
48
|
+
headers.set('Authorization', `Bearer ${accessToken}`);
|
|
49
|
+
}
|
|
50
|
+
if (!optionTmp.credentials) {
|
|
51
|
+
optionTmp.credentials = 'same-origin';
|
|
52
|
+
}
|
|
34
53
|
}
|
|
35
54
|
const newOptions = { ...optionTmp, headers };
|
|
36
55
|
return await fetch(url, newOptions, ...rest);
|
|
37
|
-
};
|
|
56
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
export type { ILOidcLocation } from './location.js';
|
|
2
|
+
export { OidcLocation } from './location.js';
|
|
2
3
|
export { getFetchDefault } from './oidc.js';
|
|
4
|
+
export type { OidcUserInfo } from './oidcClient.js';
|
|
5
|
+
export { OidcClient } from './oidcClient.js';
|
|
6
|
+
export type { Tokens } from './parseTokens.js';
|
|
3
7
|
export { TokenRenewMode } from './parseTokens.js';
|
|
4
8
|
export { getParseQueryStringFromLocation, getPath } from './route-utils';
|
|
5
|
-
|
|
6
|
-
export type {
|
|
7
|
-
Tokens
|
|
8
|
-
} from './parseTokens.js';
|
|
9
|
-
|
|
10
|
-
export type {
|
|
11
|
-
AuthorityConfiguration,
|
|
12
|
-
Fetch,
|
|
13
|
-
OidcConfiguration,
|
|
14
|
-
StringMap
|
|
15
|
-
} from './types.js';
|
|
16
|
-
|
|
17
|
-
export { OidcLocation } from './location.js';
|
|
18
|
-
export type { ILOidcLocation } from './location.js';
|
|
9
|
+
export type { AuthorityConfiguration, Fetch, OidcConfiguration, StringMap } from './types.js';
|
|
19
10
|
export { TokenAutomaticRenewMode } from './types.js';
|
|
20
|
-
export { OidcClient } from './oidcClient.js';
|
|
21
|
-
export type { OidcUserInfo } from './oidcClient.js';
|
package/src/iniWorker.spec.ts
CHANGED
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
import { describe, expect,it } from 'vitest';
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import { excludeOs, getOperatingSystem } from './initWorkerOption';
|
|
4
4
|
|
|
5
5
|
describe('initWorker test Suite', () => {
|
|
6
|
+
it.each([
|
|
7
|
+
[
|
|
8
|
+
'Mozilla/5.0 (iPhone; CPU iPhone OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1',
|
|
9
|
+
'iOS',
|
|
10
|
+
'12.1.0',
|
|
11
|
+
],
|
|
12
|
+
[
|
|
13
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.105 Mobile/15E148 Safari/605.1',
|
|
14
|
+
'Mac OS X',
|
|
15
|
+
'10_15_6',
|
|
16
|
+
],
|
|
17
|
+
])(
|
|
18
|
+
'getOperatingSystem should return OS for Version',
|
|
19
|
+
(userAgent, expectedOs, expectedVersion) => {
|
|
20
|
+
const operatingSystem = getOperatingSystem({
|
|
21
|
+
userAgent,
|
|
22
|
+
appVersion: 'OS ' + expectedVersion.replaceAll('.', '_'),
|
|
23
|
+
});
|
|
24
|
+
expect(expectedOs).toBe(operatingSystem.os);
|
|
25
|
+
expect(expectedVersion).toBe(operatingSystem.osVersion);
|
|
6
26
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const operatingSystem = getOperatingSystem({ userAgent, appVersion: 'OS ' + expectedVersion.replaceAll('.', '_') });
|
|
13
|
-
expect(expectedOs).toBe(operatingSystem.os);
|
|
14
|
-
expect(expectedVersion).toBe(operatingSystem.osVersion);
|
|
15
|
-
|
|
16
|
-
const isExcluded = excludeOs(operatingSystem);
|
|
17
|
-
expect(isExcluded).toBe(true);
|
|
18
|
-
},
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
});
|
|
27
|
+
const isExcluded = excludeOs(operatingSystem);
|
|
28
|
+
expect(isExcluded).toBe(true);
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
});
|