@axa-fr/react-oidc 6.12.1 → 6.13.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/OidcProvider.d.ts +1 -1
- package/dist/OidcProvider.d.ts.map +1 -1
- package/dist/OidcSecure.d.ts +1 -1
- package/dist/OidcSecure.d.ts.map +1 -1
- package/dist/ReactOidc.d.ts +1 -1
- package/dist/ReactOidc.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/vanilla/checkSession.d.ts +5 -0
- package/dist/vanilla/checkSession.d.ts.map +1 -0
- package/dist/vanilla/checkSession.js +68 -0
- package/dist/vanilla/checkSession.js.map +1 -0
- package/dist/vanilla/events.d.ts +29 -0
- package/dist/vanilla/events.d.ts.map +1 -0
- package/dist/vanilla/events.js +32 -0
- package/dist/vanilla/events.js.map +1 -0
- package/dist/vanilla/initSession.d.ts +3 -3
- package/dist/vanilla/initSession.d.ts.map +1 -1
- package/dist/vanilla/initSession.js +19 -23
- package/dist/vanilla/initSession.js.map +1 -1
- package/dist/vanilla/initWorker.d.ts +4 -4
- package/dist/vanilla/initWorker.d.ts.map +1 -1
- package/dist/vanilla/initWorker.js +11 -15
- package/dist/vanilla/initWorker.js.map +1 -1
- package/dist/vanilla/login.d.ts +4 -0
- package/dist/vanilla/login.d.ts.map +1 -0
- package/dist/vanilla/login.js +244 -0
- package/dist/vanilla/login.js.map +1 -0
- package/dist/vanilla/oidc.d.ts +4 -37
- package/dist/vanilla/oidc.d.ts.map +1 -1
- package/dist/vanilla/oidc.js +99 -519
- package/dist/vanilla/oidc.js.map +1 -1
- package/dist/vanilla/renewTokens.d.ts +4 -0
- package/dist/vanilla/renewTokens.d.ts.map +1 -0
- package/dist/vanilla/renewTokens.js +50 -0
- package/dist/vanilla/renewTokens.js.map +1 -0
- package/dist/vanilla/requests.d.ts +2 -0
- package/dist/vanilla/requests.d.ts.map +1 -1
- package/dist/vanilla/requests.js +20 -1
- package/dist/vanilla/requests.js.map +1 -1
- package/dist/vanilla/route-utils.js +1 -1
- package/dist/vanilla/route-utils.js.map +1 -1
- package/dist/vanilla/silentLogin.d.ts +9 -0
- package/dist/vanilla/silentLogin.d.ts.map +1 -0
- package/dist/vanilla/silentLogin.js +144 -0
- package/dist/vanilla/silentLogin.js.map +1 -0
- package/dist/vanilla/types.d.ts +33 -0
- package/dist/vanilla/types.d.ts.map +1 -0
- package/dist/vanilla/types.js +3 -0
- package/dist/vanilla/types.js.map +1 -0
- package/dist/vanilla/user.d.ts +2 -0
- package/dist/vanilla/user.d.ts.map +1 -0
- package/dist/vanilla/user.js +48 -0
- package/dist/vanilla/user.js.map +1 -0
- package/dist/vanilla/vanillaOidc.d.ts +2 -1
- package/dist/vanilla/vanillaOidc.d.ts.map +1 -1
- package/dist/vanilla/vanillaOidc.js.map +1 -1
- package/package.json +1 -1
- package/src/oidc/OidcProvider.tsx +1 -1
- package/src/oidc/OidcSecure.tsx +1 -1
- package/src/oidc/ReactOidc.tsx +1 -1
- package/src/oidc/index.ts +1 -1
- package/src/oidc/vanilla/checkSession.ts +55 -0
- package/src/oidc/vanilla/events.ts +29 -0
- package/src/oidc/vanilla/index.ts +1 -1
- package/src/oidc/vanilla/initSession.ts +19 -25
- package/src/oidc/vanilla/initWorker.ts +12 -18
- package/src/oidc/vanilla/login.ts +242 -0
- package/src/oidc/vanilla/oidc.ts +53 -554
- package/src/oidc/vanilla/renewTokens.ts +36 -0
- package/src/oidc/vanilla/requests.ts +24 -0
- package/src/oidc/vanilla/route-utils.ts +1 -1
- package/src/oidc/vanilla/silentLogin.ts +143 -0
- package/src/oidc/vanilla/types.ts +35 -0
- package/src/oidc/vanilla/user.ts +39 -0
- package/src/oidc/vanilla/vanillaOidc.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vanillaOidc.js","sourceRoot":"","sources":["../../src/oidc/vanilla/vanillaOidc.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"vanillaOidc.js","sourceRoot":"","sources":["../../src/oidc/vanilla/vanillaOidc.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iCAA6C;AAC7C,+CAAuE;AAOvE,MAAa,WAAW;IAEpB,YAAY,IAAU;QAClB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,eAAe,CAAC,IAAoB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,uBAAuB,CAAC,EAAS;QAC7B,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,YAAY,CAAC,SAAgB,EAAE,IAAQ;QACnC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,aAA+B,EAAE,IAAI,GAAG,SAAS;QAChE,OAAO,IAAI,WAAW,CAAC,WAAI,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,SAAS;QACvB,OAAO,IAAI,WAAW,CAAC,WAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IAGD,2BAA2B;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,2BAA2B,EAAE,CAAC;IACpD,CAAC;IAED,UAAU,CAAC,eAAsB,SAAS,EAAE,SAAmB,IAAI,EAAE,cAAc,GAAG,KAAK,EAAE,QAAe,SAAS,EAAE,eAAe,GAAG,KAAK;QAC1I,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAC/F,CAAC;IAED,WAAW,CAAC,oBAA+C,SAAS,EAAE,SAAoB,IAAI;QAC1F,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,wBAAwB;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,wBAAwB,EAAE,CAAC;IACjD,CAAC;IAED,gBAAgB,CAAC,SAAmB,IAAI;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,kBAAkB;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,qCAAqC,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,MAAM;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,IAAI,aAAa;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IACpC,CAAC;IAEK,kBAAkB,CAAC,MAAM,GAAG,GAAG,EAAE,UAAU,GAAG,EAAE;;YAClD,OAAO,IAAA,gCAAkB,EAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9D,CAAC;KAAA;IAEK,aAAa;;YACf,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACtC,CAAC;KAAA;;AAjEL,kCAkEC;AAxCU,sBAAU,GAAG,WAAI,CAAC,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ import { Authenticating, CallBackSuccess, Loading, SessionLost } from './core/de
|
|
|
5
5
|
import ServiceWorkerNotSupported from './core/default-component/ServiceWorkerNotSupported.component';
|
|
6
6
|
import OidcRoutes from './core/routes/OidcRoutes';
|
|
7
7
|
import { CustomHistory } from './core/routes/withRouter';
|
|
8
|
-
import { OidcConfiguration } from './vanilla/
|
|
8
|
+
import { OidcConfiguration } from './vanilla/types';
|
|
9
9
|
import { VanillaOidc } from './vanilla/vanillaOidc';
|
|
10
10
|
|
|
11
11
|
export type oidcContext = {
|
package/src/oidc/OidcSecure.tsx
CHANGED
package/src/oidc/ReactOidc.tsx
CHANGED
package/src/oidc/index.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { OidcProvider } from './OidcProvider';
|
|
|
3
3
|
export { OidcSecure, withOidcSecure } from './OidcSecure';
|
|
4
4
|
export { useOidc, useOidcAccessToken, useOidcIdToken } from './ReactOidc';
|
|
5
5
|
export { OidcUserStatus, useOidcUser } from './User';
|
|
6
|
-
export type { OidcConfiguration } from './vanilla/oidc';
|
|
7
6
|
export { TokenRenewMode } from './vanilla/parseTokens';
|
|
7
|
+
export type { AuthorityConfiguration, OidcConfiguration, StringMap } from './vanilla/types';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { CheckSessionIFrame } from './checkSessionIFrame';
|
|
2
|
+
import { Tokens } from './parseTokens';
|
|
3
|
+
import { OidcConfiguration } from './types';
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
6
|
+
export const startCheckSessionAsync = (oidcDatabase:any, configuration :OidcConfiguration, checkSessionIFrame: CheckSessionIFrame, silentLoginAsync:Function, getCurrentTokens: () => Tokens) => (checkSessionIFrameUri, clientId, sessionState, isSilentSignin = false) => {
|
|
7
|
+
return new Promise<CheckSessionIFrame>((resolve, reject): void => {
|
|
8
|
+
if (configuration.silent_login_uri && configuration.silent_redirect_uri && configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
|
|
9
|
+
const checkSessionCallback = () => {
|
|
10
|
+
checkSessionIFrame.stop();
|
|
11
|
+
const tokens = getCurrentTokens();
|
|
12
|
+
if (tokens === null) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const idToken = tokens.idToken;
|
|
16
|
+
const idTokenPayload = tokens.idTokenPayload;
|
|
17
|
+
silentLoginAsync({
|
|
18
|
+
prompt: 'none',
|
|
19
|
+
id_token_hint: idToken,
|
|
20
|
+
scope: 'openid',
|
|
21
|
+
}).then((silentSigninResponse) => {
|
|
22
|
+
const iFrameIdTokenPayload = silentSigninResponse.tokens.idTokenPayload;
|
|
23
|
+
if (idTokenPayload.sub === iFrameIdTokenPayload.sub) {
|
|
24
|
+
const sessionState = silentSigninResponse.sessionState;
|
|
25
|
+
checkSessionIFrame.start(silentSigninResponse.sessionState);
|
|
26
|
+
if (idTokenPayload.sid === iFrameIdTokenPayload.sid) {
|
|
27
|
+
console.debug('SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:', sessionState);
|
|
28
|
+
} else {
|
|
29
|
+
console.debug('SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:', sessionState);
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
console.debug('SessionMonitor._callback: Different subject signed into OP:', iFrameIdTokenPayload.sub);
|
|
33
|
+
}
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
35
|
+
}).catch(async (e) => {
|
|
36
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
37
|
+
for (const [key, oidc] of Object.entries(oidcDatabase)) {
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
await oidc.logoutOtherTabAsync(this.configuration.client_id, idTokenPayload.sub);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
checkSessionIFrame = new CheckSessionIFrame(checkSessionCallback, clientId, checkSessionIFrameUri);
|
|
45
|
+
checkSessionIFrame.load().then(() => {
|
|
46
|
+
checkSessionIFrame.start(sessionState);
|
|
47
|
+
resolve(checkSessionIFrame);
|
|
48
|
+
}).catch((e) => {
|
|
49
|
+
reject(e);
|
|
50
|
+
});
|
|
51
|
+
} else {
|
|
52
|
+
resolve(null);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
export const eventNames = {
|
|
3
|
+
service_worker_not_supported_by_browser: 'service_worker_not_supported_by_browser',
|
|
4
|
+
token_aquired: 'token_aquired',
|
|
5
|
+
logout_from_another_tab: 'logout_from_another_tab',
|
|
6
|
+
logout_from_same_tab: 'logout_from_same_tab',
|
|
7
|
+
token_renewed: 'token_renewed',
|
|
8
|
+
token_timer: 'token_timer',
|
|
9
|
+
loginAsync_begin: 'loginAsync_begin',
|
|
10
|
+
loginAsync_error: 'loginAsync_error',
|
|
11
|
+
loginCallbackAsync_begin: 'loginCallbackAsync_begin',
|
|
12
|
+
loginCallbackAsync_end: 'loginCallbackAsync_end',
|
|
13
|
+
loginCallbackAsync_error: 'loginCallbackAsync_error',
|
|
14
|
+
refreshTokensAsync_begin: 'refreshTokensAsync_begin',
|
|
15
|
+
refreshTokensAsync: 'refreshTokensAsync',
|
|
16
|
+
refreshTokensAsync_end: 'refreshTokensAsync_end',
|
|
17
|
+
refreshTokensAsync_error: 'refreshTokensAsync_error',
|
|
18
|
+
refreshTokensAsync_silent_error: 'refreshTokensAsync_silent_error',
|
|
19
|
+
tryKeepExistingSessionAsync_begin: 'tryKeepExistingSessionAsync_begin',
|
|
20
|
+
tryKeepExistingSessionAsync_end: 'tryKeepExistingSessionAsync_end',
|
|
21
|
+
tryKeepExistingSessionAsync_error: 'tryKeepExistingSessionAsync_error',
|
|
22
|
+
silentLoginAsync_begin: 'silentLoginAsync_begin',
|
|
23
|
+
silentLoginAsync: 'silentLoginAsync',
|
|
24
|
+
silentLoginAsync_end: 'silentLoginAsync_end',
|
|
25
|
+
silentLoginAsync_error: 'silentLoginAsync_error',
|
|
26
|
+
syncTokensAsync_begin: 'syncTokensAsync_begin',
|
|
27
|
+
syncTokensAsync_end: 'syncTokensAsync_end',
|
|
28
|
+
syncTokensAsync_error: 'syncTokensAsync_error',
|
|
29
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { OidcConfiguration } from './
|
|
1
|
+
export { AuthorityConfiguration, OidcConfiguration, StringMap } from './types';
|
|
2
2
|
export { VanillaOidc } from './vanillaOidc';
|
|
@@ -1,68 +1,62 @@
|
|
|
1
|
-
export const initSession = (configurationName,
|
|
1
|
+
export const initSession = (configurationName, storage = sessionStorage) => {
|
|
2
2
|
const saveItemsAsync = (items) => {
|
|
3
|
-
storage[`
|
|
3
|
+
storage[`oidc.items.${configurationName}`] = JSON.stringify(items);
|
|
4
4
|
return Promise.resolve();
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
const loadItemsAsync = () => {
|
|
8
|
-
return Promise.resolve(JSON.parse(storage[`
|
|
8
|
+
return Promise.resolve(JSON.parse(storage[`oidc.items.${configurationName}`]));
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
const clearAsync = (status) => {
|
|
12
|
-
storage[`oidc.${configurationName}
|
|
12
|
+
storage[`oidc.${configurationName}`] = JSON.stringify({ tokens: null, status });
|
|
13
13
|
return Promise.resolve();
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
const initAsync = async () => {
|
|
17
|
-
if (!storage[`oidc.${configurationName}
|
|
18
|
-
storage[`oidc.${configurationName}
|
|
17
|
+
if (!storage[`oidc.${configurationName}`]) {
|
|
18
|
+
storage[`oidc.${configurationName}`] = JSON.stringify({ tokens: null, status: null });
|
|
19
19
|
return { tokens: null, status: null };
|
|
20
20
|
}
|
|
21
|
-
const data = JSON.parse(storage[`oidc.${configurationName}
|
|
21
|
+
const data = JSON.parse(storage[`oidc.${configurationName}`]);
|
|
22
22
|
return Promise.resolve({ tokens: data.tokens, status: data.status });
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
const setTokens = (tokens) => {
|
|
26
|
-
storage[`oidc.${configurationName}
|
|
26
|
+
storage[`oidc.${configurationName}`] = JSON.stringify({ tokens });
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const setSessionState = (sessionState) => {
|
|
30
|
-
storage[`oidc.session_state.${configurationName}
|
|
30
|
+
storage[`oidc.session_state.${configurationName}`] = sessionState;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
const getSessionState = () => {
|
|
34
|
-
return storage[`oidc.session_state.${configurationName}
|
|
34
|
+
return storage[`oidc.session_state.${configurationName}`];
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
const setNonceAsync = (nonce) => {
|
|
38
|
-
localStorage[`oidc.nonce.${configurationName}
|
|
38
|
+
localStorage[`oidc.nonce.${configurationName}`] = nonce.nonce;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
const getNonceAsync = async () => {
|
|
42
42
|
// @ts-ignore
|
|
43
|
-
return { nonce: localStorage[`oidc.nonce.${configurationName}
|
|
43
|
+
return { nonce: localStorage[`oidc.nonce.${configurationName}`] };
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
const getTokens = () => {
|
|
47
|
-
if (!storage[`oidc.${configurationName}
|
|
47
|
+
if (!storage[`oidc.${configurationName}`]) {
|
|
48
48
|
return null;
|
|
49
49
|
}
|
|
50
|
-
return JSON.stringify({ tokens: JSON.parse(storage[`oidc.${configurationName}
|
|
50
|
+
return JSON.stringify({ tokens: JSON.parse(storage[`oidc.${configurationName}`]).tokens });
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const setLoginParams = (configurationName:string, redirectUri:string, data) => {
|
|
58
|
-
const sessionKey = getLoginSessionKey(configurationName, redirectUri);
|
|
53
|
+
let getLoginParamsCache = null;
|
|
54
|
+
const setLoginParams = (configurationName:string, data) => {
|
|
59
55
|
getLoginParamsCache = data;
|
|
60
|
-
storage[
|
|
56
|
+
storage[`oidc.login.${configurationName}`] = JSON.stringify(data);
|
|
61
57
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const getLoginParams = (configurationName, redirectUri) => {
|
|
65
|
-
const dataString = storage[getLoginSessionKey(configurationName, redirectUri)];
|
|
58
|
+
const getLoginParams = (configurationName) => {
|
|
59
|
+
const dataString = storage[`oidc.login.${configurationName}`];
|
|
66
60
|
if (!getLoginParamsCache) {
|
|
67
61
|
getLoginParamsCache = JSON.parse(dataString);
|
|
68
62
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { initSession } from './initSession';
|
|
2
|
-
import { OidcConfiguration } from './oidc';
|
|
3
2
|
import { parseOriginalTokens } from './parseTokens';
|
|
4
3
|
import timer from './timer';
|
|
4
|
+
import { OidcConfiguration } from './types';
|
|
5
5
|
|
|
6
6
|
export const getOperatingSystem = () => {
|
|
7
7
|
const nVer = navigator.appVersion;
|
|
@@ -140,7 +140,7 @@ const sendMessageAsync = (registration) => (data) => {
|
|
|
140
140
|
});
|
|
141
141
|
};
|
|
142
142
|
|
|
143
|
-
export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
143
|
+
export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName) => {
|
|
144
144
|
if (typeof window === 'undefined' || typeof navigator === 'undefined' || !navigator.serviceWorker || !serviceWorkerRelativeUrl) {
|
|
145
145
|
return null;
|
|
146
146
|
}
|
|
@@ -192,7 +192,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
192
192
|
const saveItemsAsync = (items) => {
|
|
193
193
|
// iOS kill Service Worker when domain we leave domain
|
|
194
194
|
if (operatingSystem.os === 'iOS') {
|
|
195
|
-
const session = initSession(configurationName
|
|
195
|
+
const session = initSession(configurationName);
|
|
196
196
|
return session.saveItemsAsync(items);
|
|
197
197
|
}
|
|
198
198
|
return sendMessageAsync(registration)({ type: 'saveItems', data: items, configurationName });
|
|
@@ -200,7 +200,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
200
200
|
const loadItemsAsync = () => {
|
|
201
201
|
// iOS kill Service Worker when domain we leave domain
|
|
202
202
|
if (operatingSystem.os === 'iOS') {
|
|
203
|
-
const session = initSession(configurationName
|
|
203
|
+
const session = initSession(configurationName);
|
|
204
204
|
return session.loadItemsAsync();
|
|
205
205
|
}
|
|
206
206
|
return sendMessageAsync(registration)({ type: 'loadItems', data: null, configurationName });
|
|
@@ -208,7 +208,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
208
208
|
const clearAsync = async (status) => {
|
|
209
209
|
// iOS kill Service Worker when domain we leave domain
|
|
210
210
|
if (operatingSystem.os === 'iOS') {
|
|
211
|
-
const session = initSession(configurationName
|
|
211
|
+
const session = initSession(configurationName);
|
|
212
212
|
await session.clearAsync(status);
|
|
213
213
|
}
|
|
214
214
|
return sendMessageAsync(registration)({ type: 'clear', data: { status }, configurationName });
|
|
@@ -243,7 +243,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
243
243
|
const setNonceAsync = (nonce) => {
|
|
244
244
|
// iOS kill Service Worker when domain we leave domain
|
|
245
245
|
if (operatingSystem.os === 'iOS') {
|
|
246
|
-
const session = initSession(configurationName
|
|
246
|
+
const session = initSession(configurationName);
|
|
247
247
|
return session.setNonceAsync(nonce);
|
|
248
248
|
}
|
|
249
249
|
return sendMessageAsync(registration)({ type: 'setNonce', data: { nonce }, configurationName });
|
|
@@ -253,7 +253,7 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
253
253
|
const getNonceAsync = async () => {
|
|
254
254
|
// iOS kill Service Worker when domain we leave domain
|
|
255
255
|
if (operatingSystem.os === 'iOS') {
|
|
256
|
-
const session = initSession(configurationName
|
|
256
|
+
const session = initSession(configurationName);
|
|
257
257
|
return session.getNonceAsync();
|
|
258
258
|
}
|
|
259
259
|
// @ts-ignore
|
|
@@ -261,19 +261,13 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
261
261
|
return { nonce: keyNonce };
|
|
262
262
|
};
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
const setLoginParams = (configurationName:string, redirectUri:string, data) => {
|
|
269
|
-
const sessionKey = getLoginSessionKey(configurationName, redirectUri);
|
|
264
|
+
let getLoginParamsCache = null;
|
|
265
|
+
const setLoginParams = (configurationName:string, data) => {
|
|
270
266
|
getLoginParamsCache = data;
|
|
271
|
-
|
|
267
|
+
localStorage[`oidc.login.${configurationName}`] = JSON.stringify(data);
|
|
272
268
|
};
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const getLoginParams = (configurationName, redirectUri) => {
|
|
276
|
-
const dataString = sessionStorage[getLoginSessionKey(configurationName, redirectUri)];
|
|
269
|
+
const getLoginParams = (configurationName) => {
|
|
270
|
+
const dataString = localStorage[`oidc.login.${configurationName}`];
|
|
277
271
|
if (!getLoginParamsCache) {
|
|
278
272
|
getLoginParamsCache = JSON.parse(dataString);
|
|
279
273
|
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthorizationNotifier,
|
|
3
|
+
AuthorizationRequest, BaseTokenRequestHandler,
|
|
4
|
+
DefaultCrypto, FetchRequestor, GRANT_TYPE_AUTHORIZATION_CODE,
|
|
5
|
+
RedirectRequestHandler,
|
|
6
|
+
TokenRequest,
|
|
7
|
+
} from '@openid/appauth';
|
|
8
|
+
|
|
9
|
+
import { eventNames } from './events';
|
|
10
|
+
import { initSession } from './initSession';
|
|
11
|
+
import { initWorkerAsync } from './initWorker';
|
|
12
|
+
import { MemoryStorageBackend } from './memoryStorageBackend';
|
|
13
|
+
import { HashQueryStringUtils, NoHashQueryStringUtils } from './noHashQueryStringUtils';
|
|
14
|
+
import { isTokensOidcValid, setTokens } from './parseTokens';
|
|
15
|
+
import { getParseQueryStringFromLocation } from './route-utils';
|
|
16
|
+
import { OidcConfiguration, StringMap } from './types';
|
|
17
|
+
|
|
18
|
+
const randomString = function(length) {
|
|
19
|
+
let text = '';
|
|
20
|
+
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
21
|
+
for (let i = 0; i < length; i++) {
|
|
22
|
+
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
23
|
+
}
|
|
24
|
+
return text;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
28
|
+
export const defaultLoginAsync = (window, configurationName, configuration:OidcConfiguration, publishEvent :(string, any)=>void, initAsync:Function) => (callbackPath:string = undefined, extras:StringMap = null, isSilentSignin = false, scope:string = undefined) => {
|
|
29
|
+
const originExtras = extras;
|
|
30
|
+
extras = { ...extras };
|
|
31
|
+
const loginLocalAsync = async () => {
|
|
32
|
+
const location = window.location;
|
|
33
|
+
const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
|
|
34
|
+
let state;
|
|
35
|
+
if (extras && 'state' in extras) {
|
|
36
|
+
state = extras.state;
|
|
37
|
+
delete extras.state;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
publishEvent(eventNames.loginAsync_begin, {});
|
|
41
|
+
if (extras) {
|
|
42
|
+
for (const key of Object.keys(extras)) {
|
|
43
|
+
if (key.endsWith(':token_request')) {
|
|
44
|
+
delete extras[key];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
|
|
50
|
+
if (!scope) {
|
|
51
|
+
scope = configuration.scope;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const extraFinal = !configuration.extras ? extras : { ...configuration.extras, ...extras };
|
|
55
|
+
if (!extraFinal.nonce) {
|
|
56
|
+
extraFinal.nonce = randomString(12);
|
|
57
|
+
}
|
|
58
|
+
const nonce = { nonce: extraFinal.nonce };
|
|
59
|
+
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, configurationName);
|
|
60
|
+
const oidcServerConfiguration = await initAsync(configuration.authority, configuration.authority_configuration);
|
|
61
|
+
let storage;
|
|
62
|
+
if (serviceWorker) {
|
|
63
|
+
serviceWorker.setLoginParams(configurationName, { callbackPath: url, extras: originExtras, state });
|
|
64
|
+
serviceWorker.startKeepAliveServiceWorker();
|
|
65
|
+
await serviceWorker.initAsync(oidcServerConfiguration, 'loginAsync', configuration);
|
|
66
|
+
await serviceWorker.setNonceAsync(nonce);
|
|
67
|
+
storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, {});
|
|
68
|
+
await storage.setItem('dummy', {});
|
|
69
|
+
} else {
|
|
70
|
+
let session = initSession(configurationName, configuration.storage ?? sessionStorage);
|
|
71
|
+
session.setLoginParams(configurationName, { callbackPath: url, extras: originExtras, state });
|
|
72
|
+
session = initSession(configurationName);
|
|
73
|
+
await session.setNonceAsync(nonce);
|
|
74
|
+
storage = new MemoryStorageBackend(session.saveItemsAsync, {});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
const queryStringUtil = redirectUri.includes('#') ? new HashQueryStringUtils() : new NoHashQueryStringUtils();
|
|
79
|
+
const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
|
|
80
|
+
const authRequest = new AuthorizationRequest({
|
|
81
|
+
client_id: configuration.client_id,
|
|
82
|
+
redirect_uri: redirectUri,
|
|
83
|
+
scope,
|
|
84
|
+
response_type: AuthorizationRequest.RESPONSE_TYPE_CODE,
|
|
85
|
+
state,
|
|
86
|
+
extras: extraFinal,
|
|
87
|
+
});
|
|
88
|
+
authorizationHandler.performAuthorizationRequest(oidcServerConfiguration, authRequest);
|
|
89
|
+
} catch (exception) {
|
|
90
|
+
publishEvent(eventNames.loginAsync_error, exception);
|
|
91
|
+
throw exception;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
return loginLocalAsync();
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const loginCallbackAsync = (oidc) => async (isSilentSignin = false) => {
|
|
98
|
+
try {
|
|
99
|
+
oidc.publishEvent(eventNames.loginCallbackAsync_begin, {});
|
|
100
|
+
const configuration = oidc.configuration;
|
|
101
|
+
const clientId = configuration.client_id;
|
|
102
|
+
const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
|
|
103
|
+
const authority = configuration.authority;
|
|
104
|
+
const tokenRequestTimeout = configuration.token_request_timeout;
|
|
105
|
+
const oidcServerConfiguration = await oidc.initAsync(authority, configuration.authority_configuration);
|
|
106
|
+
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
107
|
+
const sessionState = queryParams.session_state;
|
|
108
|
+
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, oidc.configurationName);
|
|
109
|
+
let storage = null;
|
|
110
|
+
let nonceData = null;
|
|
111
|
+
let getLoginParams = null;
|
|
112
|
+
if (serviceWorker) {
|
|
113
|
+
serviceWorker.startKeepAliveServiceWorker();
|
|
114
|
+
await serviceWorker.initAsync(oidcServerConfiguration, 'loginCallbackAsync', configuration);
|
|
115
|
+
const items = await serviceWorker.loadItemsAsync();
|
|
116
|
+
storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, items);
|
|
117
|
+
const dummy = await storage.getItem('dummy');
|
|
118
|
+
if (!dummy) {
|
|
119
|
+
throw new Error('Service Worker storage disapear');
|
|
120
|
+
}
|
|
121
|
+
await storage.removeItem('dummy');
|
|
122
|
+
await serviceWorker.setSessionStateAsync(sessionState);
|
|
123
|
+
nonceData = await serviceWorker.getNonceAsync();
|
|
124
|
+
getLoginParams = serviceWorker.getLoginParams(oidc.configurationName);
|
|
125
|
+
} else {
|
|
126
|
+
const session = initSession(oidc.configurationName);
|
|
127
|
+
session.setSessionState(sessionState);
|
|
128
|
+
const items = await session.loadItemsAsync();
|
|
129
|
+
storage = new MemoryStorageBackend(session.saveItemsAsync, items);
|
|
130
|
+
nonceData = await session.getNonceAsync();
|
|
131
|
+
getLoginParams = session.getLoginParams(oidc.configurationName);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
let queryStringUtil = new NoHashQueryStringUtils();
|
|
136
|
+
if (redirectUri.includes('#')) {
|
|
137
|
+
const splithash = window.location.href.split('#');
|
|
138
|
+
if (splithash.length === 2 && splithash[1].includes('?')) {
|
|
139
|
+
queryStringUtil = new HashQueryStringUtils();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
|
|
143
|
+
const notifier = new AuthorizationNotifier();
|
|
144
|
+
authorizationHandler.setAuthorizationNotifier(notifier);
|
|
145
|
+
|
|
146
|
+
notifier.setAuthorizationListener((request, response, error) => {
|
|
147
|
+
if (error) {
|
|
148
|
+
reject(error);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (!response) {
|
|
152
|
+
reject(new Error('no response'));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const extras = {};
|
|
157
|
+
if (request && request.internal) {
|
|
158
|
+
// @ts-ignore
|
|
159
|
+
extras.code_verifier = request.internal.code_verifier;
|
|
160
|
+
if (configuration.token_request_extras) {
|
|
161
|
+
for (const [key, value] of Object.entries(configuration.token_request_extras)) {
|
|
162
|
+
extras[key] = value;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (getLoginParams && getLoginParams.extras) {
|
|
166
|
+
for (const [key, value] of Object.entries(getLoginParams.extras)) {
|
|
167
|
+
if (key.endsWith(':token_request')) {
|
|
168
|
+
extras[key.replace(':token_request', '')] = value;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const tokenRequest = new TokenRequest({
|
|
175
|
+
client_id: clientId,
|
|
176
|
+
redirect_uri: redirectUri, // @ts-ignore
|
|
177
|
+
grant_type: GRANT_TYPE_AUTHORIZATION_CODE,
|
|
178
|
+
code: response.code,
|
|
179
|
+
refresh_token: undefined,
|
|
180
|
+
extras,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
let timeoutId = setTimeout(() => {
|
|
184
|
+
reject(new Error('performTokenRequest timeout'));
|
|
185
|
+
timeoutId = null;
|
|
186
|
+
}, tokenRequestTimeout ?? 12000);
|
|
187
|
+
try {
|
|
188
|
+
const tokenHandler = new BaseTokenRequestHandler(new FetchRequestor());
|
|
189
|
+
tokenHandler.performTokenRequest(oidcServerConfiguration, tokenRequest).then(async (tokenResponse) => {
|
|
190
|
+
if (timeoutId) {
|
|
191
|
+
clearTimeout(timeoutId);
|
|
192
|
+
oidc.timeoutId = null;
|
|
193
|
+
let loginParams = null;
|
|
194
|
+
let formattedTokens = null;
|
|
195
|
+
if (serviceWorker) {
|
|
196
|
+
const { tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'syncTokensAsync', configuration);
|
|
197
|
+
loginParams = serviceWorker.getLoginParams(oidc.configurationName);
|
|
198
|
+
formattedTokens = tokens;
|
|
199
|
+
} else {
|
|
200
|
+
const session = initSession(oidc.configurationName, configuration.storage);
|
|
201
|
+
loginParams = session.getLoginParams(oidc.configurationName);
|
|
202
|
+
formattedTokens = setTokens(tokenResponse, null, configuration.token_renew_mode);
|
|
203
|
+
}
|
|
204
|
+
if (!isTokensOidcValid(formattedTokens, nonceData.nonce, oidcServerConfiguration)) {
|
|
205
|
+
const exception = new Error('Tokens are not OpenID valid');
|
|
206
|
+
if (timeoutId) {
|
|
207
|
+
clearTimeout(timeoutId);
|
|
208
|
+
oidc.timeoutId = null;
|
|
209
|
+
oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
210
|
+
console.error(exception);
|
|
211
|
+
reject(exception);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
oidc.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, clientId, sessionState, isSilentSignin).then(() => {
|
|
216
|
+
oidc.publishEvent(eventNames.loginCallbackAsync_end, {});
|
|
217
|
+
resolve({
|
|
218
|
+
tokens: formattedTokens,
|
|
219
|
+
state: request.state,
|
|
220
|
+
callbackPath: loginParams.callbackPath,
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
} catch (exception) {
|
|
226
|
+
if (timeoutId) {
|
|
227
|
+
clearTimeout(timeoutId);
|
|
228
|
+
oidc.timeoutId = null;
|
|
229
|
+
oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
230
|
+
console.error(exception);
|
|
231
|
+
reject(exception);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
authorizationHandler.completeAuthorizationRequestIfPossible();
|
|
236
|
+
});
|
|
237
|
+
} catch (exception) {
|
|
238
|
+
console.error(exception);
|
|
239
|
+
oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
240
|
+
throw exception;
|
|
241
|
+
}
|
|
242
|
+
};
|