@axa-fr/react-oidc 6.13.4 → 6.14.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/OidcServiceWorker.js +36 -9
- package/dist/vanilla/crypto.d.ts +4 -0
- package/dist/vanilla/crypto.d.ts.map +1 -0
- package/dist/vanilla/crypto.js +81 -0
- package/dist/vanilla/crypto.js.map +1 -0
- package/dist/vanilla/initSession.d.ts +6 -4
- package/dist/vanilla/initSession.d.ts.map +1 -1
- package/dist/vanilla/initSession.js +22 -15
- package/dist/vanilla/initSession.js.map +1 -1
- package/dist/vanilla/initWorker.d.ts +4 -2
- package/dist/vanilla/initWorker.d.ts.map +1 -1
- package/dist/vanilla/initWorker.js +39 -18
- package/dist/vanilla/initWorker.js.map +1 -1
- package/dist/vanilla/login.d.ts +5 -1
- package/dist/vanilla/login.d.ts.map +1 -1
- package/dist/vanilla/login.js +70 -143
- package/dist/vanilla/login.js.map +1 -1
- package/dist/vanilla/logout.d.ts +4 -0
- package/dist/vanilla/logout.d.ts.map +1 -0
- package/dist/vanilla/logout.js +113 -0
- package/dist/vanilla/logout.js.map +1 -0
- package/dist/vanilla/oidc.d.ts +11 -6
- package/dist/vanilla/oidc.d.ts.map +1 -1
- package/dist/vanilla/oidc.js +26 -94
- package/dist/vanilla/oidc.js.map +1 -1
- package/dist/vanilla/requests.d.ts +14 -0
- package/dist/vanilla/requests.d.ts.map +1 -1
- package/dist/vanilla/requests.js +56 -1
- package/dist/vanilla/requests.js.map +1 -1
- package/dist/vanilla/route-utils.js +2 -2
- package/dist/vanilla/route-utils.js.map +1 -1
- package/package.json +2 -2
- package/src/oidc/vanilla/OidcServiceWorker.js +36 -9
- package/src/oidc/vanilla/crypto.ts +57 -0
- package/src/oidc/vanilla/initSession.ts +25 -15
- package/src/oidc/vanilla/initWorker.ts +43 -18
- package/src/oidc/vanilla/login.ts +76 -148
- package/src/oidc/vanilla/logout.ts +95 -0
- package/src/oidc/vanilla/oidc.ts +35 -98
- package/src/oidc/vanilla/requests.spec.ts +4 -0
- package/src/oidc/vanilla/requests.ts +55 -0
- package/src/oidc/vanilla/route-utils.ts +2 -2
- package/dist/vanilla/memoryStorageBackend.d.ts +0 -11
- package/dist/vanilla/memoryStorageBackend.d.ts.map +0 -1
- package/dist/vanilla/memoryStorageBackend.js +0 -31
- package/dist/vanilla/memoryStorageBackend.js.map +0 -1
- package/dist/vanilla/noHashQueryStringUtils.d.ts +0 -8
- package/dist/vanilla/noHashQueryStringUtils.d.ts.map +0 -1
- package/dist/vanilla/noHashQueryStringUtils.js +0 -32
- package/dist/vanilla/noHashQueryStringUtils.js.map +0 -1
- package/src/oidc/vanilla/memoryStorageBackend.ts +0 -40
- package/src/oidc/vanilla/noHashQueryStringUtils.ts +0 -32
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
export const initSession = (configurationName, storage = sessionStorage) => {
|
|
2
|
-
const saveItemsAsync = (items) => {
|
|
3
|
-
storage[`oidc.items.${configurationName}`] = JSON.stringify(items);
|
|
4
|
-
return Promise.resolve();
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
const loadItemsAsync = () => {
|
|
8
|
-
return Promise.resolve(JSON.parse(storage[`oidc.items.${configurationName}`]));
|
|
9
|
-
};
|
|
10
1
|
|
|
2
|
+
export const initSession = (configurationName, storage = sessionStorage) => {
|
|
11
3
|
const clearAsync = (status) => {
|
|
12
4
|
storage[`oidc.${configurationName}`] = JSON.stringify({ tokens: null, status });
|
|
13
5
|
return Promise.resolve();
|
|
@@ -26,11 +18,11 @@ export const initSession = (configurationName, storage = sessionStorage) => {
|
|
|
26
18
|
storage[`oidc.${configurationName}`] = JSON.stringify({ tokens });
|
|
27
19
|
};
|
|
28
20
|
|
|
29
|
-
const
|
|
21
|
+
const setSessionStateAsync = async (sessionState) => {
|
|
30
22
|
storage[`oidc.session_state.${configurationName}`] = sessionState;
|
|
31
23
|
};
|
|
32
24
|
|
|
33
|
-
const
|
|
25
|
+
const getSessionStateAsync = async () => {
|
|
34
26
|
return storage[`oidc.session_state.${configurationName}`];
|
|
35
27
|
};
|
|
36
28
|
|
|
@@ -63,18 +55,36 @@ export const initSession = (configurationName, storage = sessionStorage) => {
|
|
|
63
55
|
return getLoginParamsCache;
|
|
64
56
|
};
|
|
65
57
|
|
|
58
|
+
const getStateAsync = async () => {
|
|
59
|
+
return storage[`oidc.state.${configurationName}`];
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const setStateAsync = async (state) => {
|
|
63
|
+
storage[`oidc.state.${configurationName}`] = state;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const getCodeVerifierAsync = async () => {
|
|
67
|
+
return storage[`oidc.code_verifier.${configurationName}`];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const setCodeVerifierAsync = async (codeVerifier) => {
|
|
71
|
+
storage[`oidc.code_verifier.${configurationName}`] = codeVerifier;
|
|
72
|
+
};
|
|
73
|
+
|
|
66
74
|
return {
|
|
67
|
-
saveItemsAsync,
|
|
68
|
-
loadItemsAsync,
|
|
69
75
|
clearAsync,
|
|
70
76
|
initAsync,
|
|
71
77
|
setTokens,
|
|
72
78
|
getTokens,
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
setSessionStateAsync,
|
|
80
|
+
getSessionStateAsync,
|
|
75
81
|
setNonceAsync,
|
|
76
82
|
getNonceAsync,
|
|
77
83
|
setLoginParams,
|
|
78
84
|
getLoginParams,
|
|
85
|
+
getStateAsync,
|
|
86
|
+
setStateAsync,
|
|
87
|
+
getCodeVerifierAsync,
|
|
88
|
+
setCodeVerifierAsync,
|
|
79
89
|
};
|
|
80
90
|
};
|
|
@@ -189,22 +189,6 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
189
189
|
});
|
|
190
190
|
});
|
|
191
191
|
|
|
192
|
-
const saveItemsAsync = (items) => {
|
|
193
|
-
// iOS kill Service Worker when domain we leave domain
|
|
194
|
-
if (operatingSystem.os === 'iOS') {
|
|
195
|
-
const session = initSession(configurationName);
|
|
196
|
-
return session.saveItemsAsync(items);
|
|
197
|
-
}
|
|
198
|
-
return sendMessageAsync(registration)({ type: 'saveItems', data: items, configurationName });
|
|
199
|
-
};
|
|
200
|
-
const loadItemsAsync = () => {
|
|
201
|
-
// iOS kill Service Worker when domain we leave domain
|
|
202
|
-
if (operatingSystem.os === 'iOS') {
|
|
203
|
-
const session = initSession(configurationName);
|
|
204
|
-
return session.loadItemsAsync();
|
|
205
|
-
}
|
|
206
|
-
return sendMessageAsync(registration)({ type: 'loadItems', data: null, configurationName });
|
|
207
|
-
};
|
|
208
192
|
const clearAsync = async (status) => {
|
|
209
193
|
// iOS kill Service Worker when domain we leave domain
|
|
210
194
|
if (operatingSystem.os === 'iOS') {
|
|
@@ -274,9 +258,46 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
274
258
|
return getLoginParamsCache;
|
|
275
259
|
};
|
|
276
260
|
|
|
261
|
+
const getStateAsync = async () => {
|
|
262
|
+
// iOS kill Service Worker when domain we leave domain
|
|
263
|
+
if (operatingSystem.os === 'iOS') {
|
|
264
|
+
const session = initSession(configurationName);
|
|
265
|
+
return session.getStateAsync();
|
|
266
|
+
}
|
|
267
|
+
const result = await sendMessageAsync(registration)({ type: 'getState', data: null, configurationName });
|
|
268
|
+
// @ts-ignore
|
|
269
|
+
return result.state;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const setStateAsync = async (state) => {
|
|
273
|
+
// iOS kill Service Worker when domain we leave domain
|
|
274
|
+
if (operatingSystem.os === 'iOS') {
|
|
275
|
+
const session = initSession(configurationName);
|
|
276
|
+
return session.setStateAsync(state);
|
|
277
|
+
}
|
|
278
|
+
return sendMessageAsync(registration)({ type: 'setState', data: { state }, configurationName });
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
const getCodeVerifierAsync = async () => {
|
|
282
|
+
// iOS kill Service Worker when domain we leave domain
|
|
283
|
+
if (operatingSystem.os === 'iOS') {
|
|
284
|
+
const session = initSession(configurationName);
|
|
285
|
+
return session.getCodeVerifierAsync();
|
|
286
|
+
}
|
|
287
|
+
const result = await sendMessageAsync(registration)({ type: 'getCodeVerifier', data: null, configurationName });
|
|
288
|
+
// @ts-ignore
|
|
289
|
+
return result.codeVerifier;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const setCodeVerifierAsync = async (codeVerifier) => {
|
|
293
|
+
if (operatingSystem.os === 'iOS') {
|
|
294
|
+
const session = initSession(configurationName);
|
|
295
|
+
return session.setCodeVerifierAsync(codeVerifier);
|
|
296
|
+
}
|
|
297
|
+
return sendMessageAsync(registration)({ type: 'setCodeVerifier', data: { codeVerifier }, configurationName });
|
|
298
|
+
};
|
|
299
|
+
|
|
277
300
|
return {
|
|
278
|
-
saveItemsAsync,
|
|
279
|
-
loadItemsAsync,
|
|
280
301
|
clearAsync,
|
|
281
302
|
initAsync,
|
|
282
303
|
startKeepAliveServiceWorker,
|
|
@@ -288,5 +309,9 @@ export const initWorkerAsync = async(serviceWorkerRelativeUrl, configurationName
|
|
|
288
309
|
unregisterAsync,
|
|
289
310
|
setLoginParams,
|
|
290
311
|
getLoginParams,
|
|
312
|
+
getStateAsync,
|
|
313
|
+
setStateAsync,
|
|
314
|
+
getCodeVerifierAsync,
|
|
315
|
+
setCodeVerifierAsync,
|
|
291
316
|
};
|
|
292
317
|
};
|
|
@@ -1,29 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AuthorizationNotifier,
|
|
3
|
-
AuthorizationRequest, BaseTokenRequestHandler,
|
|
4
|
-
DefaultCrypto, FetchRequestor, GRANT_TYPE_AUTHORIZATION_CODE,
|
|
5
|
-
RedirectRequestHandler,
|
|
6
|
-
TokenRequest,
|
|
7
|
-
} from '@openid/appauth';
|
|
8
|
-
|
|
1
|
+
import { generateRandom } from './crypto';
|
|
9
2
|
import { eventNames } from './events';
|
|
10
3
|
import { initSession } from './initSession';
|
|
11
4
|
import { initWorkerAsync } from './initWorker';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { isTokensOidcValid, setTokens } from './parseTokens';
|
|
5
|
+
import { isTokensOidcValid } from './parseTokens';
|
|
6
|
+
import { performAuthorizationRequestAsync, performFirstTokenRequestAsync } from './requests';
|
|
15
7
|
import { getParseQueryStringFromLocation } from './route-utils';
|
|
16
8
|
import { OidcConfiguration, StringMap } from './types';
|
|
17
9
|
|
|
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
10
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
28
11
|
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
12
|
const originExtras = extras;
|
|
@@ -31,10 +14,9 @@ export const defaultLoginAsync = (window, configurationName, configuration:OidcC
|
|
|
31
14
|
const loginLocalAsync = async () => {
|
|
32
15
|
const location = window.location;
|
|
33
16
|
const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
state =
|
|
37
|
-
delete extras.state;
|
|
17
|
+
|
|
18
|
+
if (!('state' in extras)) {
|
|
19
|
+
extras.state = generateRandom(16);
|
|
38
20
|
}
|
|
39
21
|
|
|
40
22
|
publishEvent(eventNames.loginAsync_begin, {});
|
|
@@ -53,38 +35,34 @@ export const defaultLoginAsync = (window, configurationName, configuration:OidcC
|
|
|
53
35
|
|
|
54
36
|
const extraFinal = !configuration.extras ? extras : { ...configuration.extras, ...extras };
|
|
55
37
|
if (!extraFinal.nonce) {
|
|
56
|
-
extraFinal.nonce =
|
|
38
|
+
extraFinal.nonce = generateRandom(12);
|
|
57
39
|
}
|
|
58
40
|
const nonce = { nonce: extraFinal.nonce };
|
|
59
41
|
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, configurationName);
|
|
60
42
|
const oidcServerConfiguration = await initAsync(configuration.authority, configuration.authority_configuration);
|
|
61
43
|
let storage;
|
|
62
44
|
if (serviceWorker) {
|
|
63
|
-
serviceWorker.setLoginParams(configurationName, { callbackPath: url, extras: originExtras
|
|
45
|
+
serviceWorker.setLoginParams(configurationName, { callbackPath: url, extras: originExtras });
|
|
64
46
|
serviceWorker.startKeepAliveServiceWorker();
|
|
65
47
|
await serviceWorker.initAsync(oidcServerConfiguration, 'loginAsync', configuration);
|
|
66
48
|
await serviceWorker.setNonceAsync(nonce);
|
|
67
|
-
storage =
|
|
68
|
-
await storage.setItem('dummy', {});
|
|
49
|
+
storage = serviceWorker;
|
|
69
50
|
} else {
|
|
70
51
|
const session = initSession(configurationName, configuration.storage ?? sessionStorage);
|
|
71
|
-
session.setLoginParams(configurationName, { callbackPath: url, extras: originExtras
|
|
52
|
+
session.setLoginParams(configurationName, { callbackPath: url, extras: originExtras });
|
|
72
53
|
await session.setNonceAsync(nonce);
|
|
73
|
-
storage =
|
|
54
|
+
storage = session;
|
|
74
55
|
}
|
|
75
56
|
|
|
76
57
|
// @ts-ignore
|
|
77
|
-
const
|
|
78
|
-
const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
|
|
79
|
-
const authRequest = new AuthorizationRequest({
|
|
58
|
+
const extraInternal = {
|
|
80
59
|
client_id: configuration.client_id,
|
|
81
60
|
redirect_uri: redirectUri,
|
|
82
61
|
scope,
|
|
83
|
-
response_type:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
authorizationHandler.performAuthorizationRequest(oidcServerConfiguration, authRequest);
|
|
62
|
+
response_type: 'code',
|
|
63
|
+
...extraFinal,
|
|
64
|
+
};
|
|
65
|
+
await performAuthorizationRequestAsync(storage)(oidcServerConfiguration.authorizationEndpoint, extraInternal);
|
|
88
66
|
} catch (exception) {
|
|
89
67
|
publishEvent(eventNames.loginAsync_error, exception);
|
|
90
68
|
throw exception;
|
|
@@ -105,134 +83,84 @@ export const loginCallbackAsync = (oidc) => async (isSilentSignin = false) => {
|
|
|
105
83
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
106
84
|
const sessionState = queryParams.session_state;
|
|
107
85
|
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, oidc.configurationName);
|
|
108
|
-
let storage
|
|
109
|
-
let nonceData
|
|
110
|
-
let getLoginParams
|
|
86
|
+
let storage;
|
|
87
|
+
let nonceData;
|
|
88
|
+
let getLoginParams;
|
|
89
|
+
let state;
|
|
111
90
|
if (serviceWorker) {
|
|
112
91
|
serviceWorker.startKeepAliveServiceWorker();
|
|
113
92
|
await serviceWorker.initAsync(oidcServerConfiguration, 'loginCallbackAsync', configuration);
|
|
114
|
-
const items = await serviceWorker.loadItemsAsync();
|
|
115
|
-
storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, items);
|
|
116
|
-
const dummy = await storage.getItem('dummy');
|
|
117
|
-
if (!dummy) {
|
|
118
|
-
throw new Error('Service Worker storage disapear');
|
|
119
|
-
}
|
|
120
|
-
await storage.removeItem('dummy');
|
|
121
93
|
await serviceWorker.setSessionStateAsync(sessionState);
|
|
122
94
|
nonceData = await serviceWorker.getNonceAsync();
|
|
123
95
|
getLoginParams = serviceWorker.getLoginParams(oidc.configurationName);
|
|
96
|
+
state = await serviceWorker.getStateAsync();
|
|
97
|
+
storage = serviceWorker;
|
|
124
98
|
} else {
|
|
125
99
|
const session = initSession(oidc.configurationName, configuration.storage ?? sessionStorage);
|
|
126
|
-
session.
|
|
127
|
-
const items = await session.loadItemsAsync();
|
|
128
|
-
storage = new MemoryStorageBackend(session.saveItemsAsync, items);
|
|
100
|
+
await session.setSessionStateAsync(sessionState);
|
|
129
101
|
nonceData = await session.getNonceAsync();
|
|
130
102
|
getLoginParams = session.getLoginParams(oidc.configurationName);
|
|
103
|
+
state = await session.getStateAsync();
|
|
104
|
+
storage = session;
|
|
131
105
|
}
|
|
132
106
|
|
|
133
|
-
|
|
134
|
-
let queryStringUtil = new NoHashQueryStringUtils();
|
|
135
|
-
if (redirectUri.includes('#')) {
|
|
136
|
-
const splithash = window.location.href.split('#');
|
|
137
|
-
if (splithash.length === 2 && splithash[1].includes('?')) {
|
|
138
|
-
queryStringUtil = new HashQueryStringUtils();
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
|
|
142
|
-
const notifier = new AuthorizationNotifier();
|
|
143
|
-
authorizationHandler.setAuthorizationNotifier(notifier);
|
|
107
|
+
const params = getParseQueryStringFromLocation(window.location.toString());
|
|
144
108
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
109
|
+
if (params.iss && params.iss !== oidcServerConfiguration.issuer) {
|
|
110
|
+
throw new Error('issuer not valid');
|
|
111
|
+
}
|
|
112
|
+
if (params.state && params.state !== state) {
|
|
113
|
+
throw new Error('state not valid');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const data = {
|
|
117
|
+
code: params.code,
|
|
118
|
+
grant_type: 'authorization_code',
|
|
119
|
+
client_id: configuration.client_id,
|
|
120
|
+
redirect_uri: redirectUri,
|
|
121
|
+
};
|
|
154
122
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (key.endsWith(':token_request')) {
|
|
167
|
-
extras[key.replace(':token_request', '')] = value;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
123
|
+
const extras = {};
|
|
124
|
+
// @ts-ignore
|
|
125
|
+
if (configuration.token_request_extras) {
|
|
126
|
+
for (const [key, value] of Object.entries(configuration.token_request_extras)) {
|
|
127
|
+
extras[key] = value;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (getLoginParams && getLoginParams.extras) {
|
|
131
|
+
for (const [key, value] of Object.entries(getLoginParams.extras)) {
|
|
132
|
+
if (key.endsWith(':token_request')) {
|
|
133
|
+
extras[key.replace(':token_request', '')] = value;
|
|
171
134
|
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
172
137
|
|
|
173
|
-
|
|
174
|
-
client_id: clientId,
|
|
175
|
-
redirect_uri: redirectUri, // @ts-ignore
|
|
176
|
-
grant_type: GRANT_TYPE_AUTHORIZATION_CODE,
|
|
177
|
-
code: response.code,
|
|
178
|
-
refresh_token: undefined,
|
|
179
|
-
extras,
|
|
180
|
-
});
|
|
138
|
+
const tokenResponse = await performFirstTokenRequestAsync(storage)(oidcServerConfiguration.tokenEndpoint, { ...data, ...extras }, oidc.configuration.token_renew_mode, tokenRequestTimeout);
|
|
181
139
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
} else {
|
|
199
|
-
const session = initSession(oidc.configurationName, configuration.storage);
|
|
200
|
-
loginParams = session.getLoginParams(oidc.configurationName);
|
|
201
|
-
formattedTokens = setTokens(tokenResponse, null, configuration.token_renew_mode);
|
|
202
|
-
}
|
|
203
|
-
if (!isTokensOidcValid(formattedTokens, nonceData.nonce, oidcServerConfiguration)) {
|
|
204
|
-
const exception = new Error('Tokens are not OpenID valid');
|
|
205
|
-
if (timeoutId) {
|
|
206
|
-
clearTimeout(timeoutId);
|
|
207
|
-
oidc.timeoutId = null;
|
|
208
|
-
oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
209
|
-
console.error(exception);
|
|
210
|
-
reject(exception);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
140
|
+
let loginParams = null;
|
|
141
|
+
const formattedTokens = tokenResponse.data.tokens;
|
|
142
|
+
if (serviceWorker) {
|
|
143
|
+
await serviceWorker.initAsync(redirectUri, 'syncTokensAsync', configuration);
|
|
144
|
+
loginParams = serviceWorker.getLoginParams(oidc.configurationName);
|
|
145
|
+
} else {
|
|
146
|
+
const session = initSession(oidc.configurationName, configuration.storage);
|
|
147
|
+
loginParams = session.getLoginParams(oidc.configurationName);
|
|
148
|
+
}
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
if (tokenResponse.data.state !== extras.state) {
|
|
151
|
+
throw new Error('state is not valid');
|
|
152
|
+
}
|
|
153
|
+
if (!isTokensOidcValid(formattedTokens, nonceData.nonce, oidcServerConfiguration)) {
|
|
154
|
+
throw new Error('Tokens are not OpenID valid');
|
|
155
|
+
}
|
|
213
156
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
} catch (exception) {
|
|
225
|
-
if (timeoutId) {
|
|
226
|
-
clearTimeout(timeoutId);
|
|
227
|
-
oidc.timeoutId = null;
|
|
228
|
-
oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
229
|
-
console.error(exception);
|
|
230
|
-
reject(exception);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
authorizationHandler.completeAuthorizationRequestIfPossible();
|
|
235
|
-
});
|
|
157
|
+
await oidc.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, clientId, sessionState, isSilentSignin);
|
|
158
|
+
oidc.publishEvent(eventNames.loginCallbackAsync_end, {});
|
|
159
|
+
return {
|
|
160
|
+
tokens: formattedTokens,
|
|
161
|
+
state: 'request.state',
|
|
162
|
+
callbackPath: loginParams.callbackPath,
|
|
163
|
+
};
|
|
236
164
|
} catch (exception) {
|
|
237
165
|
console.error(exception);
|
|
238
166
|
oidc.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { initSession } from './initSession';
|
|
2
|
+
import { initWorkerAsync } from './initWorker';
|
|
3
|
+
import { performRevocationRequestAsync, TOKEN_TYPE } from './requests';
|
|
4
|
+
import timer from './timer';
|
|
5
|
+
import { StringMap } from './types';
|
|
6
|
+
|
|
7
|
+
export const destroyAsync = (oidc) => async (status) => {
|
|
8
|
+
timer.clearTimeout(oidc.timeoutId);
|
|
9
|
+
oidc.timeoutId = null;
|
|
10
|
+
if (oidc.checkSessionIFrame) {
|
|
11
|
+
oidc.checkSessionIFrame.stop();
|
|
12
|
+
}
|
|
13
|
+
const serviceWorker = await initWorkerAsync(oidc.configuration.service_worker_relative_url, oidc.configurationName);
|
|
14
|
+
if (!serviceWorker) {
|
|
15
|
+
const session = initSession(oidc.configurationName, oidc.configuration.storage);
|
|
16
|
+
await session.clearAsync(status);
|
|
17
|
+
} else {
|
|
18
|
+
await serviceWorker.clearAsync(status);
|
|
19
|
+
}
|
|
20
|
+
oidc.tokens = null;
|
|
21
|
+
oidc.userInfo = null;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const logoutAsync = (oidc, oidcDatabase) => async (callbackPathOrUrl: string | null | undefined = undefined, extras: StringMap = null) => {
|
|
25
|
+
const configuration = oidc.configuration;
|
|
26
|
+
const oidcServerConfiguration = await oidc.initAsync(configuration.authority, configuration.authority_configuration);
|
|
27
|
+
if (callbackPathOrUrl && (typeof callbackPathOrUrl !== 'string')) {
|
|
28
|
+
callbackPathOrUrl = undefined;
|
|
29
|
+
console.warn('callbackPathOrUrl path is not a string');
|
|
30
|
+
}
|
|
31
|
+
const path = (callbackPathOrUrl === null || callbackPathOrUrl === undefined) ? location.pathname + (location.search || '') + (location.hash || '') : callbackPathOrUrl;
|
|
32
|
+
let isUri = false;
|
|
33
|
+
if (callbackPathOrUrl) {
|
|
34
|
+
isUri = callbackPathOrUrl.includes('https://') || callbackPathOrUrl.includes('http://');
|
|
35
|
+
}
|
|
36
|
+
const url = isUri ? callbackPathOrUrl : window.location.origin + path;
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
const idToken = oidc.tokens ? oidc.tokens.idToken : '';
|
|
39
|
+
try {
|
|
40
|
+
const revocationEndpoint = oidcServerConfiguration.revocationEndpoint;
|
|
41
|
+
if (revocationEndpoint) {
|
|
42
|
+
const promises = [];
|
|
43
|
+
const accessToken = oidc.tokens.accessToken;
|
|
44
|
+
if (accessToken) {
|
|
45
|
+
const revokeAccessTokenPromise = performRevocationRequestAsync(revocationEndpoint, accessToken, TOKEN_TYPE.access_token, configuration.client_id);
|
|
46
|
+
promises.push(revokeAccessTokenPromise);
|
|
47
|
+
}
|
|
48
|
+
const refreshToken = oidc.tokens.refreshToken;
|
|
49
|
+
if (refreshToken) {
|
|
50
|
+
const revokeRefreshTokenPromise = performRevocationRequestAsync(revocationEndpoint, refreshToken, TOKEN_TYPE.refresh_token, configuration.client_id);
|
|
51
|
+
promises.push(revokeRefreshTokenPromise);
|
|
52
|
+
}
|
|
53
|
+
if (promises.length > 0) {
|
|
54
|
+
await Promise.all(promises);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch (exception) {
|
|
58
|
+
console.warn(exception);
|
|
59
|
+
}
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
const sub = oidc.tokens && oidc.tokens.idTokenPayload ? oidc.tokens.idTokenPayload.sub : null;
|
|
62
|
+
await oidc.destroyAsync('LOGGED_OUT');
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
64
|
+
for (const [key, itemOidc] of Object.entries(oidcDatabase)) {
|
|
65
|
+
if (itemOidc !== oidc) {
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
await oidc.logoutSameTabAsync(oidc.configuration.client_id, sub);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (oidcServerConfiguration.endSessionEndpoint) {
|
|
72
|
+
if (!extras) {
|
|
73
|
+
extras = {
|
|
74
|
+
id_token_hint: idToken,
|
|
75
|
+
};
|
|
76
|
+
if (callbackPathOrUrl !== null) {
|
|
77
|
+
extras.post_logout_redirect_uri = url;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
let queryString = '';
|
|
81
|
+
if (extras) {
|
|
82
|
+
for (const [key, value] of Object.entries(extras)) {
|
|
83
|
+
if (queryString === '') {
|
|
84
|
+
queryString += '?';
|
|
85
|
+
} else {
|
|
86
|
+
queryString += '&';
|
|
87
|
+
}
|
|
88
|
+
queryString += `${key}=${encodeURIComponent(value)}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
window.location.href = `${oidcServerConfiguration.endSessionEndpoint}${queryString}`;
|
|
92
|
+
} else {
|
|
93
|
+
window.location.reload();
|
|
94
|
+
}
|
|
95
|
+
};
|