@axa-fr/react-oidc 6.9.6 → 6.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -102
- package/dist/FetchToken.d.ts.map +1 -1
- package/dist/FetchToken.js +2 -2
- package/dist/FetchToken.js.map +1 -1
- package/dist/OidcProvider.d.ts +7 -6
- package/dist/OidcProvider.d.ts.map +1 -1
- package/dist/OidcProvider.js +30 -26
- package/dist/OidcProvider.js.map +1 -1
- package/dist/OidcSecure.d.ts +2 -2
- package/dist/OidcSecure.d.ts.map +1 -1
- package/dist/OidcSecure.js +2 -4
- package/dist/OidcSecure.js.map +1 -1
- package/dist/OidcServiceWorker.js +150 -144
- package/dist/OidcTrustedDomains.js +9 -10
- package/dist/ReactOidc.d.ts +1 -1
- package/dist/ReactOidc.d.ts.map +1 -1
- package/dist/ReactOidc.js +22 -16
- package/dist/ReactOidc.js.map +1 -1
- package/dist/User.d.ts.map +1 -1
- package/dist/User.js +1 -1
- package/dist/User.js.map +1 -1
- package/dist/core/default-component/AuthenticateError.component.d.ts +1 -1
- package/dist/core/default-component/AuthenticateError.component.d.ts.map +1 -1
- package/dist/core/default-component/Authenticating.component.d.ts +1 -1
- package/dist/core/default-component/Authenticating.component.d.ts.map +1 -1
- package/dist/core/default-component/Callback.component.d.ts.map +1 -1
- package/dist/core/default-component/Callback.component.js +5 -5
- package/dist/core/default-component/Callback.component.js.map +1 -1
- package/dist/core/default-component/Loading.component.d.ts +1 -1
- package/dist/core/default-component/Loading.component.d.ts.map +1 -1
- package/dist/core/default-component/ServiceWorkerNotSupported.component.d.ts +1 -1
- package/dist/core/default-component/ServiceWorkerNotSupported.component.d.ts.map +1 -1
- package/dist/core/default-component/SessionLost.component.d.ts.map +1 -1
- package/dist/core/default-component/SilentCallback.component.d.ts.map +1 -1
- package/dist/core/default-component/SilentCallback.component.js +1 -0
- package/dist/core/default-component/SilentCallback.component.js.map +1 -1
- package/dist/core/default-component/SilentLogin.component.d.ts.map +1 -1
- package/dist/core/default-component/SilentLogin.component.js +5 -7
- package/dist/core/default-component/SilentLogin.component.js.map +1 -1
- package/dist/core/default-component/index.d.ts +2 -2
- package/dist/core/default-component/index.d.ts.map +1 -1
- package/dist/core/default-component/index.js +5 -5
- package/dist/core/default-component/index.js.map +1 -1
- package/dist/core/routes/OidcRoutes.d.ts +1 -1
- package/dist/core/routes/OidcRoutes.d.ts.map +1 -1
- package/dist/core/routes/OidcRoutes.js +1 -1
- package/dist/core/routes/OidcRoutes.js.map +1 -1
- package/dist/core/routes/withRouter.d.ts.map +1 -1
- package/dist/core/routes/withRouter.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/vanilla/checkSessionIFrame.d.ts.map +1 -1
- package/dist/vanilla/checkSessionIFrame.js +15 -15
- package/dist/vanilla/checkSessionIFrame.js.map +1 -1
- package/dist/vanilla/initSession.d.ts.map +1 -1
- package/dist/vanilla/initSession.js +1 -1
- package/dist/vanilla/initSession.js.map +1 -1
- package/dist/vanilla/initWorker.d.ts +1 -1
- package/dist/vanilla/initWorker.d.ts.map +1 -1
- package/dist/vanilla/initWorker.js +22 -20
- package/dist/vanilla/initWorker.js.map +1 -1
- package/dist/vanilla/memoryStorageBackend.d.ts +5 -4
- package/dist/vanilla/memoryStorageBackend.d.ts.map +1 -1
- package/dist/vanilla/memoryStorageBackend.js.map +1 -1
- package/dist/vanilla/noHashQueryStringUtils.d.ts +3 -3
- package/dist/vanilla/noHashQueryStringUtils.d.ts.map +1 -1
- package/dist/vanilla/noHashQueryStringUtils.js +4 -4
- package/dist/vanilla/noHashQueryStringUtils.js.map +1 -1
- package/dist/vanilla/oidc.d.ts +6 -6
- package/dist/vanilla/oidc.d.ts.map +1 -1
- package/dist/vanilla/oidc.js +215 -216
- package/dist/vanilla/oidc.js.map +1 -1
- package/dist/vanilla/parseTokens.d.ts +2 -2
- package/dist/vanilla/parseTokens.d.ts.map +1 -1
- package/dist/vanilla/parseTokens.js +8 -8
- package/dist/vanilla/parseTokens.js.map +1 -1
- package/dist/vanilla/route-utils.d.ts.map +1 -1
- package/dist/vanilla/route-utils.js +10 -7
- package/dist/vanilla/route-utils.js.map +1 -1
- package/dist/vanilla/timer.d.ts.map +1 -1
- package/dist/vanilla/timer.js +8 -8
- package/dist/vanilla/timer.js.map +1 -1
- package/dist/vanilla/vanillaOidc.d.ts +6 -4
- package/dist/vanilla/vanillaOidc.d.ts.map +1 -1
- package/dist/vanilla/vanillaOidc.js +4 -5
- package/dist/vanilla/vanillaOidc.js.map +1 -1
- package/package.json +15 -6
- package/src/oidc/FetchToken.tsx +10 -11
- package/src/oidc/OidcProvider.tsx +82 -83
- package/src/oidc/OidcSecure.tsx +16 -18
- package/src/oidc/ReactOidc.tsx +74 -63
- package/src/oidc/User.ts +14 -13
- package/src/oidc/core/default-component/AuthenticateError.component.tsx +1 -1
- package/src/oidc/core/default-component/Authenticating.component.tsx +1 -1
- package/src/oidc/core/default-component/Callback.component.tsx +18 -18
- package/src/oidc/core/default-component/Loading.component.tsx +1 -1
- package/src/oidc/core/default-component/ServiceWorkerNotSupported.component.tsx +1 -1
- package/src/oidc/core/default-component/SessionLost.component.tsx +1 -1
- package/src/oidc/core/default-component/SilentCallback.component.tsx +7 -6
- package/src/oidc/core/default-component/SilentLogin.component.tsx +16 -18
- package/src/oidc/core/default-component/index.ts +2 -2
- package/src/oidc/core/routes/OidcRoutes.tsx +16 -15
- package/src/oidc/core/routes/withRouter.tsx +2 -4
- package/src/oidc/index.ts +7 -6
- package/src/oidc/vanilla/OidcServiceWorker.js +150 -144
- package/src/oidc/vanilla/OidcTrustedDomains.js +9 -10
- package/src/oidc/vanilla/checkSessionIFrame.ts +24 -23
- package/src/oidc/vanilla/index.ts +2 -1
- package/src/oidc/vanilla/initSession.ts +36 -37
- package/src/oidc/vanilla/initWorker.ts +82 -83
- package/src/oidc/vanilla/memoryStorageBackend.ts +13 -6
- package/src/oidc/vanilla/noHashQueryStringUtils.ts +13 -13
- package/src/oidc/vanilla/oidc.ts +460 -467
- package/src/oidc/vanilla/parseTokens.ts +73 -79
- package/src/oidc/vanilla/route-utils.ts +18 -18
- package/src/oidc/vanilla/timer.ts +14 -16
- package/src/oidc/vanilla/vanillaOidc.ts +35 -19
- package/src/override/AuthenticateError.component.tsx +4 -3
- package/src/override/Authenticating.component.tsx +4 -3
- package/src/override/Callback.component.tsx +4 -3
- package/src/override/Loading.component.tsx +4 -6
- package/src/override/ServiceWorkerNotSupported.component.tsx +5 -5
- package/src/override/SessionLost.component.tsx +8 -7
- package/src/override/style.ts +12 -10
- package/dist/core/routes/index.d.ts +0 -3
- package/dist/core/routes/index.d.ts.map +0 -1
- package/dist/core/routes/index.js +0 -9
- package/dist/core/routes/index.js.map +0 -1
- package/dist/vanilla/index.d.ts +0 -2
- package/dist/vanilla/index.d.ts.map +0 -1
- package/dist/vanilla/index.js +0 -6
- package/dist/vanilla/index.js.map +0 -1
- package/src/App.css +0 -38
- package/src/App.specold.tsx +0 -46
- package/src/App.tsx +0 -103
- package/src/FetchUser.tsx +0 -53
- package/src/Home.tsx +0 -23
- package/src/MultiAuth.tsx +0 -129
- package/src/Profile.tsx +0 -81
- package/src/configurations.ts +0 -73
- package/src/index.css +0 -13
- package/src/index.tsx +0 -9
- package/src/logo.svg +0 -7
- package/src/setupTests.js +0 -5
package/src/oidc/vanilla/oidc.ts
CHANGED
|
@@ -8,46 +8,45 @@ import {
|
|
|
8
8
|
GRANT_TYPE_AUTHORIZATION_CODE,
|
|
9
9
|
GRANT_TYPE_REFRESH_TOKEN,
|
|
10
10
|
RedirectRequestHandler,
|
|
11
|
-
TokenRequest
|
|
11
|
+
TokenRequest,
|
|
12
12
|
} from '@openid/appauth';
|
|
13
|
-
import {
|
|
14
|
-
import {initWorkerAsync, sleepAsync} from './initWorker'
|
|
15
|
-
import {MemoryStorageBackend} from "./memoryStorageBackend";
|
|
16
|
-
import {initSession} from "./initSession";
|
|
17
|
-
import timer from './timer';
|
|
13
|
+
import { AuthorizationServiceConfigurationJson } from '@openid/appauth/src/authorization_service_configuration';
|
|
18
14
|
|
|
19
|
-
import {CheckSessionIFrame} from
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
15
|
+
import { CheckSessionIFrame } from './checkSessionIFrame';
|
|
16
|
+
import { initSession } from './initSession';
|
|
17
|
+
import { initWorkerAsync, sleepAsync } from './initWorker';
|
|
18
|
+
import { MemoryStorageBackend } from './memoryStorageBackend';
|
|
19
|
+
import { HashQueryStringUtils, NoHashQueryStringUtils } from './noHashQueryStringUtils';
|
|
22
20
|
import {
|
|
23
21
|
computeTimeLeft,
|
|
24
22
|
isTokensOidcValid,
|
|
25
23
|
isTokensValid,
|
|
26
24
|
parseOriginalTokens,
|
|
27
25
|
setTokens, TokenRenewMode,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} from
|
|
26
|
+
Tokens,
|
|
27
|
+
} from './parseTokens';
|
|
28
|
+
import { getParseQueryStringFromLocation } from './route-utils';
|
|
29
|
+
import timer from './timer';
|
|
31
30
|
|
|
32
|
-
const TOKEN_TYPE ={
|
|
33
|
-
refresh_token:
|
|
34
|
-
access_token:
|
|
35
|
-
}
|
|
31
|
+
const TOKEN_TYPE = {
|
|
32
|
+
refresh_token: 'refresh_token',
|
|
33
|
+
access_token: 'access_token',
|
|
34
|
+
};
|
|
36
35
|
|
|
37
|
-
const performRevocationRequestAsync= async (url, token, token_type=TOKEN_TYPE.refresh_token, client_id) => {
|
|
36
|
+
const performRevocationRequestAsync = async (url, token, token_type = TOKEN_TYPE.refresh_token, client_id) => {
|
|
38
37
|
const details = {
|
|
39
|
-
token
|
|
40
|
-
token_type_hint:token_type,
|
|
41
|
-
client_id
|
|
42
|
-
}
|
|
38
|
+
token,
|
|
39
|
+
token_type_hint: token_type,
|
|
40
|
+
client_id,
|
|
41
|
+
};
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
const formBody = [];
|
|
45
44
|
for (const property in details) {
|
|
46
45
|
const encodedKey = encodeURIComponent(property);
|
|
47
46
|
const encodedValue = encodeURIComponent(details[property]);
|
|
48
47
|
formBody.push(`${encodedKey}=${encodedValue}`);
|
|
49
48
|
}
|
|
50
|
-
const formBodyString = formBody.join(
|
|
49
|
+
const formBodyString = formBody.join('&');
|
|
51
50
|
|
|
52
51
|
const response = await internalFetch(url, {
|
|
53
52
|
method: 'POST',
|
|
@@ -56,28 +55,28 @@ const performRevocationRequestAsync= async (url, token, token_type=TOKEN_TYPE.re
|
|
|
56
55
|
},
|
|
57
56
|
body: formBodyString,
|
|
58
57
|
});
|
|
59
|
-
if(response.status !== 200){
|
|
60
|
-
return { success:false };
|
|
58
|
+
if (response.status !== 200) {
|
|
59
|
+
return { success: false };
|
|
61
60
|
}
|
|
62
61
|
return {
|
|
63
|
-
success
|
|
62
|
+
success: true,
|
|
64
63
|
};
|
|
65
|
-
}
|
|
64
|
+
};
|
|
66
65
|
|
|
67
|
-
const performTokenRequestAsync= async (url, details, extras, oldTokens, tokenRenewMode: string) => {
|
|
68
|
-
for (
|
|
66
|
+
const performTokenRequestAsync = async (url, details, extras, oldTokens, tokenRenewMode: string) => {
|
|
67
|
+
for (const [key, value] of Object.entries(extras)) {
|
|
69
68
|
if (details[key] === undefined) {
|
|
70
69
|
details[key] = value;
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
const formBody = [];
|
|
75
74
|
for (const property in details) {
|
|
76
75
|
const encodedKey = encodeURIComponent(property);
|
|
77
76
|
const encodedValue = encodeURIComponent(details[property]);
|
|
78
77
|
formBody.push(`${encodedKey}=${encodedValue}`);
|
|
79
78
|
}
|
|
80
|
-
const formBodyString = formBody.join(
|
|
79
|
+
const formBodyString = formBody.join('&');
|
|
81
80
|
|
|
82
81
|
const response = await internalFetch(url, {
|
|
83
82
|
method: 'POST',
|
|
@@ -86,29 +85,28 @@ const performTokenRequestAsync= async (url, details, extras, oldTokens, tokenRen
|
|
|
86
85
|
},
|
|
87
86
|
body: formBodyString,
|
|
88
87
|
});
|
|
89
|
-
if(response.status !== 200){
|
|
90
|
-
return {success:false, status: response.status}
|
|
88
|
+
if (response.status !== 200) {
|
|
89
|
+
return { success: false, status: response.status };
|
|
91
90
|
}
|
|
92
91
|
const tokens = await response.json();
|
|
93
|
-
return {
|
|
94
|
-
success
|
|
95
|
-
data: parseOriginalTokens(tokens, oldTokens,tokenRenewMode)
|
|
92
|
+
return {
|
|
93
|
+
success: true,
|
|
94
|
+
data: parseOriginalTokens(tokens, oldTokens, tokenRenewMode),
|
|
96
95
|
};
|
|
97
|
-
}
|
|
96
|
+
};
|
|
98
97
|
|
|
99
|
-
const internalFetch = async (url, headers, numberRetry=0) => {
|
|
98
|
+
const internalFetch = async (url, headers, numberRetry = 0) => {
|
|
100
99
|
let response;
|
|
101
100
|
try {
|
|
102
|
-
|
|
101
|
+
const controller = new AbortController();
|
|
103
102
|
setTimeout(() => controller.abort(), 10000);
|
|
104
|
-
response = await fetch(url, {...headers, signal: controller.signal});
|
|
103
|
+
response = await fetch(url, { ...headers, signal: controller.signal });
|
|
105
104
|
} catch (e) {
|
|
106
|
-
if (e.message === 'AbortError'
|
|
107
|
-
|
|
108
|
-
if(numberRetry <=1) {
|
|
105
|
+
if (e.message === 'AbortError' ||
|
|
106
|
+
e.message === 'Network request failed') {
|
|
107
|
+
if (numberRetry <= 1) {
|
|
109
108
|
return await internalFetch(url, headers, numberRetry + 1);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
109
|
+
} else {
|
|
112
110
|
throw e;
|
|
113
111
|
}
|
|
114
112
|
} else {
|
|
@@ -117,26 +115,26 @@ const internalFetch = async (url, headers, numberRetry=0) => {
|
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
117
|
return response;
|
|
120
|
-
}
|
|
118
|
+
};
|
|
121
119
|
|
|
122
120
|
const randomString = function(length) {
|
|
123
|
-
let text =
|
|
124
|
-
const possible =
|
|
125
|
-
for(let i = 0; i < length; i++) {
|
|
121
|
+
let text = '';
|
|
122
|
+
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
123
|
+
for (let i = 0; i < length; i++) {
|
|
126
124
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
|
127
125
|
}
|
|
128
126
|
return text;
|
|
129
|
-
}
|
|
127
|
+
};
|
|
130
128
|
|
|
131
129
|
export interface OidcAuthorizationServiceConfigurationJson extends AuthorizationServiceConfigurationJson{
|
|
132
130
|
check_session_iframe?: string;
|
|
133
131
|
issuer:string;
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
export class OidcAuthorizationServiceConfiguration extends AuthorizationServiceConfiguration{
|
|
134
|
+
export class OidcAuthorizationServiceConfiguration extends AuthorizationServiceConfiguration {
|
|
137
135
|
private check_session_iframe: string;
|
|
138
136
|
private issuer: string;
|
|
139
|
-
|
|
137
|
+
|
|
140
138
|
constructor(request: any) {
|
|
141
139
|
super(request);
|
|
142
140
|
this.authorizationEndpoint = request.authorization_endpoint;
|
|
@@ -146,15 +144,12 @@ export class OidcAuthorizationServiceConfiguration extends AuthorizationServiceC
|
|
|
146
144
|
this.check_session_iframe = request.check_session_iframe;
|
|
147
145
|
this.issuer = request.issuer;
|
|
148
146
|
}
|
|
149
|
-
|
|
150
147
|
}
|
|
151
148
|
|
|
152
|
-
|
|
153
149
|
export interface StringMap {
|
|
154
150
|
[key: string]: string;
|
|
155
151
|
}
|
|
156
152
|
|
|
157
|
-
|
|
158
153
|
export interface AuthorityConfiguration {
|
|
159
154
|
authorization_endpoint: string;
|
|
160
155
|
token_endpoint: string;
|
|
@@ -166,59 +161,59 @@ export interface AuthorityConfiguration {
|
|
|
166
161
|
}
|
|
167
162
|
|
|
168
163
|
export type OidcConfiguration = {
|
|
169
|
-
client_id: string
|
|
170
|
-
redirect_uri: string
|
|
171
|
-
silent_redirect_uri?:string
|
|
172
|
-
silent_login_uri?:string
|
|
173
|
-
silent_login_timeout?:number
|
|
174
|
-
scope: string
|
|
175
|
-
authority: string
|
|
176
|
-
authority_time_cache_wellknowurl_in_second?: number
|
|
177
|
-
authority_configuration?: AuthorityConfiguration
|
|
178
|
-
refresh_time_before_tokens_expiration_in_second?: number
|
|
179
|
-
token_request_timeout?: number
|
|
180
|
-
service_worker_relative_url?:string
|
|
181
|
-
service_worker_only?:boolean
|
|
182
|
-
extras?:StringMap
|
|
183
|
-
token_request_extras?:StringMap
|
|
184
|
-
storage?: Storage
|
|
185
|
-
monitor_session?: boolean
|
|
186
|
-
token_renew_mode?: string
|
|
164
|
+
client_id: string;
|
|
165
|
+
redirect_uri: string;
|
|
166
|
+
silent_redirect_uri?:string;
|
|
167
|
+
silent_login_uri?:string;
|
|
168
|
+
silent_login_timeout?:number;
|
|
169
|
+
scope: string;
|
|
170
|
+
authority: string;
|
|
171
|
+
authority_time_cache_wellknowurl_in_second?: number;
|
|
172
|
+
authority_configuration?: AuthorityConfiguration;
|
|
173
|
+
refresh_time_before_tokens_expiration_in_second?: number;
|
|
174
|
+
token_request_timeout?: number;
|
|
175
|
+
service_worker_relative_url?:string;
|
|
176
|
+
service_worker_only?:boolean;
|
|
177
|
+
extras?:StringMap;
|
|
178
|
+
token_request_extras?:StringMap;
|
|
179
|
+
storage?: Storage;
|
|
180
|
+
monitor_session?: boolean;
|
|
181
|
+
token_renew_mode?: string;
|
|
187
182
|
};
|
|
188
183
|
|
|
189
184
|
const oidcDatabase = {};
|
|
190
|
-
const oidcFactory = (configuration: OidcConfiguration, name=
|
|
191
|
-
if(oidcDatabase[name]){
|
|
185
|
+
const oidcFactory = (configuration: OidcConfiguration, name = 'default') => {
|
|
186
|
+
if (oidcDatabase[name]) {
|
|
192
187
|
return oidcDatabase[name];
|
|
193
188
|
}
|
|
194
|
-
oidcDatabase[name] = new Oidc(configuration, name)
|
|
189
|
+
oidcDatabase[name] = new Oidc(configuration, name);
|
|
195
190
|
return oidcDatabase[name];
|
|
196
|
-
}
|
|
191
|
+
};
|
|
197
192
|
export type LoginCallback = {
|
|
198
|
-
callbackPath:string
|
|
193
|
+
callbackPath:string;
|
|
199
194
|
}
|
|
200
195
|
|
|
201
196
|
export type InternalLoginCallback = {
|
|
202
|
-
callbackPath:string
|
|
203
|
-
parsedTokens:Tokens
|
|
197
|
+
callbackPath:string;
|
|
198
|
+
parsedTokens:Tokens;
|
|
204
199
|
}
|
|
205
200
|
|
|
206
201
|
const loginCallbackWithAutoTokensRenewAsync = async (oidc) : Promise<LoginCallback> => {
|
|
207
202
|
const { parsedTokens, callbackPath } = await oidc.loginCallbackAsync();
|
|
208
|
-
oidc.timeoutId = autoRenewTokens(oidc, parsedTokens.refreshToken, parsedTokens.expiresAt)
|
|
203
|
+
oidc.timeoutId = autoRenewTokens(oidc, parsedTokens.refreshToken, parsedTokens.expiresAt);
|
|
209
204
|
return { callbackPath };
|
|
210
|
-
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
async function renewTokensAndStartTimerAsync(oidc, refreshToken, forceRefresh = false, extras:StringMap = null) {
|
|
208
|
+
const updateTokens = (tokens) => { oidc.tokens = tokens; };
|
|
209
|
+
const { tokens, status } = await oidc.synchroniseTokensAsync(refreshToken, 0, forceRefresh, extras, updateTokens);
|
|
211
210
|
|
|
212
|
-
async function renewTokensAndStartTimerAsync(oidc, refreshToken, forceRefresh =false, extras:StringMap=null) {
|
|
213
|
-
const updateTokens = (tokens) => oidc.tokens = tokens;
|
|
214
|
-
const {tokens, status} = await oidc.synchroniseTokensAsync(refreshToken, 0, forceRefresh, extras, updateTokens);
|
|
215
|
-
|
|
216
211
|
const serviceWorker = await initWorkerAsync(oidc.configuration.service_worker_relative_url, oidc.configurationName);
|
|
217
212
|
if (!serviceWorker) {
|
|
218
213
|
const session = initSession(oidc.configurationName, oidc.configuration.redirect_uri, oidc.configuration.storage);
|
|
219
214
|
await session.setTokens(oidc.tokens);
|
|
220
215
|
}
|
|
221
|
-
|
|
216
|
+
|
|
222
217
|
if (!oidc.tokens) {
|
|
223
218
|
await oidc.destroyAsync(status);
|
|
224
219
|
return;
|
|
@@ -229,7 +224,7 @@ async function renewTokensAndStartTimerAsync(oidc, refreshToken, forceRefresh =f
|
|
|
229
224
|
}
|
|
230
225
|
}
|
|
231
226
|
|
|
232
|
-
const autoRenewTokens = (oidc, refreshToken, expiresAt, extras:StringMap=null) => {
|
|
227
|
+
const autoRenewTokens = (oidc, refreshToken, expiresAt, extras:StringMap = null) => {
|
|
233
228
|
const refreshTimeBeforeTokensExpirationInSecond = oidc.configuration.refresh_time_before_tokens_expiration_in_second;
|
|
234
229
|
return timer.setTimeout(async () => {
|
|
235
230
|
const timeLeft = computeTimeLeft(refreshTimeBeforeTokensExpirationInSecond, expiresAt);
|
|
@@ -237,105 +232,105 @@ const autoRenewTokens = (oidc, refreshToken, expiresAt, extras:StringMap=null) =
|
|
|
237
232
|
oidc.publishEvent(Oidc.eventNames.token_timer, timeInfo);
|
|
238
233
|
await renewTokensAndStartTimerAsync(oidc, refreshToken, false, extras);
|
|
239
234
|
}, 1000);
|
|
240
|
-
}
|
|
235
|
+
};
|
|
241
236
|
|
|
242
237
|
const getLoginSessionKey = (configurationName:string, redirectUri:string) => {
|
|
243
238
|
return `oidc_login.${configurationName}:${redirectUri}`;
|
|
244
|
-
}
|
|
239
|
+
};
|
|
245
240
|
|
|
246
|
-
const setLoginParams = (configurationName:string, redirectUri:string, data) =>{
|
|
241
|
+
const setLoginParams = (configurationName:string, redirectUri:string, data) => {
|
|
247
242
|
const sessionKey = getLoginSessionKey(configurationName, redirectUri);
|
|
248
|
-
getLoginParamsCache = data
|
|
243
|
+
getLoginParamsCache = data;
|
|
249
244
|
sessionStorage[sessionKey] = JSON.stringify(data);
|
|
250
|
-
}
|
|
245
|
+
};
|
|
251
246
|
|
|
252
247
|
let getLoginParamsCache = null;
|
|
253
248
|
const getLoginParams = (configurationName, redirectUri) => {
|
|
254
249
|
const dataString = sessionStorage[getLoginSessionKey(configurationName, redirectUri)];
|
|
255
|
-
if(!getLoginParamsCache){
|
|
250
|
+
if (!getLoginParamsCache) {
|
|
256
251
|
getLoginParamsCache = JSON.parse(dataString);
|
|
257
252
|
}
|
|
258
253
|
return getLoginParamsCache;
|
|
259
|
-
}
|
|
254
|
+
};
|
|
260
255
|
|
|
261
256
|
const userInfoAsync = async (oidc) => {
|
|
262
|
-
if(oidc.userInfo != null){
|
|
257
|
+
if (oidc.userInfo != null) {
|
|
263
258
|
return oidc.userInfo;
|
|
264
259
|
}
|
|
265
|
-
if(!oidc.tokens){
|
|
260
|
+
if (!oidc.tokens) {
|
|
266
261
|
return null;
|
|
267
262
|
}
|
|
268
263
|
const accessToken = oidc.tokens.accessToken;
|
|
269
|
-
if(!accessToken){
|
|
264
|
+
if (!accessToken) {
|
|
270
265
|
return null;
|
|
271
266
|
}
|
|
272
267
|
// We wait the synchronisation before making a request
|
|
273
|
-
while (oidc.tokens && !isTokensValid(oidc.tokens)){
|
|
268
|
+
while (oidc.tokens && !isTokensValid(oidc.tokens)) {
|
|
274
269
|
await sleepAsync(200);
|
|
275
270
|
}
|
|
276
|
-
|
|
271
|
+
|
|
277
272
|
const oidcServerConfiguration = await oidc.initAsync(oidc.configuration.authority, oidc.configuration.authority_configuration);
|
|
278
273
|
const url = oidcServerConfiguration.userInfoEndpoint;
|
|
279
274
|
const fetchUserInfo = async (accessToken) => {
|
|
280
275
|
const res = await fetch(url, {
|
|
281
276
|
headers: {
|
|
282
277
|
authorization: `Bearer ${accessToken}`,
|
|
283
|
-
}
|
|
278
|
+
},
|
|
284
279
|
});
|
|
285
280
|
|
|
286
|
-
if(res.status
|
|
281
|
+
if (res.status !== 200) {
|
|
287
282
|
return null;
|
|
288
283
|
}
|
|
289
284
|
|
|
290
285
|
return res.json();
|
|
291
286
|
};
|
|
292
287
|
const userInfo = await fetchUserInfo(accessToken);
|
|
293
|
-
oidc.userInfo= userInfo;
|
|
288
|
+
oidc.userInfo = userInfo;
|
|
294
289
|
return userInfo;
|
|
295
|
-
}
|
|
290
|
+
};
|
|
296
291
|
|
|
297
292
|
const eventNames = {
|
|
298
|
-
service_worker_not_supported_by_browser:
|
|
299
|
-
token_aquired:
|
|
300
|
-
logout_from_another_tab:
|
|
301
|
-
logout_from_same_tab:
|
|
302
|
-
token_renewed:
|
|
303
|
-
token_timer:
|
|
304
|
-
loginAsync_begin:
|
|
305
|
-
loginAsync_error:
|
|
306
|
-
loginCallbackAsync_begin:
|
|
307
|
-
loginCallbackAsync_end:
|
|
308
|
-
loginCallbackAsync_error:
|
|
309
|
-
refreshTokensAsync_begin:
|
|
310
|
-
refreshTokensAsync:
|
|
311
|
-
refreshTokensAsync_end:
|
|
312
|
-
refreshTokensAsync_error:
|
|
313
|
-
refreshTokensAsync_silent_error:
|
|
314
|
-
tryKeepExistingSessionAsync_begin:
|
|
315
|
-
tryKeepExistingSessionAsync_end:
|
|
316
|
-
tryKeepExistingSessionAsync_error:
|
|
317
|
-
silentLoginAsync_begin:
|
|
318
|
-
silentLoginAsync:
|
|
319
|
-
silentLoginAsync_end:
|
|
320
|
-
silentLoginAsync_error:
|
|
321
|
-
syncTokensAsync_begin:
|
|
322
|
-
syncTokensAsync_end:
|
|
323
|
-
syncTokensAsync_error:
|
|
324
|
-
}
|
|
293
|
+
service_worker_not_supported_by_browser: 'service_worker_not_supported_by_browser',
|
|
294
|
+
token_aquired: 'token_aquired',
|
|
295
|
+
logout_from_another_tab: 'logout_from_another_tab',
|
|
296
|
+
logout_from_same_tab: 'logout_from_same_tab',
|
|
297
|
+
token_renewed: 'token_renewed',
|
|
298
|
+
token_timer: 'token_timer',
|
|
299
|
+
loginAsync_begin: 'loginAsync_begin',
|
|
300
|
+
loginAsync_error: 'loginAsync_error',
|
|
301
|
+
loginCallbackAsync_begin: 'loginCallbackAsync_begin',
|
|
302
|
+
loginCallbackAsync_end: 'loginCallbackAsync_end',
|
|
303
|
+
loginCallbackAsync_error: 'loginCallbackAsync_error',
|
|
304
|
+
refreshTokensAsync_begin: 'refreshTokensAsync_begin',
|
|
305
|
+
refreshTokensAsync: 'refreshTokensAsync',
|
|
306
|
+
refreshTokensAsync_end: 'refreshTokensAsync_end',
|
|
307
|
+
refreshTokensAsync_error: 'refreshTokensAsync_error',
|
|
308
|
+
refreshTokensAsync_silent_error: 'refreshTokensAsync_silent_error',
|
|
309
|
+
tryKeepExistingSessionAsync_begin: 'tryKeepExistingSessionAsync_begin',
|
|
310
|
+
tryKeepExistingSessionAsync_end: 'tryKeepExistingSessionAsync_end',
|
|
311
|
+
tryKeepExistingSessionAsync_error: 'tryKeepExistingSessionAsync_error',
|
|
312
|
+
silentLoginAsync_begin: 'silentLoginAsync_begin',
|
|
313
|
+
silentLoginAsync: 'silentLoginAsync',
|
|
314
|
+
silentLoginAsync_end: 'silentLoginAsync_end',
|
|
315
|
+
silentLoginAsync_error: 'silentLoginAsync_error',
|
|
316
|
+
syncTokensAsync_begin: 'syncTokensAsync_begin',
|
|
317
|
+
syncTokensAsync_end: 'syncTokensAsync_end',
|
|
318
|
+
syncTokensAsync_error: 'syncTokensAsync_error',
|
|
319
|
+
};
|
|
325
320
|
|
|
326
321
|
const getRandomInt = (max) => {
|
|
327
322
|
return Math.floor(Math.random() * max);
|
|
328
|
-
}
|
|
323
|
+
};
|
|
329
324
|
|
|
330
325
|
const oneHourSecond = 60 * 60;
|
|
331
|
-
|
|
332
|
-
const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond, storage= window.sessionStorage):
|
|
326
|
+
const fetchFromIssuerCache = {};
|
|
327
|
+
const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHourSecond, storage = window.sessionStorage):
|
|
333
328
|
Promise<OidcAuthorizationServiceConfiguration> => {
|
|
334
329
|
const fullUrl = `${openIdIssuerUrl}/.well-known/openid-configuration`;
|
|
335
|
-
|
|
330
|
+
|
|
336
331
|
const localStorageKey = `oidc.server:${openIdIssuerUrl}`;
|
|
337
|
-
if(!fetchFromIssuerCache[localStorageKey]) {
|
|
338
|
-
if(storage) {
|
|
332
|
+
if (!fetchFromIssuerCache[localStorageKey]) {
|
|
333
|
+
if (storage) {
|
|
339
334
|
const cacheJson = storage.getItem(localStorageKey);
|
|
340
335
|
if (cacheJson) {
|
|
341
336
|
fetchFromIssuerCache[localStorageKey] = JSON.parse(cacheJson);
|
|
@@ -344,24 +339,24 @@ const fetchFromIssuer = async (openIdIssuerUrl: string, timeCacheSecond = oneHou
|
|
|
344
339
|
}
|
|
345
340
|
const oneHourMinisecond = 1000 * timeCacheSecond;
|
|
346
341
|
// @ts-ignore
|
|
347
|
-
if(fetchFromIssuerCache[localStorageKey] && (fetchFromIssuerCache[localStorageKey].timestamp + oneHourMinisecond) > Date.now()){
|
|
342
|
+
if (fetchFromIssuerCache[localStorageKey] && (fetchFromIssuerCache[localStorageKey].timestamp + oneHourMinisecond) > Date.now()) {
|
|
348
343
|
return new OidcAuthorizationServiceConfiguration(fetchFromIssuerCache[localStorageKey].result);
|
|
349
344
|
}
|
|
350
345
|
const response = await fetch(fullUrl);
|
|
351
346
|
|
|
352
|
-
if (response.status
|
|
347
|
+
if (response.status !== 200) {
|
|
353
348
|
return null;
|
|
354
349
|
}
|
|
355
|
-
|
|
350
|
+
|
|
356
351
|
const result = await response.json();
|
|
357
|
-
|
|
352
|
+
|
|
358
353
|
const timestamp = Date.now();
|
|
359
|
-
fetchFromIssuerCache[localStorageKey] = {result, timestamp};
|
|
360
|
-
if(storage) {
|
|
361
|
-
storage.setItem(localStorageKey, JSON.stringify({result, timestamp}));
|
|
354
|
+
fetchFromIssuerCache[localStorageKey] = { result, timestamp };
|
|
355
|
+
if (storage) {
|
|
356
|
+
storage.setItem(localStorageKey, JSON.stringify({ result, timestamp }));
|
|
362
357
|
}
|
|
363
358
|
return new OidcAuthorizationServiceConfiguration(result);
|
|
364
|
-
}
|
|
359
|
+
};
|
|
365
360
|
|
|
366
361
|
export class Oidc {
|
|
367
362
|
public configuration: OidcConfiguration;
|
|
@@ -371,20 +366,20 @@ export class Oidc {
|
|
|
371
366
|
private timeoutId: NodeJS.Timeout;
|
|
372
367
|
private configurationName: string;
|
|
373
368
|
private checkSessionIFrame: CheckSessionIFrame;
|
|
374
|
-
constructor(configuration:OidcConfiguration, configurationName=
|
|
369
|
+
constructor(configuration:OidcConfiguration, configurationName = 'default') {
|
|
375
370
|
let silent_login_uri = configuration.silent_login_uri;
|
|
376
|
-
if(configuration.silent_redirect_uri && !configuration.silent_login_uri){
|
|
377
|
-
silent_login_uri = `${configuration.silent_redirect_uri.replace(
|
|
371
|
+
if (configuration.silent_redirect_uri && !configuration.silent_login_uri) {
|
|
372
|
+
silent_login_uri = `${configuration.silent_redirect_uri.replace('-callback', '').replace('callback', '')}-login`;
|
|
378
373
|
}
|
|
379
374
|
this.configuration = {
|
|
380
|
-
...configuration,
|
|
381
|
-
silent_login_uri,
|
|
375
|
+
...configuration,
|
|
376
|
+
silent_login_uri,
|
|
382
377
|
monitor_session: configuration.monitor_session ?? false,
|
|
383
|
-
refresh_time_before_tokens_expiration_in_second
|
|
378
|
+
refresh_time_before_tokens_expiration_in_second: configuration.refresh_time_before_tokens_expiration_in_second ?? 60,
|
|
384
379
|
silent_login_timeout: configuration.silent_login_timeout ?? 12000,
|
|
385
|
-
token_renew_mode
|
|
380
|
+
token_renew_mode: configuration.token_renew_mode ?? TokenRenewMode.access_token_or_id_token_invalid,
|
|
386
381
|
};
|
|
387
|
-
this.configurationName= configurationName;
|
|
382
|
+
this.configurationName = configurationName;
|
|
388
383
|
this.tokens = null;
|
|
389
384
|
this.userInfo = null;
|
|
390
385
|
this.events = [];
|
|
@@ -394,7 +389,7 @@ export class Oidc {
|
|
|
394
389
|
this.initAsync.bind(this);
|
|
395
390
|
this.loginCallbackAsync.bind(this);
|
|
396
391
|
this._loginCallbackAsync.bind(this);
|
|
397
|
-
this.
|
|
392
|
+
this.subscribeEvents.bind(this);
|
|
398
393
|
this.removeEventSubscription.bind(this);
|
|
399
394
|
this.publishEvent.bind(this);
|
|
400
395
|
this.destroyAsync.bind(this);
|
|
@@ -402,123 +397,130 @@ export class Oidc {
|
|
|
402
397
|
this.renewTokensAsync.bind(this);
|
|
403
398
|
this.initAsync(this.configuration.authority, this.configuration.authority_configuration);
|
|
404
399
|
}
|
|
405
|
-
|
|
400
|
+
|
|
401
|
+
subscribeEvents(func):string {
|
|
406
402
|
const id = getRandomInt(9999999999999).toString();
|
|
407
|
-
this.events.push({id, func});
|
|
403
|
+
this.events.push({ id, func });
|
|
408
404
|
return id;
|
|
409
405
|
}
|
|
410
|
-
|
|
411
|
-
|
|
406
|
+
|
|
407
|
+
removeEventSubscription(id) :void {
|
|
408
|
+
const newEvents = this.events.filter(e => e.id !== id);
|
|
412
409
|
this.events = newEvents;
|
|
413
410
|
}
|
|
414
|
-
|
|
411
|
+
|
|
412
|
+
publishEvent(eventName, data) {
|
|
415
413
|
this.events.forEach(event => {
|
|
416
|
-
event.func(eventName, data)
|
|
414
|
+
event.func(eventName, data);
|
|
417
415
|
});
|
|
418
416
|
}
|
|
419
|
-
|
|
417
|
+
|
|
418
|
+
static getOrCreate(configuration, name = 'default') {
|
|
420
419
|
return oidcFactory(configuration, name);
|
|
421
420
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
421
|
+
|
|
422
|
+
static get(name = 'default') {
|
|
423
|
+
const isInsideBrowser = (typeof process === 'undefined');
|
|
424
|
+
if (!Object.prototype.hasOwnProperty.call(oidcDatabase, name) && isInsideBrowser) {
|
|
425
|
+
throw Error(`OIDC library does seem initialized.
|
|
426
|
+
Please checkout that you are using OIDC hook inside a <OidcProvider configurationName="${name}"></OidcProvider> compoment.`);
|
|
427
427
|
}
|
|
428
428
|
return oidcDatabase[name];
|
|
429
429
|
}
|
|
430
|
+
|
|
430
431
|
static eventNames = eventNames;
|
|
431
|
-
|
|
432
|
-
_silentLoginCallbackFromIFrame(){
|
|
432
|
+
|
|
433
|
+
_silentLoginCallbackFromIFrame() {
|
|
433
434
|
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
434
435
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
435
|
-
window.top.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({tokens:this.tokens, sessionState:queryParams.session_state})}`, window.location.origin);
|
|
436
|
+
window.top.postMessage(`${this.configurationName}_oidc_tokens:${JSON.stringify({ tokens: this.tokens, sessionState: queryParams.session_state })}`, window.location.origin);
|
|
436
437
|
}
|
|
437
438
|
}
|
|
439
|
+
|
|
438
440
|
_silentLoginErrorCallbackFromIFrame() {
|
|
439
441
|
if (this.configuration.silent_redirect_uri && this.configuration.silent_login_uri) {
|
|
440
442
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
441
|
-
window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({error: queryParams.error})}`, window.location.origin);
|
|
443
|
+
window.top.postMessage(`${this.configurationName}_oidc_error:${JSON.stringify({ error: queryParams.error })}`, window.location.origin);
|
|
442
444
|
}
|
|
443
445
|
}
|
|
446
|
+
|
|
444
447
|
async silentLoginCallbackAsync() {
|
|
445
448
|
try {
|
|
446
449
|
await this.loginCallbackAsync(true);
|
|
447
450
|
this._silentLoginCallbackFromIFrame();
|
|
448
451
|
} catch (error) {
|
|
449
|
-
console.error(error)
|
|
452
|
+
console.error(error);
|
|
450
453
|
this._silentLoginErrorCallbackFromIFrame();
|
|
451
454
|
}
|
|
452
455
|
}
|
|
453
|
-
|
|
456
|
+
|
|
457
|
+
async silentLoginAsync(extras:StringMap = null, state:string = null, scope:string = null) {
|
|
454
458
|
if (!this.configuration.silent_redirect_uri || !this.configuration.silent_login_uri) {
|
|
455
459
|
return Promise.resolve(null);
|
|
456
460
|
}
|
|
457
|
-
|
|
461
|
+
|
|
458
462
|
try {
|
|
459
463
|
this.publishEvent(eventNames.silentLoginAsync_begin, {});
|
|
460
|
-
const configuration = this.configuration
|
|
461
|
-
let queries =
|
|
462
|
-
|
|
463
|
-
if(state){
|
|
464
|
-
if(extras == null){
|
|
464
|
+
const configuration = this.configuration;
|
|
465
|
+
let queries = '';
|
|
466
|
+
|
|
467
|
+
if (state) {
|
|
468
|
+
if (extras == null) {
|
|
465
469
|
extras = {};
|
|
466
470
|
}
|
|
467
471
|
extras.state = state;
|
|
468
472
|
}
|
|
469
|
-
|
|
470
|
-
if(scope){
|
|
471
|
-
if(extras == null){
|
|
473
|
+
|
|
474
|
+
if (scope) {
|
|
475
|
+
if (extras == null) {
|
|
472
476
|
extras = {};
|
|
473
477
|
}
|
|
474
478
|
extras.scope = scope;
|
|
475
479
|
}
|
|
476
|
-
|
|
477
|
-
if(extras != null){
|
|
478
|
-
for (
|
|
479
|
-
if (queries ===
|
|
480
|
-
queries = `?${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
480
|
+
|
|
481
|
+
if (extras != null) {
|
|
482
|
+
for (const [key, value] of Object.entries(extras)) {
|
|
483
|
+
if (queries === '') {
|
|
484
|
+
queries = `?${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
481
485
|
} else {
|
|
482
|
-
queries+= `&${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
486
|
+
queries += `&${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
483
487
|
}
|
|
484
488
|
}
|
|
485
489
|
}
|
|
486
|
-
const link = configuration.silent_login_uri
|
|
487
|
-
const idx = link.indexOf(
|
|
490
|
+
const link = configuration.silent_login_uri + queries;
|
|
491
|
+
const idx = link.indexOf('/', link.indexOf('//') + 2);
|
|
488
492
|
const iFrameOrigin = link.substr(0, idx);
|
|
489
493
|
const iframe = document.createElement('iframe');
|
|
490
|
-
iframe.width =
|
|
491
|
-
iframe.height =
|
|
492
|
-
|
|
494
|
+
iframe.width = '0px';
|
|
495
|
+
iframe.height = '0px';
|
|
496
|
+
|
|
493
497
|
iframe.id = `${this.configurationName}_oidc_iframe`;
|
|
494
|
-
iframe.setAttribute(
|
|
498
|
+
iframe.setAttribute('src', link);
|
|
495
499
|
document.body.appendChild(iframe);
|
|
496
|
-
const self = this;
|
|
497
500
|
return new Promise((resolve, reject) => {
|
|
498
501
|
try {
|
|
499
502
|
let isResolved = false;
|
|
500
|
-
window.onmessage =
|
|
503
|
+
window.onmessage = (e: MessageEvent<any>) => {
|
|
501
504
|
if (e.origin === iFrameOrigin &&
|
|
502
505
|
e.source === iframe.contentWindow
|
|
503
506
|
) {
|
|
504
|
-
const key = `${
|
|
505
|
-
const key_error = `${
|
|
507
|
+
const key = `${this.configurationName}_oidc_tokens:`;
|
|
508
|
+
const key_error = `${this.configurationName}_oidc_error:`;
|
|
506
509
|
const data = e.data;
|
|
507
|
-
if (data && typeof (data) ===
|
|
510
|
+
if (data && typeof (data) === 'string') {
|
|
508
511
|
if (!isResolved) {
|
|
509
|
-
if(data.startsWith(key)) {
|
|
512
|
+
if (data.startsWith(key)) {
|
|
510
513
|
const result = JSON.parse(e.data.replace(key, ''));
|
|
511
|
-
|
|
514
|
+
this.publishEvent(eventNames.silentLoginAsync_end, {});
|
|
512
515
|
iframe.remove();
|
|
513
516
|
isResolved = true;
|
|
514
517
|
resolve(result);
|
|
515
|
-
}
|
|
516
|
-
else if(data.startsWith(key_error)) {
|
|
518
|
+
} else if (data.startsWith(key_error)) {
|
|
517
519
|
const result = JSON.parse(e.data.replace(key_error, ''));
|
|
518
|
-
|
|
520
|
+
this.publishEvent(eventNames.silentLoginAsync_error, result);
|
|
519
521
|
iframe.remove();
|
|
520
522
|
isResolved = true;
|
|
521
|
-
reject(new Error(
|
|
523
|
+
reject(new Error('oidc_' + result.error));
|
|
522
524
|
}
|
|
523
525
|
}
|
|
524
526
|
}
|
|
@@ -527,15 +529,15 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
527
529
|
const silentSigninTimeout = configuration.silent_login_timeout;
|
|
528
530
|
setTimeout(() => {
|
|
529
531
|
if (!isResolved) {
|
|
530
|
-
|
|
532
|
+
this.publishEvent(eventNames.silentLoginAsync_error, { reason: 'timeout' });
|
|
531
533
|
iframe.remove();
|
|
532
534
|
isResolved = true;
|
|
533
|
-
reject(new Error(
|
|
535
|
+
reject(new Error('timeout'));
|
|
534
536
|
}
|
|
535
537
|
}, silentSigninTimeout);
|
|
536
538
|
} catch (e) {
|
|
537
539
|
iframe.remove();
|
|
538
|
-
|
|
540
|
+
this.publishEvent(eventNames.silentLoginAsync_error, e);
|
|
539
541
|
reject(e);
|
|
540
542
|
}
|
|
541
543
|
});
|
|
@@ -544,9 +546,10 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
544
546
|
throw e;
|
|
545
547
|
}
|
|
546
548
|
}
|
|
549
|
+
|
|
547
550
|
initPromise = null;
|
|
548
551
|
async initAsync(authority:string, authorityConfiguration:AuthorityConfiguration) {
|
|
549
|
-
if(this.initPromise !== null){
|
|
552
|
+
if (this.initPromise !== null) {
|
|
550
553
|
return this.initPromise;
|
|
551
554
|
}
|
|
552
555
|
const localFuncAsync = async () => {
|
|
@@ -565,21 +568,21 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
565
568
|
const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
|
|
566
569
|
const storage = serviceWorker ? window.localStorage : null;
|
|
567
570
|
return await fetchFromIssuer(authority, this.configuration.authority_time_cache_wellknowurl_in_second ?? 60 * 60, storage);
|
|
568
|
-
}
|
|
571
|
+
};
|
|
569
572
|
this.initPromise = localFuncAsync();
|
|
570
|
-
return this.initPromise.then((result) =>{
|
|
573
|
+
return this.initPromise.then((result) => {
|
|
571
574
|
this.initPromise = null;
|
|
572
575
|
return result;
|
|
573
|
-
})
|
|
576
|
+
});
|
|
574
577
|
}
|
|
575
578
|
|
|
576
579
|
tryKeepExistingSessionPromise = null;
|
|
577
580
|
async tryKeepExistingSessionAsync() :Promise<boolean> {
|
|
578
|
-
if(this.tryKeepExistingSessionPromise !== null){
|
|
581
|
+
if (this.tryKeepExistingSessionPromise !== null) {
|
|
579
582
|
return this.tryKeepExistingSessionPromise;
|
|
580
583
|
}
|
|
581
|
-
const funcAsync
|
|
582
|
-
let serviceWorker
|
|
584
|
+
const funcAsync = async () => {
|
|
585
|
+
let serviceWorker;
|
|
583
586
|
if (this.tokens != null) {
|
|
584
587
|
return false;
|
|
585
588
|
}
|
|
@@ -589,7 +592,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
589
592
|
const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
|
|
590
593
|
serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
|
|
591
594
|
if (serviceWorker) {
|
|
592
|
-
const {tokens} = await serviceWorker.initAsync(oidcServerConfiguration,
|
|
595
|
+
const { tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'tryKeepExistingSessionAsync', configuration);
|
|
593
596
|
if (tokens) {
|
|
594
597
|
serviceWorker.startKeepAliveServiceWorker();
|
|
595
598
|
// @ts-ignore
|
|
@@ -601,22 +604,22 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
601
604
|
await this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState);
|
|
602
605
|
this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
|
|
603
606
|
success: true,
|
|
604
|
-
message:
|
|
607
|
+
message: 'tokens inside ServiceWorker are valid',
|
|
605
608
|
});
|
|
606
609
|
return true;
|
|
607
610
|
}
|
|
608
611
|
this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
|
|
609
612
|
success: false,
|
|
610
|
-
message:
|
|
613
|
+
message: 'no exiting session found',
|
|
611
614
|
});
|
|
612
615
|
} else {
|
|
613
616
|
if (configuration.service_worker_relative_url) {
|
|
614
617
|
this.publishEvent(eventNames.service_worker_not_supported_by_browser, {
|
|
615
|
-
message:
|
|
618
|
+
message: 'service worker is not supported by this browser',
|
|
616
619
|
});
|
|
617
620
|
}
|
|
618
621
|
const session = initSession(this.configurationName, configuration.redirect_uri, configuration.storage ?? sessionStorage);
|
|
619
|
-
const {tokens} = await session.initAsync();
|
|
622
|
+
const { tokens } = await session.initAsync();
|
|
620
623
|
if (tokens) {
|
|
621
624
|
// @ts-ignore
|
|
622
625
|
this.tokens = setTokens(tokens, null, configuration.token_renew_mode);
|
|
@@ -627,14 +630,14 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
627
630
|
await this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, configuration.client_id, sessionState);
|
|
628
631
|
this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
|
|
629
632
|
success: true,
|
|
630
|
-
message:
|
|
633
|
+
message: 'tokens inside storage are valid',
|
|
631
634
|
});
|
|
632
635
|
return true;
|
|
633
636
|
}
|
|
634
637
|
}
|
|
635
638
|
this.publishEvent(eventNames.tryKeepExistingSessionAsync_end, {
|
|
636
639
|
success: false,
|
|
637
|
-
message: serviceWorker ?
|
|
640
|
+
message: serviceWorker ? 'service worker sessions not retrieved' : 'session storage sessions not retrieved',
|
|
638
641
|
});
|
|
639
642
|
return false;
|
|
640
643
|
} catch (exception) {
|
|
@@ -642,37 +645,38 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
642
645
|
if (serviceWorker) {
|
|
643
646
|
await serviceWorker.clearAsync();
|
|
644
647
|
}
|
|
645
|
-
this.publishEvent(eventNames.tryKeepExistingSessionAsync_error,
|
|
648
|
+
this.publishEvent(eventNames.tryKeepExistingSessionAsync_error, 'tokens inside ServiceWorker are invalid');
|
|
646
649
|
return false;
|
|
647
650
|
}
|
|
648
|
-
}
|
|
649
|
-
|
|
651
|
+
};
|
|
652
|
+
|
|
650
653
|
this.tryKeepExistingSessionPromise = funcAsync();
|
|
651
654
|
return this.tryKeepExistingSessionPromise.then((result) => {
|
|
652
|
-
this.tryKeepExistingSessionPromise =null;
|
|
655
|
+
this.tryKeepExistingSessionPromise = null;
|
|
653
656
|
return result;
|
|
654
657
|
});
|
|
655
658
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
+
|
|
660
|
+
loginPromise: Promise<void> = null;
|
|
661
|
+
async loginAsync(callbackPath:string = undefined, extras:StringMap = null, isSilentSignin = false, scope:string = undefined, silentLoginOnly = false) {
|
|
662
|
+
if (this.loginPromise !== null) {
|
|
659
663
|
return this.loginPromise;
|
|
660
664
|
}
|
|
661
|
-
const loginLocalAsync=async () => {
|
|
665
|
+
const loginLocalAsync = async () => {
|
|
662
666
|
const location = window.location;
|
|
663
667
|
const url = callbackPath || location.pathname + (location.search || '') + (location.hash || '');
|
|
664
668
|
const configuration = this.configuration;
|
|
665
|
-
let state
|
|
666
|
-
if(extras &&
|
|
667
|
-
state = extras
|
|
668
|
-
delete extras
|
|
669
|
+
let state;
|
|
670
|
+
if (extras && 'state' in extras) {
|
|
671
|
+
state = extras.state;
|
|
672
|
+
delete extras.state;
|
|
669
673
|
}
|
|
670
|
-
if(silentLoginOnly){
|
|
674
|
+
if (silentLoginOnly) {
|
|
671
675
|
try {
|
|
672
676
|
const extraFinal = extras ?? configuration.extras ?? {};
|
|
673
677
|
const silentResult = await this.silentLoginAsync({
|
|
674
678
|
...extraFinal,
|
|
675
|
-
prompt:
|
|
679
|
+
prompt: 'none',
|
|
676
680
|
}, state, scope);
|
|
677
681
|
|
|
678
682
|
if (silentResult) {
|
|
@@ -682,42 +686,41 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
682
686
|
this.timeoutId = autoRenewTokens(this, this.tokens.refreshToken, this.tokens.expiresAt, extras);
|
|
683
687
|
return {};
|
|
684
688
|
}
|
|
685
|
-
}catch (e) {
|
|
689
|
+
} catch (e) {
|
|
686
690
|
return e;
|
|
687
691
|
}
|
|
688
692
|
}
|
|
689
693
|
this.publishEvent(eventNames.loginAsync_begin, {});
|
|
690
|
-
|
|
694
|
+
|
|
691
695
|
try {
|
|
692
696
|
const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
|
|
693
697
|
if (!scope) {
|
|
694
698
|
scope = configuration.scope;
|
|
695
699
|
}
|
|
696
700
|
|
|
697
|
-
setLoginParams(this.configurationName, redirectUri, {callbackPath: url, extras, state});
|
|
701
|
+
setLoginParams(this.configurationName, redirectUri, { callbackPath: url, extras, state });
|
|
698
702
|
const extraFinal = extras ?? configuration.extras ?? {};
|
|
699
|
-
if(!extraFinal.nonce) {
|
|
700
|
-
extraFinal
|
|
703
|
+
if (!extraFinal.nonce) {
|
|
704
|
+
extraFinal.nonce = randomString(12);
|
|
701
705
|
}
|
|
702
|
-
const nonce = {
|
|
703
|
-
|
|
706
|
+
const nonce = { nonce: extraFinal.nonce };
|
|
707
|
+
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
|
|
704
708
|
const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
|
|
705
709
|
let storage;
|
|
706
710
|
if (serviceWorker) {
|
|
707
711
|
serviceWorker.startKeepAliveServiceWorker();
|
|
708
|
-
await serviceWorker.initAsync(oidcServerConfiguration,
|
|
712
|
+
await serviceWorker.initAsync(oidcServerConfiguration, 'loginAsync', configuration);
|
|
709
713
|
await serviceWorker.setNonceAsync(nonce);
|
|
710
714
|
storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, {});
|
|
711
|
-
await storage.setItem(
|
|
712
|
-
|
|
715
|
+
await storage.setItem('dummy', {});
|
|
713
716
|
} else {
|
|
714
717
|
const session = initSession(this.configurationName, redirectUri);
|
|
715
718
|
await session.setNonceAsync(nonce);
|
|
716
719
|
storage = new MemoryStorageBackend(session.saveItemsAsync, {});
|
|
717
720
|
}
|
|
718
|
-
|
|
721
|
+
|
|
719
722
|
// @ts-ignore
|
|
720
|
-
const queryStringUtil = redirectUri.includes(
|
|
723
|
+
const queryStringUtil = redirectUri.includes('#') ? new HashQueryStringUtils() : new NoHashQueryStringUtils();
|
|
721
724
|
const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
|
|
722
725
|
const authRequest = new AuthorizationRequest({
|
|
723
726
|
client_id: configuration.client_id,
|
|
@@ -725,28 +728,28 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
725
728
|
scope,
|
|
726
729
|
response_type: AuthorizationRequest.RESPONSE_TYPE_CODE,
|
|
727
730
|
state,
|
|
728
|
-
extras: extraFinal
|
|
731
|
+
extras: extraFinal,
|
|
729
732
|
});
|
|
730
733
|
authorizationHandler.performAuthorizationRequest(oidcServerConfiguration, authRequest);
|
|
731
734
|
} catch (exception) {
|
|
732
735
|
this.publishEvent(eventNames.loginAsync_error, exception);
|
|
733
736
|
throw exception;
|
|
734
737
|
}
|
|
735
|
-
}
|
|
738
|
+
};
|
|
736
739
|
this.loginPromise = loginLocalAsync();
|
|
737
|
-
return this.loginPromise.then(result =>{
|
|
740
|
+
return this.loginPromise.then(result => {
|
|
738
741
|
this.loginPromise = null;
|
|
739
742
|
return result;
|
|
740
743
|
});
|
|
741
744
|
}
|
|
742
|
-
|
|
743
|
-
async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin=false){
|
|
744
|
-
return new Promise((resolve
|
|
745
|
+
|
|
746
|
+
async startCheckSessionAsync(checkSessionIFrameUri, clientId, sessionState, isSilentSignin = false) {
|
|
747
|
+
return new Promise<void>((resolve, reject): void => {
|
|
745
748
|
if (this.configuration.silent_login_uri && this.configuration.silent_redirect_uri && this.configuration.monitor_session && checkSessionIFrameUri && sessionState && !isSilentSignin) {
|
|
746
749
|
const checkSessionCallback = () => {
|
|
747
750
|
this.checkSessionIFrame.stop();
|
|
748
|
-
|
|
749
|
-
if(this.tokens === null){
|
|
751
|
+
|
|
752
|
+
if (this.tokens === null) {
|
|
750
753
|
return;
|
|
751
754
|
}
|
|
752
755
|
// @ts-ignore
|
|
@@ -754,33 +757,33 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
754
757
|
// @ts-ignore
|
|
755
758
|
const idTokenPayload = this.tokens.idTokenPayload;
|
|
756
759
|
this.silentLoginAsync({
|
|
757
|
-
prompt:
|
|
760
|
+
prompt: 'none',
|
|
758
761
|
id_token_hint: idToken,
|
|
759
|
-
scope:
|
|
762
|
+
scope: 'openid',
|
|
760
763
|
}).then((silentSigninResponse) => {
|
|
761
764
|
const iFrameIdTokenPayload = silentSigninResponse.tokens.idTokenPayload;
|
|
762
765
|
if (idTokenPayload.sub === iFrameIdTokenPayload.sub) {
|
|
763
766
|
const sessionState = silentSigninResponse.sessionState;
|
|
764
767
|
this.checkSessionIFrame.start(silentSigninResponse.sessionState);
|
|
765
768
|
if (idTokenPayload.sid === iFrameIdTokenPayload.sid) {
|
|
766
|
-
console.debug(
|
|
769
|
+
console.debug('SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:', sessionState);
|
|
767
770
|
} else {
|
|
768
|
-
console.debug(
|
|
771
|
+
console.debug('SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:', sessionState);
|
|
769
772
|
}
|
|
773
|
+
} else {
|
|
774
|
+
console.debug('SessionMonitor._callback: Different subject signed into OP:', iFrameIdTokenPayload.sub);
|
|
770
775
|
}
|
|
771
|
-
|
|
772
|
-
console.debug("SessionMonitor._callback: Different subject signed into OP:", iFrameIdTokenPayload.sub);
|
|
773
|
-
}
|
|
776
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
774
777
|
}).catch(async (e) => {
|
|
778
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
775
779
|
for (const [key, oidc] of Object.entries(oidcDatabase)) {
|
|
776
|
-
//if(oidc !== this) {
|
|
780
|
+
// if(oidc !== this) {
|
|
777
781
|
// @ts-ignore
|
|
778
782
|
await oidc.logoutOtherTabAsync(this.configuration.client_id, idTokenPayload.sub);
|
|
779
|
-
//}
|
|
783
|
+
// }
|
|
780
784
|
}
|
|
781
|
-
//await this.destroyAsync();
|
|
782
|
-
//this.publishEvent(eventNames.logout_from_another_tab, {message : "SessionMonitor"});
|
|
783
|
-
|
|
785
|
+
// await this.destroyAsync();
|
|
786
|
+
// this.publishEvent(eventNames.logout_from_another_tab, {message : "SessionMonitor"});
|
|
784
787
|
});
|
|
785
788
|
};
|
|
786
789
|
|
|
@@ -788,7 +791,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
788
791
|
this.checkSessionIFrame.load().then(() => {
|
|
789
792
|
this.checkSessionIFrame.start(sessionState);
|
|
790
793
|
resolve();
|
|
791
|
-
}).catch((e) =>{
|
|
794
|
+
}).catch((e) => {
|
|
792
795
|
reject(e);
|
|
793
796
|
});
|
|
794
797
|
} else {
|
|
@@ -797,62 +800,61 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
797
800
|
});
|
|
798
801
|
}
|
|
799
802
|
|
|
800
|
-
loginCallbackPromise : Promise<any
|
|
801
|
-
async loginCallbackAsync(isSilenSignin
|
|
802
|
-
if(this.loginCallbackPromise !== null){
|
|
803
|
+
loginCallbackPromise : Promise<any> = null;
|
|
804
|
+
async loginCallbackAsync(isSilenSignin = false) {
|
|
805
|
+
if (this.loginCallbackPromise !== null) {
|
|
803
806
|
return this.loginCallbackPromise;
|
|
804
807
|
}
|
|
805
|
-
|
|
806
|
-
const loginCallbackLocalAsync= async():Promise<InternalLoginCallback> =>{
|
|
808
|
+
|
|
809
|
+
const loginCallbackLocalAsync = async():Promise<InternalLoginCallback> => {
|
|
807
810
|
const response = await this._loginCallbackAsync(isSilenSignin);
|
|
808
811
|
// @ts-ignore
|
|
809
812
|
const parsedTokens = response.tokens;
|
|
810
813
|
// @ts-ignore
|
|
811
814
|
this.tokens = response.tokens;
|
|
812
|
-
const
|
|
813
|
-
const serviceWorker = await initWorkerAsync(oidc.configuration.service_worker_relative_url, oidc.configurationName);
|
|
815
|
+
const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
|
|
814
816
|
if (!serviceWorker) {
|
|
815
|
-
const session = initSession(this.configurationName,
|
|
816
|
-
|
|
817
|
+
const session = initSession(this.configurationName, this.configuration.redirect_uri, this.configuration.storage);
|
|
818
|
+
session.setTokens(parsedTokens);
|
|
817
819
|
}
|
|
818
820
|
this.publishEvent(Oidc.eventNames.token_aquired, parsedTokens);
|
|
819
821
|
// @ts-ignore
|
|
820
|
-
return
|
|
821
|
-
}
|
|
822
|
+
return { parsedTokens, state: response.state, callbackPath: response.callbackPath };
|
|
823
|
+
};
|
|
822
824
|
this.loginCallbackPromise = loginCallbackLocalAsync();
|
|
823
|
-
return this.loginCallbackPromise.then(result =>{
|
|
825
|
+
return this.loginCallbackPromise.then(result => {
|
|
824
826
|
this.loginCallbackPromise = null;
|
|
825
827
|
return result;
|
|
826
|
-
})
|
|
828
|
+
});
|
|
827
829
|
}
|
|
828
|
-
|
|
829
|
-
async _loginCallbackAsync(isSilentSignin
|
|
830
|
+
|
|
831
|
+
async _loginCallbackAsync(isSilentSignin = false) {
|
|
830
832
|
try {
|
|
831
833
|
this.publishEvent(eventNames.loginCallbackAsync_begin, {});
|
|
832
834
|
const configuration = this.configuration;
|
|
833
835
|
const clientId = configuration.client_id;
|
|
834
836
|
const redirectUri = isSilentSignin ? configuration.silent_redirect_uri : configuration.redirect_uri;
|
|
835
|
-
const authority =
|
|
836
|
-
const tokenRequestTimeout =
|
|
837
|
+
const authority = configuration.authority;
|
|
838
|
+
const tokenRequestTimeout = configuration.token_request_timeout;
|
|
837
839
|
const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
|
|
838
840
|
const queryParams = getParseQueryStringFromLocation(window.location.href);
|
|
839
|
-
const sessionState =
|
|
841
|
+
const sessionState = queryParams.session_state;
|
|
840
842
|
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, this.configurationName);
|
|
841
843
|
let storage = null;
|
|
842
844
|
let nonceData = null;
|
|
843
|
-
if(serviceWorker){
|
|
845
|
+
if (serviceWorker) {
|
|
844
846
|
serviceWorker.startKeepAliveServiceWorker();
|
|
845
|
-
await serviceWorker.initAsync(oidcServerConfiguration,
|
|
847
|
+
await serviceWorker.initAsync(oidcServerConfiguration, 'loginCallbackAsync', configuration);
|
|
846
848
|
const items = await serviceWorker.loadItemsAsync();
|
|
847
849
|
storage = new MemoryStorageBackend(serviceWorker.saveItemsAsync, items);
|
|
848
|
-
const dummy =await storage.getItem(
|
|
849
|
-
if(!dummy){
|
|
850
|
-
throw new Error(
|
|
850
|
+
const dummy = await storage.getItem('dummy');
|
|
851
|
+
if (!dummy) {
|
|
852
|
+
throw new Error('Service Worker storage disapear');
|
|
851
853
|
}
|
|
852
|
-
await storage.removeItem(
|
|
854
|
+
await storage.removeItem('dummy');
|
|
853
855
|
await serviceWorker.setSessionStateAsync(sessionState);
|
|
854
856
|
nonceData = await serviceWorker.getNonceAsync();
|
|
855
|
-
}else{
|
|
857
|
+
} else {
|
|
856
858
|
const session = initSession(this.configurationName, redirectUri);
|
|
857
859
|
session.setSessionState(sessionState);
|
|
858
860
|
const items = await session.loadItemsAsync();
|
|
@@ -861,26 +863,24 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
861
863
|
}
|
|
862
864
|
|
|
863
865
|
return new Promise((resolve, reject) => {
|
|
864
|
-
// @ts-ignore
|
|
865
866
|
let queryStringUtil = new NoHashQueryStringUtils();
|
|
866
|
-
if(redirectUri.includes(
|
|
867
|
-
const splithash = window.location.href.split(
|
|
868
|
-
if (splithash.length === 2 && splithash[1].includes(
|
|
867
|
+
if (redirectUri.includes('#')) {
|
|
868
|
+
const splithash = window.location.href.split('#');
|
|
869
|
+
if (splithash.length === 2 && splithash[1].includes('?')) {
|
|
869
870
|
queryStringUtil = new HashQueryStringUtils();
|
|
870
871
|
}
|
|
871
872
|
}
|
|
872
|
-
|
|
873
|
-
const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location , new DefaultCrypto());
|
|
873
|
+
const authorizationHandler = new RedirectRequestHandler(storage, queryStringUtil, window.location, new DefaultCrypto());
|
|
874
874
|
const notifier = new AuthorizationNotifier();
|
|
875
875
|
authorizationHandler.setAuthorizationNotifier(notifier);
|
|
876
876
|
|
|
877
|
-
notifier.setAuthorizationListener(
|
|
877
|
+
notifier.setAuthorizationListener((request, response, error) => {
|
|
878
878
|
if (error) {
|
|
879
879
|
reject(error);
|
|
880
880
|
return;
|
|
881
881
|
}
|
|
882
882
|
if (!response) {
|
|
883
|
-
reject(
|
|
883
|
+
reject(new Error('no response'));
|
|
884
884
|
return;
|
|
885
885
|
}
|
|
886
886
|
|
|
@@ -889,7 +889,7 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
889
889
|
extras = {};
|
|
890
890
|
extras.code_verifier = request.internal.code_verifier;
|
|
891
891
|
if (configuration.token_request_extras) {
|
|
892
|
-
for (
|
|
892
|
+
for (const [key, value] of Object.entries(configuration.token_request_extras)) {
|
|
893
893
|
extras[key] = value;
|
|
894
894
|
}
|
|
895
895
|
}
|
|
@@ -904,37 +904,35 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
904
904
|
extras,
|
|
905
905
|
});
|
|
906
906
|
|
|
907
|
-
let timeoutId = setTimeout(()=>{
|
|
908
|
-
reject(
|
|
909
|
-
timeoutId=null;
|
|
907
|
+
let timeoutId = setTimeout(() => {
|
|
908
|
+
reject(new Error('performTokenRequest timeout'));
|
|
909
|
+
timeoutId = null;
|
|
910
910
|
}, tokenRequestTimeout ?? 12000);
|
|
911
911
|
try {
|
|
912
912
|
const tokenHandler = new BaseTokenRequestHandler(new FetchRequestor());
|
|
913
913
|
tokenHandler.performTokenRequest(oidcServerConfiguration, tokenRequest).then(async (tokenResponse) => {
|
|
914
|
-
|
|
915
914
|
if (timeoutId) {
|
|
916
915
|
clearTimeout(timeoutId);
|
|
917
916
|
this.timeoutId = null;
|
|
918
917
|
const loginParams = getLoginParams(this.configurationName, redirectUri);
|
|
919
918
|
let formattedTokens = null;
|
|
920
919
|
if (serviceWorker) {
|
|
921
|
-
const {tokens} = await serviceWorker.initAsync(oidcServerConfiguration,
|
|
920
|
+
const { tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'syncTokensAsync', configuration);
|
|
922
921
|
formattedTokens = tokens;
|
|
923
|
-
} else{
|
|
922
|
+
} else {
|
|
924
923
|
formattedTokens = setTokens(tokenResponse, null, configuration.token_renew_mode);
|
|
925
924
|
}
|
|
926
|
-
if(!isTokensOidcValid(formattedTokens, nonceData.nonce, oidcServerConfiguration)){
|
|
927
|
-
const exception = new Error(
|
|
928
|
-
if(timeoutId) {
|
|
925
|
+
if (!isTokensOidcValid(formattedTokens, nonceData.nonce, oidcServerConfiguration)) {
|
|
926
|
+
const exception = new Error('Tokens are not OpenID valid');
|
|
927
|
+
if (timeoutId) {
|
|
929
928
|
clearTimeout(timeoutId);
|
|
930
|
-
this.timeoutId=null;
|
|
929
|
+
this.timeoutId = null;
|
|
931
930
|
this.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
932
931
|
console.error(exception);
|
|
933
932
|
reject(exception);
|
|
934
933
|
}
|
|
935
934
|
}
|
|
936
935
|
|
|
937
|
-
// @ts-ignore
|
|
938
936
|
this.startCheckSessionAsync(oidcServerConfiguration.check_session_iframe, clientId, sessionState, isSilentSignin).then(() => {
|
|
939
937
|
this.publishEvent(eventNames.loginCallbackAsync_end, {});
|
|
940
938
|
resolve({
|
|
@@ -946,9 +944,9 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
946
944
|
}
|
|
947
945
|
});
|
|
948
946
|
} catch (exception) {
|
|
949
|
-
if(timeoutId) {
|
|
947
|
+
if (timeoutId) {
|
|
950
948
|
clearTimeout(timeoutId);
|
|
951
|
-
this.timeoutId=null;
|
|
949
|
+
this.timeoutId = null;
|
|
952
950
|
this.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
953
951
|
console.error(exception);
|
|
954
952
|
reject(exception);
|
|
@@ -957,267 +955,265 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
957
955
|
});
|
|
958
956
|
authorizationHandler.completeAuthorizationRequestIfPossible();
|
|
959
957
|
});
|
|
960
|
-
} catch(exception) {
|
|
958
|
+
} catch (exception) {
|
|
961
959
|
console.error(exception);
|
|
962
960
|
this.publishEvent(eventNames.loginCallbackAsync_error, exception);
|
|
963
961
|
throw exception;
|
|
964
962
|
}
|
|
965
963
|
}
|
|
966
964
|
|
|
967
|
-
async synchroniseTokensAsync(refreshToken, index=0, forceRefresh =false, extras:StringMap=null, updateTokens) {
|
|
965
|
+
async synchroniseTokensAsync(refreshToken, index = 0, forceRefresh = false, extras:StringMap = null, updateTokens) {
|
|
968
966
|
if (document.hidden) {
|
|
969
967
|
await sleepAsync(1000);
|
|
970
|
-
this.publishEvent(eventNames.refreshTokensAsync, {message:
|
|
968
|
+
this.publishEvent(eventNames.refreshTokensAsync, { message: 'wait because document is hidden' });
|
|
971
969
|
return await this.synchroniseTokensAsync(refreshToken, index, forceRefresh, extras, updateTokens);
|
|
972
970
|
}
|
|
973
971
|
let numberTryOnline = 6;
|
|
974
972
|
while (!navigator.onLine && numberTryOnline > 0) {
|
|
975
973
|
await sleepAsync(1000);
|
|
976
974
|
numberTryOnline--;
|
|
977
|
-
this.publishEvent(eventNames.refreshTokensAsync, {message: `wait because navigator is offline try ${numberTryOnline}` });
|
|
975
|
+
this.publishEvent(eventNames.refreshTokensAsync, { message: `wait because navigator is offline try ${numberTryOnline}` });
|
|
978
976
|
}
|
|
979
|
-
if(!extras){
|
|
980
|
-
extras = {}
|
|
977
|
+
if (!extras) {
|
|
978
|
+
extras = {};
|
|
981
979
|
}
|
|
982
980
|
const configuration = this.configuration;
|
|
983
|
-
const localsilentLoginAsync= async () => {
|
|
981
|
+
const localsilentLoginAsync = async () => {
|
|
984
982
|
try {
|
|
985
983
|
const loginParams = getLoginParams(this.configurationName, configuration.redirect_uri);
|
|
986
|
-
|
|
984
|
+
|
|
987
985
|
const silent_token_response = await this.silentLoginAsync({
|
|
988
986
|
...loginParams.extras,
|
|
989
987
|
...extras,
|
|
990
|
-
prompt:
|
|
988
|
+
prompt: 'none',
|
|
991
989
|
}, loginParams.state);
|
|
992
990
|
if (silent_token_response) {
|
|
993
991
|
updateTokens(silent_token_response.tokens);
|
|
994
992
|
this.publishEvent(Oidc.eventNames.token_renewed, {});
|
|
995
|
-
return {tokens:silent_token_response.tokens, status:
|
|
993
|
+
return { tokens: silent_token_response.tokens, status: 'LOGGED' };
|
|
996
994
|
}
|
|
997
995
|
} catch (exceptionSilent) {
|
|
998
996
|
console.error(exceptionSilent);
|
|
999
|
-
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message:
|
|
1000
|
-
if(exceptionSilent && exceptionSilent.message && exceptionSilent.message.startsWith(
|
|
997
|
+
this.publishEvent(eventNames.refreshTokensAsync_silent_error, { message: 'exceptionSilent', exception: exceptionSilent.message });
|
|
998
|
+
if (exceptionSilent && exceptionSilent.message && exceptionSilent.message.startsWith('oidc')) {
|
|
1001
999
|
updateTokens(null);
|
|
1002
|
-
this.publishEvent(eventNames.refreshTokensAsync_error, {message:
|
|
1003
|
-
return {tokens:null, status:
|
|
1004
|
-
}
|
|
1000
|
+
this.publishEvent(eventNames.refreshTokensAsync_error, { message: 'refresh token silent' });
|
|
1001
|
+
return { tokens: null, status: 'SESSION_LOST' };
|
|
1002
|
+
}
|
|
1005
1003
|
await sleepAsync(1000);
|
|
1006
1004
|
throw exceptionSilent;
|
|
1007
1005
|
}
|
|
1008
1006
|
updateTokens(null);
|
|
1009
|
-
this.publishEvent(eventNames.refreshTokensAsync_error, {message:
|
|
1010
|
-
return {tokens:null, status:
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
if (index <=4) {
|
|
1007
|
+
this.publishEvent(eventNames.refreshTokensAsync_error, { message: 'refresh token silent return' });
|
|
1008
|
+
return { tokens: null, status: 'SESSION_LOST' };
|
|
1009
|
+
};
|
|
1010
|
+
|
|
1011
|
+
if (index <= 4) {
|
|
1014
1012
|
try {
|
|
1015
1013
|
const { status, tokens, nonce } = await this.syncTokensInfoAsync(configuration, this.configurationName, this.tokens, forceRefresh);
|
|
1016
1014
|
switch (status) {
|
|
1017
|
-
case
|
|
1015
|
+
case 'SESSION_LOST':
|
|
1018
1016
|
updateTokens(null);
|
|
1019
|
-
this.publishEvent(eventNames.refreshTokensAsync_error, {message:
|
|
1020
|
-
return {tokens:null, status:
|
|
1021
|
-
case
|
|
1017
|
+
this.publishEvent(eventNames.refreshTokensAsync_error, { message: 'refresh token session lost' });
|
|
1018
|
+
return { tokens: null, status: 'SESSION_LOST' };
|
|
1019
|
+
case 'NOT_CONNECTED':
|
|
1022
1020
|
updateTokens(null);
|
|
1023
|
-
return {tokens:null, status:null};
|
|
1024
|
-
case
|
|
1021
|
+
return { tokens: null, status: null };
|
|
1022
|
+
case 'TOKENS_VALID':
|
|
1025
1023
|
updateTokens(tokens);
|
|
1026
|
-
return {tokens, status:
|
|
1027
|
-
case
|
|
1024
|
+
return { tokens, status: 'LOGGED_IN' };
|
|
1025
|
+
case 'TOKEN_UPDATED_BY_ANOTHER_TAB_TOKENS_VALID':
|
|
1028
1026
|
updateTokens(tokens);
|
|
1029
1027
|
this.publishEvent(Oidc.eventNames.token_renewed, {});
|
|
1030
|
-
return {tokens, status:
|
|
1031
|
-
case
|
|
1028
|
+
return { tokens, status: 'LOGGED_IN' };
|
|
1029
|
+
case 'LOGOUT_FROM_ANOTHER_TAB':
|
|
1032
1030
|
updateTokens(null);
|
|
1033
|
-
this.publishEvent(eventNames.logout_from_another_tab, {
|
|
1034
|
-
return {tokens:null, status:
|
|
1035
|
-
case
|
|
1036
|
-
this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken
|
|
1031
|
+
this.publishEvent(eventNames.logout_from_another_tab, { status: 'session syncTokensAsync' });
|
|
1032
|
+
return { tokens: null, status: 'LOGGED_OUT' };
|
|
1033
|
+
case 'REQUIRE_SYNC_TOKENS':
|
|
1034
|
+
this.publishEvent(eventNames.refreshTokensAsync_begin, { refreshToken, status, tryNumber: index });
|
|
1037
1035
|
return await localsilentLoginAsync();
|
|
1038
1036
|
default:
|
|
1039
|
-
if(!refreshToken)
|
|
1040
|
-
{
|
|
1037
|
+
if (!refreshToken) {
|
|
1041
1038
|
return await localsilentLoginAsync();
|
|
1042
1039
|
}
|
|
1043
|
-
this.publishEvent(eventNames.refreshTokensAsync_begin, {refreshToken
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
if(
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1040
|
+
this.publishEvent(eventNames.refreshTokensAsync_begin, { refreshToken, status, tryNumber: index });
|
|
1041
|
+
{
|
|
1042
|
+
const clientId = configuration.client_id;
|
|
1043
|
+
const redirectUri = configuration.redirect_uri;
|
|
1044
|
+
const authority = configuration.authority;
|
|
1045
|
+
const tokenExtras = configuration.token_request_extras ? configuration.token_request_extras : {};
|
|
1046
|
+
const finalExtras = { ...tokenExtras, ...extras };
|
|
1047
|
+
|
|
1048
|
+
const details = {
|
|
1049
|
+
client_id: clientId,
|
|
1050
|
+
redirect_uri: redirectUri,
|
|
1051
|
+
grant_type: GRANT_TYPE_REFRESH_TOKEN,
|
|
1052
|
+
refresh_token: tokens.refreshToken,
|
|
1053
|
+
};
|
|
1054
|
+
const oidcServerConfiguration = await this.initAsync(authority, configuration.authority_configuration);
|
|
1055
|
+
const tokenResponse = await performTokenRequestAsync(oidcServerConfiguration.tokenEndpoint, details, finalExtras, tokens, configuration.token_renew_mode);
|
|
1056
|
+
if (tokenResponse.success) {
|
|
1057
|
+
if (!isTokensOidcValid(tokenResponse.data, nonce.nonce, oidcServerConfiguration)) {
|
|
1058
|
+
updateTokens(null);
|
|
1059
|
+
this.publishEvent(eventNames.refreshTokensAsync_error, { message: 'refresh token return not valid tokens' });
|
|
1060
|
+
return { tokens: null, status: 'SESSION_LOST' };
|
|
1061
|
+
}
|
|
1062
|
+
updateTokens(tokenResponse.data);
|
|
1063
|
+
this.publishEvent(eventNames.refreshTokensAsync_end, { success: tokenResponse.success });
|
|
1064
|
+
this.publishEvent(Oidc.eventNames.token_renewed, {});
|
|
1065
|
+
return { tokens: tokenResponse.data, status: 'LOGGED_IN' };
|
|
1066
|
+
} else {
|
|
1067
|
+
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {
|
|
1068
|
+
message: 'bad request',
|
|
1069
|
+
tokenResponse,
|
|
1070
|
+
});
|
|
1071
|
+
return await this.synchroniseTokensAsync(null, index + 1, forceRefresh, extras, updateTokens);
|
|
1063
1072
|
}
|
|
1064
|
-
|
|
1065
|
-
this.publishEvent(eventNames.refreshTokensAsync_end, {success: tokenResponse.success});
|
|
1066
|
-
this.publishEvent(Oidc.eventNames.token_renewed, {});
|
|
1067
|
-
return {tokens: tokenResponse.data, status:"LOGGED_IN"};
|
|
1068
|
-
} else {
|
|
1069
|
-
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {
|
|
1070
|
-
message: "bad request",
|
|
1071
|
-
tokenResponse: tokenResponse
|
|
1072
|
-
});
|
|
1073
|
-
return await this.synchroniseTokensAsync(null, index+1, forceRefresh, extras, updateTokens);
|
|
1074
|
-
}
|
|
1073
|
+
}
|
|
1075
1074
|
}
|
|
1076
1075
|
} catch (exception) {
|
|
1077
1076
|
console.error(exception);
|
|
1078
|
-
this.publishEvent(eventNames.refreshTokensAsync_silent_error, {message:
|
|
1079
|
-
return this.synchroniseTokensAsync(refreshToken, index+1, forceRefresh, extras, updateTokens);
|
|
1077
|
+
this.publishEvent(eventNames.refreshTokensAsync_silent_error, { message: 'exception', exception: exception.message });
|
|
1078
|
+
return this.synchroniseTokensAsync(refreshToken, index + 1, forceRefresh, extras, updateTokens);
|
|
1080
1079
|
}
|
|
1081
1080
|
}
|
|
1082
1081
|
|
|
1083
|
-
this.publishEvent(eventNames.refreshTokensAsync_error, {message:
|
|
1084
|
-
return {tokens:null, status:
|
|
1082
|
+
this.publishEvent(eventNames.refreshTokensAsync_error, { message: 'refresh token' });
|
|
1083
|
+
return { tokens: null, status: 'SESSION_LOST' };
|
|
1085
1084
|
}
|
|
1086
1085
|
|
|
1087
|
-
async syncTokensInfoAsync(configuration, configurationName, currentTokens, forceRefresh =false)
|
|
1086
|
+
async syncTokensInfoAsync(configuration, configurationName, currentTokens, forceRefresh = false) {
|
|
1088
1087
|
// Service Worker can be killed by the browser (when it wants,for example after 10 seconds of inactivity, so we retreieve the session if it happen)
|
|
1089
|
-
//const configuration = this.configuration;
|
|
1090
|
-
const nullNonce = { nonce:null };
|
|
1088
|
+
// const configuration = this.configuration;
|
|
1089
|
+
const nullNonce = { nonce: null };
|
|
1091
1090
|
if (!currentTokens) {
|
|
1092
|
-
return { tokens
|
|
1091
|
+
return { tokens: null, status: 'NOT_CONNECTED', nonce: nullNonce };
|
|
1093
1092
|
}
|
|
1094
1093
|
let nonce = nullNonce;
|
|
1095
1094
|
const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
|
|
1096
1095
|
const serviceWorker = await initWorkerAsync(configuration.service_worker_relative_url, configurationName);
|
|
1097
1096
|
if (serviceWorker) {
|
|
1098
|
-
const {status, tokens} = await serviceWorker.initAsync(oidcServerConfiguration,
|
|
1099
|
-
if (status
|
|
1100
|
-
return {tokens: null, status:
|
|
1101
|
-
}else if (status
|
|
1102
|
-
return { tokens
|
|
1097
|
+
const { status, tokens } = await serviceWorker.initAsync(oidcServerConfiguration, 'syncTokensAsync', configuration);
|
|
1098
|
+
if (status === 'LOGGED_OUT') {
|
|
1099
|
+
return { tokens: null, status: 'LOGOUT_FROM_ANOTHER_TAB', nonce: nullNonce };
|
|
1100
|
+
} else if (status === 'SESSIONS_LOST') {
|
|
1101
|
+
return { tokens: null, status: 'SESSIONS_LOST', nonce: nullNonce };
|
|
1103
1102
|
} else if (!status || !tokens) {
|
|
1104
|
-
return { tokens
|
|
1105
|
-
} else if(tokens.issuedAt !== currentTokens.issuedAt) {
|
|
1103
|
+
return { tokens: null, status: 'REQUIRE_SYNC_TOKENS', nonce: nullNonce };
|
|
1104
|
+
} else if (tokens.issuedAt !== currentTokens.issuedAt) {
|
|
1106
1105
|
const timeLeft = computeTimeLeft(configuration.refresh_time_before_tokens_expiration_in_second, tokens.expiresAt);
|
|
1107
|
-
const status = (timeLeft > 0) ?
|
|
1106
|
+
const status = (timeLeft > 0) ? 'TOKEN_UPDATED_BY_ANOTHER_TAB_TOKENS_VALID' : 'TOKEN_UPDATED_BY_ANOTHER_TAB_TOKENS_INVALID';
|
|
1108
1107
|
const nonce = await serviceWorker.getNonceAsync();
|
|
1109
|
-
return { tokens
|
|
1108
|
+
return { tokens, status, nonce };
|
|
1110
1109
|
}
|
|
1111
1110
|
nonce = await serviceWorker.getNonceAsync();
|
|
1112
1111
|
} else {
|
|
1113
1112
|
const session = initSession(configurationName, configuration.redirect_uri, configuration.storage ?? sessionStorage);
|
|
1114
1113
|
const { tokens, status } = await session.initAsync();
|
|
1115
1114
|
if (!tokens) {
|
|
1116
|
-
return {tokens: null, status:
|
|
1117
|
-
} else if (status
|
|
1118
|
-
return { tokens
|
|
1119
|
-
}
|
|
1120
|
-
else if(tokens.issuedAt !== currentTokens.issuedAt){
|
|
1115
|
+
return { tokens: null, status: 'LOGOUT_FROM_ANOTHER_TAB', nonce: nullNonce };
|
|
1116
|
+
} else if (status === 'SESSIONS_LOST') {
|
|
1117
|
+
return { tokens: null, status: 'SESSIONS_LOST', nonce: nullNonce };
|
|
1118
|
+
} else if (tokens.issuedAt !== currentTokens.issuedAt) {
|
|
1121
1119
|
const timeLeft = computeTimeLeft(configuration.refresh_time_before_tokens_expiration_in_second, tokens.expiresAt);
|
|
1122
|
-
const status = (timeLeft > 0) ?
|
|
1120
|
+
const status = (timeLeft > 0) ? 'TOKEN_UPDATED_BY_ANOTHER_TAB_TOKENS_VALID' : 'TOKEN_UPDATED_BY_ANOTHER_TAB_TOKENS_INVALID';
|
|
1123
1121
|
const nonce = await session.getNonceAsync();
|
|
1124
|
-
return { tokens
|
|
1122
|
+
return { tokens, status, nonce };
|
|
1125
1123
|
}
|
|
1126
1124
|
nonce = await session.getNonceAsync();
|
|
1127
1125
|
}
|
|
1128
1126
|
|
|
1129
1127
|
const timeLeft = computeTimeLeft(configuration.refresh_time_before_tokens_expiration_in_second, currentTokens.expiresAt);
|
|
1130
|
-
const status = (timeLeft > 0) ?
|
|
1131
|
-
if(forceRefresh){
|
|
1132
|
-
return { tokens:currentTokens, status:
|
|
1128
|
+
const status = (timeLeft > 0) ? 'TOKENS_VALID' : 'TOKENS_INVALID';
|
|
1129
|
+
if (forceRefresh) {
|
|
1130
|
+
return { tokens: currentTokens, status: 'FORCE_REFRESH', nonce };
|
|
1133
1131
|
}
|
|
1134
|
-
return { tokens:currentTokens, status, nonce};
|
|
1132
|
+
return { tokens: currentTokens, status, nonce };
|
|
1135
1133
|
}
|
|
1136
1134
|
|
|
1137
1135
|
loginCallbackWithAutoTokensRenewPromise:Promise<LoginCallback> = null;
|
|
1138
|
-
loginCallbackWithAutoTokensRenewAsync():Promise<LoginCallback>{
|
|
1139
|
-
if(this.loginCallbackWithAutoTokensRenewPromise !== null){
|
|
1136
|
+
loginCallbackWithAutoTokensRenewAsync():Promise<LoginCallback> {
|
|
1137
|
+
if (this.loginCallbackWithAutoTokensRenewPromise !== null) {
|
|
1140
1138
|
return this.loginCallbackWithAutoTokensRenewPromise;
|
|
1141
1139
|
}
|
|
1142
1140
|
this.loginCallbackWithAutoTokensRenewPromise = loginCallbackWithAutoTokensRenewAsync(this);
|
|
1143
|
-
return this.loginCallbackWithAutoTokensRenewPromise.then(result =>{
|
|
1141
|
+
return this.loginCallbackWithAutoTokensRenewPromise.then(result => {
|
|
1144
1142
|
this.loginCallbackWithAutoTokensRenewPromise = null;
|
|
1145
1143
|
return result;
|
|
1146
|
-
})
|
|
1144
|
+
});
|
|
1147
1145
|
}
|
|
1148
1146
|
|
|
1149
1147
|
userInfoPromise:Promise<any> = null;
|
|
1150
|
-
userInfoAsync(){
|
|
1151
|
-
if(this.userInfoPromise !== null){
|
|
1148
|
+
userInfoAsync() {
|
|
1149
|
+
if (this.userInfoPromise !== null) {
|
|
1152
1150
|
return this.userInfoPromise;
|
|
1153
1151
|
}
|
|
1154
1152
|
this.userInfoPromise = userInfoAsync(this);
|
|
1155
|
-
return this.userInfoPromise.then(result =>{
|
|
1153
|
+
return this.userInfoPromise.then(result => {
|
|
1156
1154
|
this.userInfoPromise = null;
|
|
1157
1155
|
return result;
|
|
1158
|
-
})
|
|
1156
|
+
});
|
|
1159
1157
|
}
|
|
1160
|
-
|
|
1161
|
-
async renewTokensAsync (extras:StringMap=null){
|
|
1162
|
-
if(!this.timeoutId){
|
|
1158
|
+
|
|
1159
|
+
async renewTokensAsync (extras:StringMap = null) {
|
|
1160
|
+
if (!this.timeoutId) {
|
|
1163
1161
|
return;
|
|
1164
1162
|
}
|
|
1165
1163
|
timer.clearTimeout(this.timeoutId);
|
|
1166
1164
|
// @ts-ignore
|
|
1167
1165
|
await renewTokensAndStartTimerAsync(this, this.tokens.refreshToken, true, extras);
|
|
1168
1166
|
}
|
|
1169
|
-
|
|
1167
|
+
|
|
1170
1168
|
async destroyAsync(status) {
|
|
1171
1169
|
timer.clearTimeout(this.timeoutId);
|
|
1172
|
-
this.timeoutId=null;
|
|
1173
|
-
if(this.checkSessionIFrame){
|
|
1170
|
+
this.timeoutId = null;
|
|
1171
|
+
if (this.checkSessionIFrame) {
|
|
1174
1172
|
this.checkSessionIFrame.stop();
|
|
1175
1173
|
}
|
|
1176
|
-
const
|
|
1177
|
-
const serviceWorker = await initWorkerAsync(oidc.configuration.service_worker_relative_url, oidc.configurationName);
|
|
1174
|
+
const serviceWorker = await initWorkerAsync(this.configuration.service_worker_relative_url, this.configurationName);
|
|
1178
1175
|
if (!serviceWorker) {
|
|
1179
|
-
const session = initSession(this.configurationName,
|
|
1176
|
+
const session = initSession(this.configurationName, this.configuration.redirect_uri, this.configuration.storage);
|
|
1180
1177
|
await session.clearAsync(status);
|
|
1181
|
-
} else{
|
|
1178
|
+
} else {
|
|
1182
1179
|
await serviceWorker.clearAsync(status);
|
|
1183
1180
|
}
|
|
1184
1181
|
this.tokens = null;
|
|
1185
1182
|
this.userInfo = null;
|
|
1186
1183
|
// this.events = [];
|
|
1187
1184
|
}
|
|
1188
|
-
|
|
1189
|
-
async logoutSameTabAsync(clientId, sub){
|
|
1185
|
+
|
|
1186
|
+
async logoutSameTabAsync(clientId: string, sub: any) {
|
|
1190
1187
|
// @ts-ignore
|
|
1191
|
-
if(this.configuration.monitor_session&& this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
|
|
1192
|
-
this.publishEvent(eventNames.logout_from_same_tab, {
|
|
1193
|
-
await this.destroyAsync(
|
|
1188
|
+
if (this.configuration.monitor_session && this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
|
|
1189
|
+
this.publishEvent(eventNames.logout_from_same_tab, { message: sub });
|
|
1190
|
+
await this.destroyAsync('LOGGED_OUT');
|
|
1194
1191
|
}
|
|
1195
1192
|
}
|
|
1196
1193
|
|
|
1197
|
-
async logoutOtherTabAsync(clientId, sub){
|
|
1194
|
+
async logoutOtherTabAsync(clientId: string, sub: any) {
|
|
1198
1195
|
// @ts-ignore
|
|
1199
|
-
if(this.configuration.monitor_session && this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
|
|
1200
|
-
await this.destroyAsync(
|
|
1201
|
-
this.publishEvent(eventNames.logout_from_another_tab, {message
|
|
1196
|
+
if (this.configuration.monitor_session && this.configuration.client_id === clientId && sub && this.tokens && this.tokens.idTokenPayload && this.tokens.idTokenPayload.sub === sub) {
|
|
1197
|
+
await this.destroyAsync('LOGGED_OUT');
|
|
1198
|
+
this.publishEvent(eventNames.logout_from_another_tab, { message: 'SessionMonitor', sub });
|
|
1202
1199
|
}
|
|
1203
1200
|
}
|
|
1204
|
-
|
|
1201
|
+
|
|
1205
1202
|
async logoutAsync(callbackPathOrUrl: string | null | undefined = undefined, extras: StringMap = null) {
|
|
1206
1203
|
const configuration = this.configuration;
|
|
1207
1204
|
const oidcServerConfiguration = await this.initAsync(configuration.authority, configuration.authority_configuration);
|
|
1208
|
-
if(callbackPathOrUrl && (typeof callbackPathOrUrl !== 'string'))
|
|
1209
|
-
{
|
|
1205
|
+
if (callbackPathOrUrl && (typeof callbackPathOrUrl !== 'string')) {
|
|
1210
1206
|
callbackPathOrUrl = undefined;
|
|
1211
1207
|
console.warn('callbackPathOrUrl path is not a string');
|
|
1212
1208
|
}
|
|
1213
1209
|
const path = (callbackPathOrUrl === null || callbackPathOrUrl === undefined) ? location.pathname + (location.search || '') + (location.hash || '') : callbackPathOrUrl;
|
|
1214
|
-
|
|
1215
|
-
if(callbackPathOrUrl) {
|
|
1216
|
-
isUri = callbackPathOrUrl.includes(
|
|
1210
|
+
let isUri = false;
|
|
1211
|
+
if (callbackPathOrUrl) {
|
|
1212
|
+
isUri = callbackPathOrUrl.includes('https://') || callbackPathOrUrl.includes('http://');
|
|
1217
1213
|
}
|
|
1218
|
-
|
|
1214
|
+
const url = isUri ? callbackPathOrUrl : window.location.origin + path;
|
|
1219
1215
|
// @ts-ignore
|
|
1220
|
-
const idToken = this.tokens ? this.tokens.idToken :
|
|
1216
|
+
const idToken = this.tokens ? this.tokens.idToken : '';
|
|
1221
1217
|
try {
|
|
1222
1218
|
const revocationEndpoint = oidcServerConfiguration.revocationEndpoint;
|
|
1223
1219
|
if (revocationEndpoint) {
|
|
@@ -1234,48 +1230,45 @@ Please checkout that you are using OIDC hook inside a <OidcProvider configuratio
|
|
|
1234
1230
|
await Promise.all(promises);
|
|
1235
1231
|
}
|
|
1236
1232
|
}
|
|
1237
|
-
}catch(exception){
|
|
1233
|
+
} catch (exception) {
|
|
1238
1234
|
console.warn(exception);
|
|
1239
1235
|
}
|
|
1240
1236
|
// @ts-ignore
|
|
1241
1237
|
const sub = this.tokens && this.tokens.idTokenPayload ? this.tokens.idTokenPayload.sub : null;
|
|
1242
|
-
await this.destroyAsync(
|
|
1238
|
+
await this.destroyAsync('LOGGED_OUT');
|
|
1239
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1243
1240
|
for (const [key, oidc] of Object.entries(oidcDatabase)) {
|
|
1244
|
-
if(oidc !== this) {
|
|
1241
|
+
if (oidc !== this) {
|
|
1245
1242
|
// @ts-ignore
|
|
1246
1243
|
await oidc.logoutSameTabAsync(this.configuration.client_id, sub);
|
|
1247
1244
|
}
|
|
1248
1245
|
}
|
|
1249
1246
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
id_token_hint: idToken
|
|
1247
|
+
if (oidcServerConfiguration.endSessionEndpoint) {
|
|
1248
|
+
if (!extras) {
|
|
1249
|
+
extras = {
|
|
1250
|
+
id_token_hint: idToken,
|
|
1255
1251
|
};
|
|
1256
|
-
if(callbackPathOrUrl !== null){
|
|
1257
|
-
extras
|
|
1252
|
+
if (callbackPathOrUrl !== null) {
|
|
1253
|
+
extras.post_logout_redirect_uri = url;
|
|
1258
1254
|
}
|
|
1259
1255
|
}
|
|
1260
|
-
let queryString =
|
|
1261
|
-
if(extras){
|
|
1262
|
-
for (
|
|
1263
|
-
if(queryString ===
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
queryString += "&";
|
|
1256
|
+
let queryString = '';
|
|
1257
|
+
if (extras) {
|
|
1258
|
+
for (const [key, value] of Object.entries(extras)) {
|
|
1259
|
+
if (queryString === '') {
|
|
1260
|
+
queryString += '?';
|
|
1261
|
+
} else {
|
|
1262
|
+
queryString += '&';
|
|
1268
1263
|
}
|
|
1269
|
-
queryString
|
|
1264
|
+
queryString += `${key}=${encodeURIComponent(value)}`;
|
|
1270
1265
|
}
|
|
1271
1266
|
}
|
|
1272
1267
|
window.location.href = `${oidcServerConfiguration.endSessionEndpoint}${queryString}`;
|
|
1273
|
-
}
|
|
1274
|
-
else{
|
|
1268
|
+
} else {
|
|
1275
1269
|
window.location.reload();
|
|
1276
1270
|
}
|
|
1277
1271
|
}
|
|
1278
1272
|
}
|
|
1279
|
-
|
|
1280
1273
|
|
|
1281
1274
|
export default Oidc;
|