@openeo/js-client 2.5.0 → 2.6.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/LICENSE +201 -201
- package/README.md +93 -83
- package/openeo.d.ts +112 -53
- package/openeo.js +3670 -4114
- package/openeo.min.js +1 -1
- package/package.json +72 -70
- package/src/authprovider.js +147 -138
- package/src/baseentity.js +162 -162
- package/src/basicprovider.js +69 -48
- package/src/browser.js +168 -168
- package/src/builder/builder.js +400 -400
- package/src/builder/formula.js +211 -211
- package/src/builder/node.js +268 -268
- package/src/builder/parameter.js +144 -144
- package/src/builder/tapdigit.js +489 -489
- package/src/capabilities.js +265 -220
- package/src/connection.js +1310 -1212
- package/src/env.js +5 -5
- package/src/filetypes.js +111 -111
- package/src/job.js +323 -322
- package/src/logs.js +73 -68
- package/src/node.js +168 -168
- package/src/oidcprovider.js +387 -375
- package/src/openeo.js +137 -138
- package/src/service.js +222 -221
- package/src/typedefs.js +242 -242
- package/src/userfile.js +128 -128
- package/src/userprocess.js +166 -166
package/src/oidcprovider.js
CHANGED
|
@@ -1,375 +1,387 @@
|
|
|
1
|
-
const Utils = require('@openeo/js-commons/src/utils');
|
|
2
|
-
const AuthProvider = require('./authprovider');
|
|
3
|
-
const Environment = require('./env');
|
|
4
|
-
const Oidc = require('oidc-client');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* The Authentication Provider for OpenID Connect.
|
|
8
|
-
*
|
|
9
|
-
* See the openid-connect-popup.html and openid-connect-redirect.html files in
|
|
10
|
-
* the `/examples/oidc` folder for usage examples in the browser.
|
|
11
|
-
*
|
|
12
|
-
* If you want to implement OIDC in a non-browser environment, you can override
|
|
13
|
-
* the OidcProvider or AuthProvider classes with custom behavior.
|
|
14
|
-
* In this case you must provide a function that creates your new class to the
|
|
15
|
-
* `Connection.setOidcProviderFactory()` method.
|
|
16
|
-
*
|
|
17
|
-
* @augments AuthProvider
|
|
18
|
-
* @see Connection#setOidcProviderFactory
|
|
19
|
-
*/
|
|
20
|
-
class OidcProvider extends AuthProvider {
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Checks whether the required OIDC client library `openid-client-js` is available.
|
|
24
|
-
*
|
|
25
|
-
* @static
|
|
26
|
-
* @returns {boolean}
|
|
27
|
-
*/
|
|
28
|
-
static isSupported() {
|
|
29
|
-
return Utils.isObject(Oidc) && Boolean(Oidc.UserManager);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Finishes the OpenID Connect sign in (authentication) workflow.
|
|
34
|
-
*
|
|
35
|
-
* Must be called in the page that OpenID Connect redirects to after logging in.
|
|
36
|
-
*
|
|
37
|
-
* Supported only in Browser environments.
|
|
38
|
-
*
|
|
39
|
-
* @async
|
|
40
|
-
* @static
|
|
41
|
-
* @param {OidcProvider} provider - A OIDC provider to assign the user to.
|
|
42
|
-
* @param {object.<string, *>} [options={}] - Object with additional options.
|
|
43
|
-
* @returns {Promise<?Oidc.User>} For uiMethod = 'redirect' only: OIDC User
|
|
44
|
-
* @throws {Error}
|
|
45
|
-
* @see https://github.com/IdentityModel/oidc-client-js/wiki#other-optional-settings
|
|
46
|
-
*/
|
|
47
|
-
static async signinCallback(provider = null, options = {}) {
|
|
48
|
-
let url = Environment.getUrl();
|
|
49
|
-
if (!provider) {
|
|
50
|
-
// No provider options available, try to detect response mode from URL
|
|
51
|
-
provider = new OidcProvider(null, {});
|
|
52
|
-
provider.setGrant(url.includes('?') ? 'authorization_code+pkce' : 'implicit');
|
|
53
|
-
}
|
|
54
|
-
let providerOptions = provider.getOptions(options);
|
|
55
|
-
let oidc = new Oidc.UserManager(providerOptions);
|
|
56
|
-
return await oidc.signinCallback(url);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Creates a new OidcProvider instance to authenticate using OpenID Connect.
|
|
61
|
-
*
|
|
62
|
-
* @param {Connection} connection - A Connection object representing an established connection to an openEO back-end.
|
|
63
|
-
* @param {OidcProviderMeta} options - OpenID Connect Provider details as returned by the API.
|
|
64
|
-
*/
|
|
65
|
-
constructor(connection, options) {
|
|
66
|
-
super("oidc", connection, options);
|
|
67
|
-
|
|
68
|
-
this.manager = null;
|
|
69
|
-
this.listeners = {};
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* The authenticated OIDC user.
|
|
73
|
-
*
|
|
74
|
-
* @type {Oidc.User}
|
|
75
|
-
*/
|
|
76
|
-
this.user = null;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* The client ID to use for authentication.
|
|
80
|
-
*
|
|
81
|
-
* @type {string | null}
|
|
82
|
-
*/
|
|
83
|
-
this.clientId = null;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* The grant type (flow) to use for this provider.
|
|
87
|
-
*
|
|
88
|
-
* Either "authorization_code+pkce" (default) or "implicit"
|
|
89
|
-
*
|
|
90
|
-
* @type {string}
|
|
91
|
-
*/
|
|
92
|
-
this.grant = "authorization_code+pkce"; // Set this before calling detectDefaultClient
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* The issuer, i.e. the link to the identity provider.
|
|
96
|
-
*
|
|
97
|
-
* @type {string}
|
|
98
|
-
*/
|
|
99
|
-
this.issuer = options.issuer || "";
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* The scopes to be requested.
|
|
103
|
-
*
|
|
104
|
-
* @type {Array.<string>}
|
|
105
|
-
*/
|
|
106
|
-
this.scopes = Array.isArray(options.scopes) && options.scopes.length > 0 ? options.scopes : ['openid'];
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* The scope that is used to request a refresh token.
|
|
110
|
-
*
|
|
111
|
-
* @type {string}
|
|
112
|
-
*/
|
|
113
|
-
this.refreshTokenScope = "offline_access";
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Any additional links.
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* @type {Array.<Link>}
|
|
120
|
-
*/
|
|
121
|
-
this.links = Array.isArray(options.links) ? options.links : [];
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* The default clients made available by the back-end.
|
|
125
|
-
*
|
|
126
|
-
* @type {Array.<OidcClient>}
|
|
127
|
-
*/
|
|
128
|
-
this.defaultClients = Array.isArray(options.default_clients) ? options.default_clients : [];
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* The detected default Client.
|
|
132
|
-
*
|
|
133
|
-
* @type {OidcClient}
|
|
134
|
-
*/
|
|
135
|
-
this.defaultClient = this.detectDefaultClient();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Adds a listener to one of the following events:
|
|
140
|
-
*
|
|
141
|
-
* - AccessTokenExpiring: Raised prior to the access token expiring.
|
|
142
|
-
* - AccessTokenExpired: Raised after the access token has expired.
|
|
143
|
-
* - SilentRenewError: Raised when the automatic silent renew has failed.
|
|
144
|
-
*
|
|
145
|
-
* @param {string} event
|
|
146
|
-
* @param {Function} callback
|
|
147
|
-
* @param {string} [scope="default"]
|
|
148
|
-
*/
|
|
149
|
-
addListener(event, callback, scope = 'default') {
|
|
150
|
-
this.manager.events[`add${event}`](callback);
|
|
151
|
-
this.listeners[`${scope}:${event}`] = callback;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Removes the listener for the given event that has been set with addListener.
|
|
156
|
-
*
|
|
157
|
-
* @param {string} event
|
|
158
|
-
* @param {string} [scope="default"]
|
|
159
|
-
* @see OidcProvider#addListener
|
|
160
|
-
*/
|
|
161
|
-
removeListener(event, scope = 'default') {
|
|
162
|
-
this.manager.events[`remove${event}`](this.listeners[event]);
|
|
163
|
-
delete this.listeners[`${scope}:${event}`];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Authenticate with OpenID Connect (OIDC).
|
|
168
|
-
*
|
|
169
|
-
* Supported only in Browser environments.
|
|
170
|
-
*
|
|
171
|
-
* @async
|
|
172
|
-
* @param {object.<string, *>} [options={}] - Object with authentication options.
|
|
173
|
-
* @param {boolean} [requestRefreshToken=false] - If set to `true`, adds a scope to request a refresh token.
|
|
174
|
-
* @returns {Promise<void>}
|
|
175
|
-
* @throws {Error}
|
|
176
|
-
* @see https://github.com/IdentityModel/oidc-client-js/wiki#other-optional-settings
|
|
177
|
-
* @see {OidcProvider#refreshTokenScope}
|
|
178
|
-
*/
|
|
179
|
-
async login(options = {}, requestRefreshToken = false) {
|
|
180
|
-
if (!this.issuer || typeof this.issuer !== 'string') {
|
|
181
|
-
throw new Error("No Issuer URL available for OpenID Connect");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
this.manager = new Oidc.UserManager(this.getOptions(options, requestRefreshToken));
|
|
185
|
-
this.addListener('UserLoaded', async () => this.setUser(await this.manager.getUser()), 'js-client');
|
|
186
|
-
this.addListener('AccessTokenExpired', () => this.setUser(null), 'js-client');
|
|
187
|
-
if (OidcProvider.uiMethod === 'popup') {
|
|
188
|
-
await this.manager.signinPopup();
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
await this.manager.signinRedirect();
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Logout from the established session.
|
|
197
|
-
*
|
|
198
|
-
* @async
|
|
199
|
-
*/
|
|
200
|
-
async logout() {
|
|
201
|
-
if (this.manager !== null) {
|
|
202
|
-
try {
|
|
203
|
-
if (OidcProvider.uiMethod === 'popup') {
|
|
204
|
-
await this.manager.signoutPopup();
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
await this.manager.signoutRedirect({
|
|
208
|
-
post_logout_redirect_uri: Environment.getUrl()
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
} catch (error) {
|
|
212
|
-
console.warn(error);
|
|
213
|
-
}
|
|
214
|
-
super.logout();
|
|
215
|
-
this.removeListener('UserLoaded', 'js-client');
|
|
216
|
-
this.removeListener('AccessTokenExpired', 'js-client');
|
|
217
|
-
this.manager = null;
|
|
218
|
-
this.setUser(null);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Returns the options for the OIDC client library.
|
|
224
|
-
*
|
|
225
|
-
* Options can be overridden by custom options via the options parameter.
|
|
226
|
-
*
|
|
227
|
-
* @protected
|
|
228
|
-
* @param {object.<string, *>} options
|
|
229
|
-
* @param {boolean} [requestRefreshToken=false] - If set to `true`, adds a scope to request a refresh token.
|
|
230
|
-
* @returns {object.<string, *>}
|
|
231
|
-
* @see {OidcProvider#refreshTokenScope}
|
|
232
|
-
*/
|
|
233
|
-
getOptions(options = {}, requestRefreshToken = false) {
|
|
234
|
-
let response_type = this.getResponseType();
|
|
235
|
-
let scope = this.scopes.slice(0);
|
|
236
|
-
if (requestRefreshToken && !scope.includes(this.refreshTokenScope)) {
|
|
237
|
-
scope.push(this.refreshTokenScope);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return Object.assign({
|
|
241
|
-
client_id: this.clientId,
|
|
242
|
-
redirect_uri: OidcProvider.redirectUrl,
|
|
243
|
-
authority: this.issuer.replace('/.well-known/openid-configuration', ''),
|
|
244
|
-
scope: scope.join(' '),
|
|
245
|
-
validateSubOnSilentRenew: true,
|
|
246
|
-
response_type,
|
|
247
|
-
response_mode: response_type.includes('code') ? 'query' : 'fragment'
|
|
248
|
-
}, options);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Get the response_type based on the grant type.
|
|
253
|
-
*
|
|
254
|
-
* @protected
|
|
255
|
-
* @returns {string}
|
|
256
|
-
* @throws {Error}
|
|
257
|
-
*/
|
|
258
|
-
getResponseType() {
|
|
259
|
-
switch(this.grant) {
|
|
260
|
-
case 'authorization_code+pkce':
|
|
261
|
-
return 'code';
|
|
262
|
-
case 'implicit':
|
|
263
|
-
return 'token id_token';
|
|
264
|
-
default:
|
|
265
|
-
throw new Error('Grant Type not supported');
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Sets the grant type (flow) used for OIDC authentication.
|
|
271
|
-
*
|
|
272
|
-
* @param {string} grant - Grant Type
|
|
273
|
-
* @throws {Error}
|
|
274
|
-
*/
|
|
275
|
-
setGrant(grant) { //
|
|
276
|
-
switch(grant) {
|
|
277
|
-
case 'authorization_code+pkce':
|
|
278
|
-
case 'implicit':
|
|
279
|
-
this.grant = grant;
|
|
280
|
-
break;
|
|
281
|
-
default:
|
|
282
|
-
throw new Error('Grant Type not supported');
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Sets the Client ID for OIDC authentication.
|
|
288
|
-
*
|
|
289
|
-
* This may override a detected default client ID.
|
|
290
|
-
*
|
|
291
|
-
* @param {string | null} clientId
|
|
292
|
-
*/
|
|
293
|
-
setClientId(clientId) {
|
|
294
|
-
this.clientId = clientId;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Sets the OIDC User.
|
|
299
|
-
*
|
|
300
|
-
* @see https://github.com/IdentityModel/oidc-client-js/wiki#user
|
|
301
|
-
* @param {Oidc.User | null} user - The OIDC User. Passing `null` resets OIDC authentication details.
|
|
302
|
-
*/
|
|
303
|
-
setUser(user) {
|
|
304
|
-
if (!user) {
|
|
305
|
-
this.user = null;
|
|
306
|
-
this.setToken(null);
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
this.user = user;
|
|
310
|
-
this.setToken(user.access_token);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
1
|
+
const Utils = require('@openeo/js-commons/src/utils');
|
|
2
|
+
const AuthProvider = require('./authprovider');
|
|
3
|
+
const Environment = require('./env');
|
|
4
|
+
const Oidc = require('oidc-client');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The Authentication Provider for OpenID Connect.
|
|
8
|
+
*
|
|
9
|
+
* See the openid-connect-popup.html and openid-connect-redirect.html files in
|
|
10
|
+
* the `/examples/oidc` folder for usage examples in the browser.
|
|
11
|
+
*
|
|
12
|
+
* If you want to implement OIDC in a non-browser environment, you can override
|
|
13
|
+
* the OidcProvider or AuthProvider classes with custom behavior.
|
|
14
|
+
* In this case you must provide a function that creates your new class to the
|
|
15
|
+
* `Connection.setOidcProviderFactory()` method.
|
|
16
|
+
*
|
|
17
|
+
* @augments AuthProvider
|
|
18
|
+
* @see Connection#setOidcProviderFactory
|
|
19
|
+
*/
|
|
20
|
+
class OidcProvider extends AuthProvider {
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Checks whether the required OIDC client library `openid-client-js` is available.
|
|
24
|
+
*
|
|
25
|
+
* @static
|
|
26
|
+
* @returns {boolean}
|
|
27
|
+
*/
|
|
28
|
+
static isSupported() {
|
|
29
|
+
return Utils.isObject(Oidc) && Boolean(Oidc.UserManager);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Finishes the OpenID Connect sign in (authentication) workflow.
|
|
34
|
+
*
|
|
35
|
+
* Must be called in the page that OpenID Connect redirects to after logging in.
|
|
36
|
+
*
|
|
37
|
+
* Supported only in Browser environments.
|
|
38
|
+
*
|
|
39
|
+
* @async
|
|
40
|
+
* @static
|
|
41
|
+
* @param {OidcProvider} provider - A OIDC provider to assign the user to.
|
|
42
|
+
* @param {object.<string, *>} [options={}] - Object with additional options.
|
|
43
|
+
* @returns {Promise<?Oidc.User>} For uiMethod = 'redirect' only: OIDC User
|
|
44
|
+
* @throws {Error}
|
|
45
|
+
* @see https://github.com/IdentityModel/oidc-client-js/wiki#other-optional-settings
|
|
46
|
+
*/
|
|
47
|
+
static async signinCallback(provider = null, options = {}) {
|
|
48
|
+
let url = Environment.getUrl();
|
|
49
|
+
if (!provider) {
|
|
50
|
+
// No provider options available, try to detect response mode from URL
|
|
51
|
+
provider = new OidcProvider(null, {});
|
|
52
|
+
provider.setGrant(url.includes('?') ? 'authorization_code+pkce' : 'implicit');
|
|
53
|
+
}
|
|
54
|
+
let providerOptions = provider.getOptions(options);
|
|
55
|
+
let oidc = new Oidc.UserManager(providerOptions);
|
|
56
|
+
return await oidc.signinCallback(url);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Creates a new OidcProvider instance to authenticate using OpenID Connect.
|
|
61
|
+
*
|
|
62
|
+
* @param {Connection} connection - A Connection object representing an established connection to an openEO back-end.
|
|
63
|
+
* @param {OidcProviderMeta} options - OpenID Connect Provider details as returned by the API.
|
|
64
|
+
*/
|
|
65
|
+
constructor(connection, options) {
|
|
66
|
+
super("oidc", connection, options);
|
|
67
|
+
|
|
68
|
+
this.manager = null;
|
|
69
|
+
this.listeners = {};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The authenticated OIDC user.
|
|
73
|
+
*
|
|
74
|
+
* @type {Oidc.User}
|
|
75
|
+
*/
|
|
76
|
+
this.user = null;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The client ID to use for authentication.
|
|
80
|
+
*
|
|
81
|
+
* @type {string | null}
|
|
82
|
+
*/
|
|
83
|
+
this.clientId = null;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The grant type (flow) to use for this provider.
|
|
87
|
+
*
|
|
88
|
+
* Either "authorization_code+pkce" (default) or "implicit"
|
|
89
|
+
*
|
|
90
|
+
* @type {string}
|
|
91
|
+
*/
|
|
92
|
+
this.grant = "authorization_code+pkce"; // Set this before calling detectDefaultClient
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The issuer, i.e. the link to the identity provider.
|
|
96
|
+
*
|
|
97
|
+
* @type {string}
|
|
98
|
+
*/
|
|
99
|
+
this.issuer = options.issuer || "";
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The scopes to be requested.
|
|
103
|
+
*
|
|
104
|
+
* @type {Array.<string>}
|
|
105
|
+
*/
|
|
106
|
+
this.scopes = Array.isArray(options.scopes) && options.scopes.length > 0 ? options.scopes : ['openid'];
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The scope that is used to request a refresh token.
|
|
110
|
+
*
|
|
111
|
+
* @type {string}
|
|
112
|
+
*/
|
|
113
|
+
this.refreshTokenScope = "offline_access";
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Any additional links.
|
|
117
|
+
*
|
|
118
|
+
*
|
|
119
|
+
* @type {Array.<Link>}
|
|
120
|
+
*/
|
|
121
|
+
this.links = Array.isArray(options.links) ? options.links : [];
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The default clients made available by the back-end.
|
|
125
|
+
*
|
|
126
|
+
* @type {Array.<OidcClient>}
|
|
127
|
+
*/
|
|
128
|
+
this.defaultClients = Array.isArray(options.default_clients) ? options.default_clients : [];
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The detected default Client.
|
|
132
|
+
*
|
|
133
|
+
* @type {OidcClient}
|
|
134
|
+
*/
|
|
135
|
+
this.defaultClient = this.detectDefaultClient();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Adds a listener to one of the following events:
|
|
140
|
+
*
|
|
141
|
+
* - AccessTokenExpiring: Raised prior to the access token expiring.
|
|
142
|
+
* - AccessTokenExpired: Raised after the access token has expired.
|
|
143
|
+
* - SilentRenewError: Raised when the automatic silent renew has failed.
|
|
144
|
+
*
|
|
145
|
+
* @param {string} event
|
|
146
|
+
* @param {Function} callback
|
|
147
|
+
* @param {string} [scope="default"]
|
|
148
|
+
*/
|
|
149
|
+
addListener(event, callback, scope = 'default') {
|
|
150
|
+
this.manager.events[`add${event}`](callback);
|
|
151
|
+
this.listeners[`${scope}:${event}`] = callback;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Removes the listener for the given event that has been set with addListener.
|
|
156
|
+
*
|
|
157
|
+
* @param {string} event
|
|
158
|
+
* @param {string} [scope="default"]
|
|
159
|
+
* @see OidcProvider#addListener
|
|
160
|
+
*/
|
|
161
|
+
removeListener(event, scope = 'default') {
|
|
162
|
+
this.manager.events[`remove${event}`](this.listeners[event]);
|
|
163
|
+
delete this.listeners[`${scope}:${event}`];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Authenticate with OpenID Connect (OIDC).
|
|
168
|
+
*
|
|
169
|
+
* Supported only in Browser environments.
|
|
170
|
+
*
|
|
171
|
+
* @async
|
|
172
|
+
* @param {object.<string, *>} [options={}] - Object with authentication options.
|
|
173
|
+
* @param {boolean} [requestRefreshToken=false] - If set to `true`, adds a scope to request a refresh token.
|
|
174
|
+
* @returns {Promise<void>}
|
|
175
|
+
* @throws {Error}
|
|
176
|
+
* @see https://github.com/IdentityModel/oidc-client-js/wiki#other-optional-settings
|
|
177
|
+
* @see {OidcProvider#refreshTokenScope}
|
|
178
|
+
*/
|
|
179
|
+
async login(options = {}, requestRefreshToken = false) {
|
|
180
|
+
if (!this.issuer || typeof this.issuer !== 'string') {
|
|
181
|
+
throw new Error("No Issuer URL available for OpenID Connect");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
this.manager = new Oidc.UserManager(this.getOptions(options, requestRefreshToken));
|
|
185
|
+
this.addListener('UserLoaded', async () => this.setUser(await this.manager.getUser()), 'js-client');
|
|
186
|
+
this.addListener('AccessTokenExpired', () => this.setUser(null), 'js-client');
|
|
187
|
+
if (OidcProvider.uiMethod === 'popup') {
|
|
188
|
+
await this.manager.signinPopup();
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
await this.manager.signinRedirect();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Logout from the established session.
|
|
197
|
+
*
|
|
198
|
+
* @async
|
|
199
|
+
*/
|
|
200
|
+
async logout() {
|
|
201
|
+
if (this.manager !== null) {
|
|
202
|
+
try {
|
|
203
|
+
if (OidcProvider.uiMethod === 'popup') {
|
|
204
|
+
await this.manager.signoutPopup();
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
await this.manager.signoutRedirect({
|
|
208
|
+
post_logout_redirect_uri: Environment.getUrl()
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.warn(error);
|
|
213
|
+
}
|
|
214
|
+
super.logout();
|
|
215
|
+
this.removeListener('UserLoaded', 'js-client');
|
|
216
|
+
this.removeListener('AccessTokenExpired', 'js-client');
|
|
217
|
+
this.manager = null;
|
|
218
|
+
this.setUser(null);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Returns the options for the OIDC client library.
|
|
224
|
+
*
|
|
225
|
+
* Options can be overridden by custom options via the options parameter.
|
|
226
|
+
*
|
|
227
|
+
* @protected
|
|
228
|
+
* @param {object.<string, *>} options
|
|
229
|
+
* @param {boolean} [requestRefreshToken=false] - If set to `true`, adds a scope to request a refresh token.
|
|
230
|
+
* @returns {object.<string, *>}
|
|
231
|
+
* @see {OidcProvider#refreshTokenScope}
|
|
232
|
+
*/
|
|
233
|
+
getOptions(options = {}, requestRefreshToken = false) {
|
|
234
|
+
let response_type = this.getResponseType();
|
|
235
|
+
let scope = this.scopes.slice(0);
|
|
236
|
+
if (requestRefreshToken && !scope.includes(this.refreshTokenScope)) {
|
|
237
|
+
scope.push(this.refreshTokenScope);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return Object.assign({
|
|
241
|
+
client_id: this.clientId,
|
|
242
|
+
redirect_uri: OidcProvider.redirectUrl,
|
|
243
|
+
authority: this.issuer.replace('/.well-known/openid-configuration', ''),
|
|
244
|
+
scope: scope.join(' '),
|
|
245
|
+
validateSubOnSilentRenew: true,
|
|
246
|
+
response_type,
|
|
247
|
+
response_mode: response_type.includes('code') ? 'query' : 'fragment'
|
|
248
|
+
}, options);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get the response_type based on the grant type.
|
|
253
|
+
*
|
|
254
|
+
* @protected
|
|
255
|
+
* @returns {string}
|
|
256
|
+
* @throws {Error}
|
|
257
|
+
*/
|
|
258
|
+
getResponseType() {
|
|
259
|
+
switch(this.grant) {
|
|
260
|
+
case 'authorization_code+pkce':
|
|
261
|
+
return 'code';
|
|
262
|
+
case 'implicit':
|
|
263
|
+
return 'token id_token';
|
|
264
|
+
default:
|
|
265
|
+
throw new Error('Grant Type not supported');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Sets the grant type (flow) used for OIDC authentication.
|
|
271
|
+
*
|
|
272
|
+
* @param {string} grant - Grant Type
|
|
273
|
+
* @throws {Error}
|
|
274
|
+
*/
|
|
275
|
+
setGrant(grant) { //
|
|
276
|
+
switch(grant) {
|
|
277
|
+
case 'authorization_code+pkce':
|
|
278
|
+
case 'implicit':
|
|
279
|
+
this.grant = grant;
|
|
280
|
+
break;
|
|
281
|
+
default:
|
|
282
|
+
throw new Error('Grant Type not supported');
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Sets the Client ID for OIDC authentication.
|
|
288
|
+
*
|
|
289
|
+
* This may override a detected default client ID.
|
|
290
|
+
*
|
|
291
|
+
* @param {string | null} clientId
|
|
292
|
+
*/
|
|
293
|
+
setClientId(clientId) {
|
|
294
|
+
this.clientId = clientId;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Sets the OIDC User.
|
|
299
|
+
*
|
|
300
|
+
* @see https://github.com/IdentityModel/oidc-client-js/wiki#user
|
|
301
|
+
* @param {Oidc.User | null} user - The OIDC User. Passing `null` resets OIDC authentication details.
|
|
302
|
+
*/
|
|
303
|
+
setUser(user) {
|
|
304
|
+
if (!user) {
|
|
305
|
+
this.user = null;
|
|
306
|
+
this.setToken(null);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
this.user = user;
|
|
310
|
+
this.setToken(user.access_token);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Returns a display name for the authenticated user.
|
|
316
|
+
*
|
|
317
|
+
* @returns {string?} Name of the user or `null`
|
|
318
|
+
*/
|
|
319
|
+
getDisplayName() {
|
|
320
|
+
if (this.user && Utils.isObject(this.user.profile)) {
|
|
321
|
+
return this.user.profile.name || this.user.profile.preferred_username || this.user.profile.email || null;
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Detects the default OIDC client ID for the given redirect URL.
|
|
328
|
+
*
|
|
329
|
+
* Sets the grant and client ID accordingly.
|
|
330
|
+
*
|
|
331
|
+
* @returns {OidcClient | null}
|
|
332
|
+
* @see OidcProvider#setGrant
|
|
333
|
+
* @see OidcProvider#setClientId
|
|
334
|
+
*/
|
|
335
|
+
detectDefaultClient() {
|
|
336
|
+
for(let grant of OidcProvider.grants) {
|
|
337
|
+
let defaultClient = this.defaultClients.find(client => Boolean(client.grant_types.includes(grant) && Array.isArray(client.redirect_urls) && client.redirect_urls.find(url => url.startsWith(OidcProvider.redirectUrl))));
|
|
338
|
+
if (defaultClient) {
|
|
339
|
+
this.setGrant(grant);
|
|
340
|
+
this.setClientId(defaultClient.id);
|
|
341
|
+
this.defaultClient = defaultClient;
|
|
342
|
+
return defaultClient;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* The global "UI" method to use to open the login URL, either "redirect" (default) or "popup".
|
|
353
|
+
*
|
|
354
|
+
* @type {string}
|
|
355
|
+
*/
|
|
356
|
+
OidcProvider.uiMethod = 'redirect';
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* The global redirect URL to use.
|
|
360
|
+
*
|
|
361
|
+
* By default uses the location of the browser, but removes fragment, query and
|
|
362
|
+
* trailing slash.
|
|
363
|
+
* The fragment conflicts with the fragment appended by the Implicit Flow and
|
|
364
|
+
* the query conflicts with the query appended by the Authorization Code Flow.
|
|
365
|
+
* The trailing slash is removed for consistency.
|
|
366
|
+
*
|
|
367
|
+
* @type {string}
|
|
368
|
+
*/
|
|
369
|
+
OidcProvider.redirectUrl = Environment.getUrl().split('#')[0].split('?')[0].replace(/\/$/, '');
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* The supported OpenID Connect grants (flows).
|
|
373
|
+
*
|
|
374
|
+
* The grants are given as defined in openEO API, e.g. `implicit` and/or `authorization_code+pkce`
|
|
375
|
+
* If not defined there, consult the OpenID Connect Discovery documentation.
|
|
376
|
+
*
|
|
377
|
+
* Lists the grants by priority so that the first grant is the default grant.
|
|
378
|
+
* The default grant type since client version 2.0.0 is 'authorization_code+pkce'.
|
|
379
|
+
*
|
|
380
|
+
* @type {Array.<string>}
|
|
381
|
+
*/
|
|
382
|
+
OidcProvider.grants = [
|
|
383
|
+
'authorization_code+pkce',
|
|
384
|
+
'implicit'
|
|
385
|
+
];
|
|
386
|
+
|
|
387
|
+
module.exports = OidcProvider;
|