@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/oidc.ts
CHANGED
|
@@ -1,401 +1,490 @@
|
|
|
1
|
-
import {startCheckSessionAsync as defaultStartCheckSessionAsync} from './checkSession.js';
|
|
2
|
-
import {CheckSessionIFrame} from './checkSessionIFrame.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {TokenRenewMode, Tokens,} from './parseTokens.js';
|
|
1
|
+
import { startCheckSessionAsync as defaultStartCheckSessionAsync } from './checkSession.js';
|
|
2
|
+
import { CheckSessionIFrame } from './checkSessionIFrame.js';
|
|
3
|
+
import { base64urlOfHashOfASCIIEncodingAsync } from './crypto';
|
|
4
|
+
import { eventNames } from './events.js';
|
|
5
|
+
import { initSession } from './initSession.js';
|
|
6
|
+
import { defaultServiceWorkerUpdateRequireCallback, initWorkerAsync } from './initWorker.js';
|
|
7
|
+
import { activateServiceWorker } from './initWorkerOption';
|
|
9
8
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from './
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
9
|
+
defaultDemonstratingProofOfPossessionConfiguration,
|
|
10
|
+
generateJwtDemonstratingProofOfPossessionAsync,
|
|
11
|
+
} from './jwt';
|
|
12
|
+
import { tryKeepSessionAsync } from './keepSession';
|
|
13
|
+
import { ILOidcLocation, OidcLocation } from './location';
|
|
14
|
+
import { defaultLoginAsync, loginCallbackAsync } from './login.js';
|
|
15
|
+
import { destroyAsync, logoutAsync } from './logout.js';
|
|
16
|
+
import { TokenRenewMode, Tokens } from './parseTokens.js';
|
|
17
|
+
import { autoRenewTokens, renewTokensAndStartTimerAsync } from './renewTokens.js';
|
|
18
|
+
import { fetchFromIssuer } from './requests.js';
|
|
19
|
+
import { getParseQueryStringFromLocation } from './route-utils.js';
|
|
15
20
|
import defaultSilentLoginAsync from './silentLogin.js';
|
|
16
21
|
import timer from './timer.js';
|
|
17
|
-
import {AuthorityConfiguration, Fetch, OidcConfiguration, StringMap, TokenAutomaticRenewMode} from './types.js';
|
|
18
|
-
import {userInfoAsync} from './user.js';
|
|
19
|
-
import {base64urlOfHashOfASCIIEncodingAsync} from "./crypto";
|
|
20
22
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
AuthorityConfiguration,
|
|
24
|
+
Fetch,
|
|
25
|
+
OidcConfiguration,
|
|
26
|
+
StringMap,
|
|
27
|
+
TokenAutomaticRenewMode,
|
|
28
|
+
} from './types.js';
|
|
29
|
+
import { userInfoAsync } from './user.js';
|
|
29
30
|
|
|
30
31
|
export const getFetchDefault = () => {
|
|
31
|
-
|
|
32
|
+
return fetch;
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
export interface OidcAuthorizationServiceConfigurationJson {
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
check_session_iframe?: string;
|
|
37
|
+
issuer: string;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
40
|
export class OidcAuthorizationServiceConfiguration {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
41
|
+
private checkSessionIframe: string;
|
|
42
|
+
private issuer: string;
|
|
43
|
+
private authorizationEndpoint: string;
|
|
44
|
+
private tokenEndpoint: string;
|
|
45
|
+
private revocationEndpoint: string;
|
|
46
|
+
private userInfoEndpoint: string;
|
|
47
|
+
private endSessionEndpoint: string;
|
|
48
|
+
|
|
49
|
+
constructor(request: any) {
|
|
50
|
+
this.authorizationEndpoint = request.authorization_endpoint;
|
|
51
|
+
this.tokenEndpoint = request.token_endpoint;
|
|
52
|
+
this.revocationEndpoint = request.revocation_endpoint;
|
|
53
|
+
this.userInfoEndpoint = request.userinfo_endpoint;
|
|
54
|
+
this.checkSessionIframe = request.check_session_iframe;
|
|
55
|
+
this.issuer = request.issuer;
|
|
56
|
+
this.endSessionEndpoint = request.end_session_endpoint;
|
|
57
|
+
}
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
const oidcDatabase = {};
|
|
62
|
-
const oidcFactory =
|
|
61
|
+
const oidcFactory =
|
|
62
|
+
(getFetch: () => Fetch, location: ILOidcLocation = new OidcLocation()) =>
|
|
63
|
+
(configuration: OidcConfiguration, name = 'default') => {
|
|
63
64
|
if (oidcDatabase[name]) {
|
|
64
|
-
|
|
65
|
+
return oidcDatabase[name];
|
|
65
66
|
}
|
|
66
67
|
oidcDatabase[name] = new Oidc(configuration, name, getFetch, location);
|
|
67
68
|
return oidcDatabase[name];
|
|
68
|
-
};
|
|
69
|
+
};
|
|
69
70
|
export type LoginCallback = {
|
|
70
|
-
|
|
71
|
-
}
|
|
71
|
+
callbackPath: string;
|
|
72
|
+
};
|
|
72
73
|
|
|
73
74
|
export type InternalLoginCallback = {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
75
|
+
callbackPath: string;
|
|
76
|
+
parsedTokens: Tokens;
|
|
77
|
+
};
|
|
77
78
|
|
|
78
|
-
const loginCallbackWithAutoTokensRenewAsync = async (oidc)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
const loginCallbackWithAutoTokensRenewAsync = async (oidc): Promise<LoginCallback> => {
|
|
80
|
+
const { parsedTokens, callbackPath } = await oidc.loginCallbackAsync();
|
|
81
|
+
oidc.timeoutId = autoRenewTokens(oidc, parsedTokens.expiresAt);
|
|
82
|
+
return { callbackPath };
|
|
82
83
|
};
|
|
83
84
|
|
|
84
|
-
const getRandomInt =
|
|
85
|
-
|
|
85
|
+
const getRandomInt = max => {
|
|
86
|
+
return Math.floor(Math.random() * max);
|
|
86
87
|
};
|
|
87
88
|
|
|
88
89
|
export class Oidc {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
90
|
+
public configuration: OidcConfiguration;
|
|
91
|
+
public userInfo: null;
|
|
92
|
+
public tokens?: Tokens;
|
|
93
|
+
public events: Array<any>;
|
|
94
|
+
public timeoutId: NodeJS.Timeout | number;
|
|
95
|
+
public configurationName: string;
|
|
96
|
+
public checkSessionIFrame: CheckSessionIFrame;
|
|
97
|
+
public getFetch: () => Fetch;
|
|
98
|
+
public location: ILOidcLocation;
|
|
99
|
+
constructor(
|
|
100
|
+
configuration: OidcConfiguration,
|
|
101
|
+
configurationName = 'default',
|
|
102
|
+
getFetch: () => Fetch,
|
|
103
|
+
location: ILOidcLocation = new OidcLocation(),
|
|
104
|
+
) {
|
|
105
|
+
let silent_login_uri = configuration.silent_login_uri;
|
|
106
|
+
if (configuration.silent_redirect_uri && !configuration.silent_login_uri) {
|
|
107
|
+
silent_login_uri = `${configuration.silent_redirect_uri.replace('-callback', '').replace('callback', '')}-login`;
|
|
108
|
+
}
|
|
109
|
+
let refresh_time_before_tokens_expiration_in_second =
|
|
110
|
+
configuration.refresh_time_before_tokens_expiration_in_second ?? 120;
|
|
111
|
+
if (refresh_time_before_tokens_expiration_in_second > 60) {
|
|
112
|
+
refresh_time_before_tokens_expiration_in_second =
|
|
113
|
+
refresh_time_before_tokens_expiration_in_second - Math.floor(Math.random() * 40);
|
|
114
|
+
}
|
|
115
|
+
this.location = location ?? new OidcLocation();
|
|
116
|
+
const service_worker_update_require_callback =
|
|
117
|
+
configuration.service_worker_update_require_callback ??
|
|
118
|
+
defaultServiceWorkerUpdateRequireCallback(this.location);
|
|
119
|
+
|
|
120
|
+
this.configuration = {
|
|
121
|
+
...configuration,
|
|
122
|
+
silent_login_uri,
|
|
123
|
+
token_automatic_renew_mode:
|
|
124
|
+
configuration.token_automatic_renew_mode ??
|
|
125
|
+
TokenAutomaticRenewMode.AutomaticBeforeTokenExpiration,
|
|
126
|
+
monitor_session: configuration.monitor_session ?? false,
|
|
127
|
+
refresh_time_before_tokens_expiration_in_second,
|
|
128
|
+
silent_login_timeout: configuration.silent_login_timeout ?? 12000,
|
|
129
|
+
token_renew_mode:
|
|
130
|
+
configuration.token_renew_mode ?? TokenRenewMode.access_token_or_id_token_invalid,
|
|
131
|
+
demonstrating_proof_of_possession: configuration.demonstrating_proof_of_possession ?? false,
|
|
132
|
+
authority_timeout_wellknowurl_in_millisecond:
|
|
133
|
+
configuration.authority_timeout_wellknowurl_in_millisecond ?? 10000,
|
|
134
|
+
logout_tokens_to_invalidate: configuration.logout_tokens_to_invalidate ?? [
|
|
135
|
+
'access_token',
|
|
136
|
+
'refresh_token',
|
|
137
|
+
],
|
|
138
|
+
service_worker_update_require_callback,
|
|
139
|
+
service_worker_activate: configuration.service_worker_activate ?? activateServiceWorker,
|
|
140
|
+
demonstrating_proof_of_possession_configuration:
|
|
141
|
+
configuration.demonstrating_proof_of_possession_configuration ??
|
|
142
|
+
defaultDemonstratingProofOfPossessionConfiguration,
|
|
143
|
+
preload_user_info: configuration.preload_user_info ?? false,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
this.getFetch = getFetch ?? getFetchDefault;
|
|
147
|
+
this.configurationName = configurationName;
|
|
148
|
+
this.tokens = null;
|
|
149
|
+
this.userInfo = null;
|
|
150
|
+
this.events = [];
|
|
151
|
+
this.timeoutId = null;
|
|
152
|
+
this.loginCallbackWithAutoTokensRenewAsync.bind(this);
|
|
153
|
+
this.initAsync.bind(this);
|
|
154
|
+
this.loginCallbackAsync.bind(this);
|
|
155
|
+
this.subscribeEvents.bind(this);
|
|
156
|
+
this.removeEventSubscription.bind(this);
|
|
157
|
+
this.publishEvent.bind(this);
|
|
158
|
+
this.destroyAsync.bind(this);
|
|
159
|
+
this.logoutAsync.bind(this);
|
|
160
|
+
this.renewTokensAsync.bind(this);
|
|
161
|
+
this.initAsync(this.configuration.authority, this.configuration.authority_configuration);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
subscribeEvents(func): string {
|
|
165
|
+
const id = getRandomInt(9999999999999).toString();
|
|
166
|
+
this.events.push({ id, func });
|
|
167
|
+
return id;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
removeEventSubscription(id): void {
|
|
171
|
+
const newEvents = this.events.filter(e => e.id !== id);
|
|
172
|
+
this.events = newEvents;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
publishEvent(eventName, data) {
|
|
176
|
+
this.events.forEach(event => {
|
|
177
|
+
event.func(eventName, data);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static getOrCreate =
|
|
182
|
+
(getFetch: () => Fetch, location: ILOidcLocation) =>
|
|
183
|
+
(configuration, name = 'default') => {
|
|
184
|
+
return oidcFactory(getFetch, location)(configuration, name);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
static get(name = 'default') {
|
|
188
|
+
const isInsideBrowser = typeof process === 'undefined';
|
|
189
|
+
if (!Object.prototype.hasOwnProperty.call(oidcDatabase, name) && isInsideBrowser) {
|
|
190
|
+
throw Error(`OIDC library does seem initialized.
|
|
191
|
+
Please checkout that you are using OIDC hook inside a <OidcProvider configurationName="${name}"></OidcProvider> component.`);
|
|
143
192
|
}
|
|
193
|
+
return oidcDatabase[name];
|
|
194
|
+
}
|
|
144
195
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
196
|
+
static eventNames = eventNames;
|
|
197
|
+
|
|
198
|
+
_silentLoginCallbackFromIFrame() {
|
|
199
|
+
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
200
|
+
const location = this.location;
|
|
201
|
+
const queryParams = getParseQueryStringFromLocation(location.getCurrentHref());
|
|
202
|
+
window.parent.postMessage(
|
|
203
|
+
`${this.configurationName}_oidc_tokens:${JSON.stringify({ tokens: this.tokens, sessionState: queryParams.session_state })}`,
|
|
204
|
+
location.getOrigin(),
|
|
205
|
+
);
|
|
149
206
|
}
|
|
207
|
+
}
|
|
150
208
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
209
|
+
_silentLoginErrorCallbackFromIFrame(exception = null) {
|
|
210
|
+
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
211
|
+
const location = this.location;
|
|
212
|
+
const queryParams = getParseQueryStringFromLocation(location.getCurrentHref());
|
|
213
|
+
if (queryParams.error) {
|
|
214
|
+
window.parent.postMessage(
|
|
215
|
+
`${this.configurationName}_oidc_error:${JSON.stringify({ error: queryParams.error })}`,
|
|
216
|
+
location.getOrigin(),
|
|
217
|
+
);
|
|
218
|
+
} else {
|
|
219
|
+
window.parent.postMessage(
|
|
220
|
+
`${this.configurationName}_oidc_exception:${JSON.stringify({ error: exception == null ? '' : exception.toString() })}`,
|
|
221
|
+
location.getOrigin(),
|
|
222
|
+
);
|
|
223
|
+
}
|
|
154
224
|
}
|
|
225
|
+
}
|
|
155
226
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
227
|
+
async silentLoginCallbackAsync() {
|
|
228
|
+
try {
|
|
229
|
+
await this.loginCallbackAsync(true);
|
|
230
|
+
this._silentLoginCallbackFromIFrame();
|
|
231
|
+
} catch (exception) {
|
|
232
|
+
console.error(exception);
|
|
233
|
+
this._silentLoginErrorCallbackFromIFrame(exception);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
initPromise = null;
|
|
238
|
+
async initAsync(authority: string, authorityConfiguration: AuthorityConfiguration) {
|
|
239
|
+
if (this.initPromise !== null) {
|
|
240
|
+
return this.initPromise;
|
|
160
241
|
}
|
|
242
|
+
const localFuncAsync = async () => {
|
|
243
|
+
if (authorityConfiguration != null) {
|
|
244
|
+
return new OidcAuthorizationServiceConfiguration({
|
|
245
|
+
authorization_endpoint: authorityConfiguration.authorization_endpoint,
|
|
246
|
+
end_session_endpoint: authorityConfiguration.end_session_endpoint,
|
|
247
|
+
revocation_endpoint: authorityConfiguration.revocation_endpoint,
|
|
248
|
+
token_endpoint: authorityConfiguration.token_endpoint,
|
|
249
|
+
userinfo_endpoint: authorityConfiguration.userinfo_endpoint,
|
|
250
|
+
check_session_iframe: authorityConfiguration.check_session_iframe,
|
|
251
|
+
issuer: authorityConfiguration.issuer,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
161
254
|
|
|
162
|
-
|
|
163
|
-
|
|
255
|
+
const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
|
|
256
|
+
const storage = serviceWorker ? window.localStorage : null;
|
|
257
|
+
return await fetchFromIssuer(this.getFetch())(
|
|
258
|
+
authority,
|
|
259
|
+
this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60,
|
|
260
|
+
storage,
|
|
261
|
+
this.configuration.authority_timeout_wellknowurl_in_millisecond,
|
|
262
|
+
);
|
|
164
263
|
};
|
|
264
|
+
this.initPromise = localFuncAsync();
|
|
265
|
+
return this.initPromise.finally(() => {
|
|
266
|
+
// in case if anything went wrong with the promise, we should reset the initPromise to null too
|
|
267
|
+
// otherwise client can't re-init the OIDC client
|
|
268
|
+
// as the promise is already fulfilled with rejected state, so could not ever reach this point again,
|
|
269
|
+
// so that leads to infinite loop of calls, when client tries to re-init the OIDC client after error
|
|
270
|
+
this.initPromise = null;
|
|
271
|
+
});
|
|
272
|
+
}
|
|
165
273
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
Please checkout that you are using OIDC hook inside a <OidcProvider configurationName="${name}"></OidcProvider> component.`);
|
|
171
|
-
}
|
|
172
|
-
return oidcDatabase[name];
|
|
274
|
+
tryKeepExistingSessionPromise = null;
|
|
275
|
+
async tryKeepExistingSessionAsync(): Promise<boolean> {
|
|
276
|
+
if (this.tryKeepExistingSessionPromise !== null) {
|
|
277
|
+
return this.tryKeepExistingSessionPromise;
|
|
173
278
|
}
|
|
279
|
+
this.tryKeepExistingSessionPromise = tryKeepSessionAsync(this);
|
|
280
|
+
return this.tryKeepExistingSessionPromise.finally(() => {
|
|
281
|
+
this.tryKeepExistingSessionPromise = null;
|
|
282
|
+
});
|
|
283
|
+
}
|
|
174
284
|
|
|
175
|
-
|
|
285
|
+
async startCheckSessionAsync(
|
|
286
|
+
checkSessionIFrameUri,
|
|
287
|
+
clientId,
|
|
288
|
+
sessionState,
|
|
289
|
+
isSilentSignin = false,
|
|
290
|
+
) {
|
|
291
|
+
await defaultStartCheckSessionAsync(this, oidcDatabase, this.configuration)(
|
|
292
|
+
checkSessionIFrameUri,
|
|
293
|
+
clientId,
|
|
294
|
+
sessionState,
|
|
295
|
+
isSilentSignin,
|
|
296
|
+
);
|
|
297
|
+
}
|
|
176
298
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
299
|
+
loginPromise: Promise<void> = null;
|
|
300
|
+
async loginAsync(
|
|
301
|
+
callbackPath: string = undefined,
|
|
302
|
+
extras: StringMap = null,
|
|
303
|
+
isSilentSignin = false,
|
|
304
|
+
scope: string = undefined,
|
|
305
|
+
silentLoginOnly = false,
|
|
306
|
+
) {
|
|
307
|
+
if (this.logoutPromise) {
|
|
308
|
+
await this.logoutPromise;
|
|
183
309
|
}
|
|
184
310
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
311
|
+
if (this.loginPromise !== null) {
|
|
312
|
+
return this.loginPromise;
|
|
313
|
+
}
|
|
314
|
+
if (silentLoginOnly) {
|
|
315
|
+
return defaultSilentLoginAsync(
|
|
316
|
+
window,
|
|
317
|
+
this.configurationName,
|
|
318
|
+
this.configuration,
|
|
319
|
+
this.publishEvent.bind(this),
|
|
320
|
+
this,
|
|
321
|
+
)(extras, scope);
|
|
196
322
|
}
|
|
323
|
+
this.loginPromise = defaultLoginAsync(
|
|
324
|
+
this.configurationName,
|
|
325
|
+
this.configuration,
|
|
326
|
+
this.publishEvent.bind(this),
|
|
327
|
+
this.initAsync.bind(this),
|
|
328
|
+
this.location,
|
|
329
|
+
)(callbackPath, extras, isSilentSignin, scope);
|
|
330
|
+
return this.loginPromise.finally(() => {
|
|
331
|
+
this.loginPromise = null;
|
|
332
|
+
});
|
|
333
|
+
}
|
|
197
334
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
} catch (exception) {
|
|
203
|
-
console.error(exception);
|
|
204
|
-
this._silentLoginErrorCallbackFromIFrame(exception);
|
|
205
|
-
}
|
|
335
|
+
loginCallbackPromise: Promise<any> = null;
|
|
336
|
+
async loginCallbackAsync(isSilenSignin = false) {
|
|
337
|
+
if (this.loginCallbackPromise !== null) {
|
|
338
|
+
return this.loginCallbackPromise;
|
|
206
339
|
}
|
|
207
340
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
341
|
+
const loginCallbackLocalAsync = async (): Promise<InternalLoginCallback> => {
|
|
342
|
+
const response = await loginCallbackAsync(this)(isSilenSignin);
|
|
343
|
+
// @ts-ignore
|
|
344
|
+
const parsedTokens = response.tokens;
|
|
345
|
+
// @ts-ignore
|
|
346
|
+
this.tokens = parsedTokens;
|
|
347
|
+
const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
|
|
348
|
+
if (!serviceWorker) {
|
|
349
|
+
const session = initSession(this.configurationName, this.configuration.storage);
|
|
350
|
+
session.setTokens(parsedTokens);
|
|
351
|
+
}
|
|
352
|
+
this.publishEvent(Oidc.eventNames.token_aquired, parsedTokens);
|
|
353
|
+
if (this.configuration.preload_user_info) {
|
|
354
|
+
await this.userInfoAsync();
|
|
355
|
+
}
|
|
356
|
+
// @ts-ignore
|
|
357
|
+
return { parsedTokens, state: response.state, callbackPath: response.callbackPath };
|
|
358
|
+
};
|
|
359
|
+
this.loginCallbackPromise = loginCallbackLocalAsync();
|
|
360
|
+
return this.loginCallbackPromise.finally(() => {
|
|
361
|
+
this.loginCallbackPromise = null;
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async generateDemonstrationOfProofOfPossessionAsync(
|
|
366
|
+
accessToken: string,
|
|
367
|
+
url: string,
|
|
368
|
+
method: string,
|
|
369
|
+
extras: StringMap = {},
|
|
370
|
+
): Promise<string> {
|
|
371
|
+
const configuration = this.configuration;
|
|
372
|
+
const claimsExtras = {
|
|
373
|
+
ath: await base64urlOfHashOfASCIIEncodingAsync(accessToken),
|
|
374
|
+
...extras,
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const serviceWorker = await initWorkerAsync(configuration, this.configurationName);
|
|
378
|
+
|
|
379
|
+
if (serviceWorker) {
|
|
380
|
+
return `DPOP_SECURED_BY_OIDC_SERVICE_WORKER_${this.configurationName}`;
|
|
238
381
|
}
|
|
239
382
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return this.tryKeepExistingSessionPromise.finally(() => {
|
|
247
|
-
this.tryKeepExistingSessionPromise = null;
|
|
248
|
-
});
|
|
383
|
+
const session = initSession(this.configurationName, configuration.storage);
|
|
384
|
+
const jwk = await session.getDemonstratingProofOfPossessionJwkAsync();
|
|
385
|
+
const demonstratingProofOfPossessionNonce = session.getDemonstratingProofOfPossessionNonce();
|
|
386
|
+
|
|
387
|
+
if (demonstratingProofOfPossessionNonce) {
|
|
388
|
+
claimsExtras['nonce'] = demonstratingProofOfPossessionNonce;
|
|
249
389
|
}
|
|
250
390
|
|
|
251
|
-
|
|
252
|
-
|
|
391
|
+
return await generateJwtDemonstratingProofOfPossessionAsync(window)(
|
|
392
|
+
configuration.demonstrating_proof_of_possession_configuration,
|
|
393
|
+
)(jwk, method, url, claimsExtras);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
loginCallbackWithAutoTokensRenewPromise: Promise<LoginCallback> = null;
|
|
397
|
+
loginCallbackWithAutoTokensRenewAsync(): Promise<LoginCallback> {
|
|
398
|
+
if (this.loginCallbackWithAutoTokensRenewPromise !== null) {
|
|
399
|
+
return this.loginCallbackWithAutoTokensRenewPromise;
|
|
253
400
|
}
|
|
401
|
+
this.loginCallbackWithAutoTokensRenewPromise = loginCallbackWithAutoTokensRenewAsync(this);
|
|
402
|
+
return this.loginCallbackWithAutoTokensRenewPromise.finally(() => {
|
|
403
|
+
this.loginCallbackWithAutoTokensRenewPromise = null;
|
|
404
|
+
});
|
|
405
|
+
}
|
|
254
406
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if (this.loginPromise !== null) {
|
|
262
|
-
return this.loginPromise;
|
|
263
|
-
}
|
|
264
|
-
if (silentLoginOnly) {
|
|
265
|
-
return defaultSilentLoginAsync(window, this.configurationName, this.configuration, this.publishEvent.bind(this), this)(extras, scope);
|
|
266
|
-
}
|
|
267
|
-
this.loginPromise = defaultLoginAsync(this.configurationName, this.configuration, this.publishEvent.bind(this), this.initAsync.bind(this), this.location)(callbackPath, extras, isSilentSignin, scope);
|
|
268
|
-
return this.loginPromise.finally(() => {
|
|
269
|
-
this.loginPromise = null;
|
|
270
|
-
});
|
|
407
|
+
userInfoPromise: Promise<any> = null;
|
|
408
|
+
userInfoAsync(noCache = false, demonstrating_proof_of_possession = false) {
|
|
409
|
+
if (this.userInfoPromise !== null) {
|
|
410
|
+
return this.userInfoPromise;
|
|
271
411
|
}
|
|
412
|
+
this.userInfoPromise = userInfoAsync(this)(noCache, demonstrating_proof_of_possession);
|
|
413
|
+
return this.userInfoPromise.finally(() => {
|
|
414
|
+
this.userInfoPromise = null;
|
|
415
|
+
});
|
|
416
|
+
}
|
|
272
417
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
// @ts-ignore
|
|
282
|
-
const parsedTokens = response.tokens;
|
|
283
|
-
// @ts-ignore
|
|
284
|
-
this.tokens = parsedTokens;
|
|
285
|
-
const serviceWorker = await initWorkerAsync(this.configuration, this.configurationName);
|
|
286
|
-
if (!serviceWorker) {
|
|
287
|
-
const session = initSession(this.configurationName, this.configuration.storage);
|
|
288
|
-
session.setTokens(parsedTokens);
|
|
289
|
-
}
|
|
290
|
-
this.publishEvent(Oidc.eventNames.token_aquired, parsedTokens);
|
|
291
|
-
if(this.configuration.preload_user_info){
|
|
292
|
-
await this.userInfoAsync();
|
|
293
|
-
}
|
|
294
|
-
// @ts-ignore
|
|
295
|
-
return { parsedTokens, state: response.state, callbackPath: response.callbackPath };
|
|
296
|
-
};
|
|
297
|
-
this.loginCallbackPromise = loginCallbackLocalAsync();
|
|
298
|
-
return this.loginCallbackPromise.finally(() => {
|
|
299
|
-
this.loginCallbackPromise = null;
|
|
300
|
-
});
|
|
418
|
+
renewTokensPromise: Promise<any> = null;
|
|
419
|
+
|
|
420
|
+
async renewTokensAsync(extras: StringMap = null) {
|
|
421
|
+
if (this.renewTokensPromise !== null) {
|
|
422
|
+
return this.renewTokensPromise;
|
|
423
|
+
}
|
|
424
|
+
if (!this.timeoutId) {
|
|
425
|
+
return;
|
|
301
426
|
}
|
|
427
|
+
timer.clearTimeout(this.timeoutId);
|
|
428
|
+
// @ts-ignore
|
|
429
|
+
this.renewTokensPromise = renewTokensAndStartTimerAsync(this, true, extras);
|
|
430
|
+
return this.renewTokensPromise.finally(() => {
|
|
431
|
+
this.renewTokensPromise = null;
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
async destroyAsync(status) {
|
|
436
|
+
return await destroyAsync(this)(status);
|
|
437
|
+
}
|
|
302
438
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return `DPOP_SECURED_BY_OIDC_SERVICE_WORKER_${this.configurationName}`;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const session = initSession(this.configurationName, configuration.storage);
|
|
319
|
-
let jwk = await session.getDemonstratingProofOfPossessionJwkAsync();
|
|
320
|
-
demonstratingProofOfPossessionNonce = await session.getDemonstratingProofOfPossessionNonce();
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if (demonstratingProofOfPossessionNonce) {
|
|
324
|
-
claimsExtras['nonce'] = demonstratingProofOfPossessionNonce;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return await generateJwtDemonstratingProofOfPossessionAsync(window)(configuration.demonstrating_proof_of_possession_configuration)(jwk, method, url, claimsExtras);
|
|
439
|
+
async logoutSameTabAsync(clientId: string, sub: any) {
|
|
440
|
+
// @ts-ignore
|
|
441
|
+
if (
|
|
442
|
+
this.configuration.monitor_session &&
|
|
443
|
+
this.configuration.client_id === clientId &&
|
|
444
|
+
sub &&
|
|
445
|
+
this.tokens &&
|
|
446
|
+
this.tokens.idTokenPayload &&
|
|
447
|
+
this.tokens.idTokenPayload.sub === sub
|
|
448
|
+
) {
|
|
449
|
+
await this.destroyAsync('LOGGED_OUT');
|
|
450
|
+
this.publishEvent(eventNames.logout_from_same_tab, { mmessage: 'SessionMonitor', sub });
|
|
328
451
|
}
|
|
452
|
+
}
|
|
329
453
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
userInfoAsync(noCache = false, demonstrating_proof_of_possession=false) {
|
|
343
|
-
if (this.userInfoPromise !== null) {
|
|
344
|
-
return this.userInfoPromise;
|
|
345
|
-
}
|
|
346
|
-
this.userInfoPromise = userInfoAsync(this)(noCache, demonstrating_proof_of_possession);
|
|
347
|
-
return this.userInfoPromise.finally(() => {
|
|
348
|
-
this.userInfoPromise = null;
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
renewTokensPromise:Promise<any> = null;
|
|
353
|
-
|
|
354
|
-
async renewTokensAsync (extras:StringMap = null) {
|
|
355
|
-
if (this.renewTokensPromise !== null) {
|
|
356
|
-
return this.renewTokensPromise;
|
|
357
|
-
}
|
|
358
|
-
if (!this.timeoutId) {
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
timer.clearTimeout(this.timeoutId);
|
|
362
|
-
// @ts-ignore
|
|
363
|
-
this.renewTokensPromise = renewTokensAndStartTimerAsync(this, true, extras);
|
|
364
|
-
return this.renewTokensPromise.finally(() => {
|
|
365
|
-
this.renewTokensPromise = null;
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
async destroyAsync(status) {
|
|
370
|
-
return await destroyAsync(this)(status);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
async logoutSameTabAsync(clientId: string, sub: any) {
|
|
374
|
-
// @ts-ignore
|
|
375
|
-
if (this.configuration.monitor_session && this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
|
|
376
|
-
await this.destroyAsync('LOGGED_OUT');
|
|
377
|
-
this.publishEvent(eventNames.logout_from_same_tab, { mmessage: 'SessionMonitor', sub });
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
async logoutOtherTabAsync(clientId: string, sub: any) {
|
|
382
|
-
// @ts-ignore
|
|
383
|
-
if (this.configuration.monitor_session && this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
|
|
384
|
-
await this.destroyAsync('LOGGED_OUT');
|
|
385
|
-
this.publishEvent(eventNames.logout_from_another_tab, { message: 'SessionMonitor', sub });
|
|
386
|
-
}
|
|
454
|
+
async logoutOtherTabAsync(clientId: string, sub: any) {
|
|
455
|
+
// @ts-ignore
|
|
456
|
+
if (
|
|
457
|
+
this.configuration.monitor_session &&
|
|
458
|
+
this.configuration.client_id === clientId &&
|
|
459
|
+
sub &&
|
|
460
|
+
this.tokens &&
|
|
461
|
+
this.tokens.idTokenPayload &&
|
|
462
|
+
this.tokens.idTokenPayload.sub === sub
|
|
463
|
+
) {
|
|
464
|
+
await this.destroyAsync('LOGGED_OUT');
|
|
465
|
+
this.publishEvent(eventNames.logout_from_another_tab, { message: 'SessionMonitor', sub });
|
|
387
466
|
}
|
|
467
|
+
}
|
|
388
468
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
this.logoutPromise = null;
|
|
397
|
-
});
|
|
469
|
+
logoutPromise: Promise<void> = null;
|
|
470
|
+
async logoutAsync(
|
|
471
|
+
callbackPathOrUrl: string | null | undefined = undefined,
|
|
472
|
+
extras: StringMap = null,
|
|
473
|
+
) {
|
|
474
|
+
if (this.logoutPromise) {
|
|
475
|
+
return this.logoutPromise;
|
|
398
476
|
}
|
|
477
|
+
this.logoutPromise = logoutAsync(
|
|
478
|
+
this,
|
|
479
|
+
oidcDatabase,
|
|
480
|
+
this.getFetch(),
|
|
481
|
+
console,
|
|
482
|
+
this.location,
|
|
483
|
+
)(callbackPathOrUrl, extras);
|
|
484
|
+
return this.logoutPromise.finally(() => {
|
|
485
|
+
this.logoutPromise = null;
|
|
486
|
+
});
|
|
399
487
|
}
|
|
488
|
+
}
|
|
400
489
|
|
|
401
|
-
|
|
490
|
+
export default Oidc;
|