@tidecloak/js 0.12.46 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,15 @@
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
7
16
  *
8
17
  * Modifications Copyright (C) 2025 Tide Foundation Ltd
9
18
  * Tide Protocol - Infrastructure for a TRUE Zero-Trust paradigm
@@ -22,1784 +31,1792 @@
22
31
  * You should have received a copy of the Tide Community Open Code License along
23
32
  * with this program. If not, see https://tide.org/licenses_tcoc2-0-0-en
24
33
  */
25
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
26
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
27
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
28
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
29
- };
30
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
31
- if (kind === "m") throw new TypeError("Private method is not writable");
32
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
33
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
34
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
35
- };
36
- var _TideCloak_instances, _TideCloak_refreshQueue, _TideCloak_adapter, _TideCloak_useNonce, _TideCloak_callbackStorage, _TideCloak_logInfo, _TideCloak_logWarn, _TideCloak_loginIframe, _TideCloak_config, _TideCloak_loadAdapter, _TideCloak_loadDefaultAdapter, _TideCloak_loadCordovaAdapter, _TideCloak_loadCordovaNativeAdapter, _TideCloak_loadConfig, _TideCloak_setupEndpoints, _TideCloak_loadOidcConfig, _TideCloak_setupOidcEndpoints, _TideCloak_check3pCookiesSupported, _TideCloak_processInit, _TideCloak_setupCheckLoginIframe, _TideCloak_checkLoginIframe, _TideCloak_checkSsoSilently, _TideCloak_parseCallback, _TideCloak_parseCallbackUrl, _TideCloak_parseCallbackParams, _TideCloak_processCallback, _TideCloak_scheduleCheckIframe, _TideCloak_getVoucherUrl, _TideCloak_setToken, _TideCloak_getRealmUrl, _TideCloak_createLogger, _LocalStorage_instances, _LocalStorage_clearInvalidValues, _LocalStorage_clearAllValues, _LocalStorage_getStoredEntries, _LocalStorage_parseExpiry, _CookieStorage_instances, _CookieStorage_getCookie, _CookieStorage_setCookie, _CookieStorage_cookieExpiration;
37
34
  // MODIFIED: Added dependency to external Tide helper libraries.
38
- import { RequestEnclave, ApprovalEnclave, ApprovalEnclaveNew } from "heimdall-tide";
39
- const CONTENT_TYPE_JSON = 'application/json';
40
- /**
41
- * @typedef {Object} Endpoints
42
- * @property {() => string} authorize
43
- * @property {() => string} token
44
- * @property {() => string} logout
45
- * @property {() => string} checkSessionIframe
46
- * @property {() => string=} thirdPartyCookiesIframe
47
- * @property {() => string} register
48
- * @property {() => string} userinfo
49
- */
50
- /**
51
- * @typedef {Object} LoginIframe
52
- * @property {boolean} enable
53
- * @property {((error: Error | null, value?: boolean) => void)[]} callbackList
54
- * @property {number} interval
55
- * @property {HTMLIFrameElement=} iframe
56
- * @property {string=} iframeOrigin
57
- */
58
- export { RequestEnclave, ApprovalEnclave, ApprovalEnclaveNew, TideMemory, BaseTideRequest, PolicySignRequest, Policy, PolicyParameters } from "heimdall-tide";
59
- class TideCloak {
60
- /**
61
- * @param {KeycloakConfig} config
62
- */
63
- constructor(config) {
64
- _TideCloak_instances.add(this);
65
- /** @type {Pick<PromiseWithResolvers<boolean>, 'resolve' | 'reject'>[]} */
66
- _TideCloak_refreshQueue.set(this, []
67
- /** @type {KeycloakAdapter} */
68
- );
69
- /** @type {KeycloakAdapter} */
70
- _TideCloak_adapter.set(this, void 0);
71
- /** @type {boolean} */
72
- _TideCloak_useNonce.set(this, true
73
- /** @type {CallbackStorage} */
74
- );
75
- /** @type {CallbackStorage} */
76
- _TideCloak_callbackStorage.set(this, void 0);
77
- _TideCloak_logInfo.set(this, __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_createLogger).call(this, console.info));
78
- _TideCloak_logWarn.set(this, __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_createLogger).call(this, console.warn)
79
- /** @type {LoginIframe} */
80
- );
81
- /** @type {LoginIframe} */
82
- _TideCloak_loginIframe.set(this, {
83
- enable: true,
84
- callbackList: [],
85
- interval: 5
86
- }
87
- /** @type {KeycloakConfig} config */
88
- );
89
- /** @type {KeycloakConfig} config */
90
- _TideCloak_config.set(this, void 0);
91
- this.didInitialize = false;
92
- this.authenticated = false;
93
- this.loginRequired = false;
94
- /** @type {KeycloakResponseMode} */
95
- this.responseMode = 'fragment';
96
- /** @type {KeycloakResponseType} */
97
- this.responseType = 'code';
98
- /** @type {KeycloakFlow} */
99
- this.flow = 'standard';
100
- /** @type {boolean} */
101
- this.silentCheckSsoFallback = true;
102
- /** @type {KeycloakPkceMethod} */
103
- this.pkceMethod = 'S256';
104
- this.enableLogging = false;
105
- /** @type {'GET' | 'POST'} */
106
- this.logoutMethod = 'GET';
107
- this.messageReceiveTimeout = 10000;
108
- if (typeof config !== 'string' && !isObject(config)) {
109
- throw new Error("The 'TideCloak' constructor must be provided with a configuration object, or a URL to a JSON configuration file.");
110
- }
111
- // if (isObject(config)) {
112
- // const requiredProperties = 'oidcProvider' in config
113
- // ? ['clientId']
114
- // : ['url', 'realm', 'clientId', 'homeOrkUrl', 'vendorId', 'clientOriginAuth']
115
- // for (const property of requiredProperties) {
116
- // if (!config[property]) {
117
- // throw new Error(`The configuration object is missing the required '${property}' property.`)
118
- // }
119
- // }
120
- // }
121
- if (!globalThis.isSecureContext) {
122
- __classPrivateFieldGet(this, _TideCloak_logWarn, "f").call(this, "[TIDECLOAK] TideCloak JS must be used in a 'secure context' to function properly as it relies on browser APIs that are otherwise not available.\n" +
123
- 'Continuing to run your application insecurely will lead to unexpected behavior and breakage.\n\n' +
124
- 'For more information see: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts');
125
- }
126
- __classPrivateFieldSet(this, _TideCloak_config, config, "f");
35
+ import { RequestEnclave, ApprovalEnclave } from "heimdall-tide";
36
+ import { StringFromUint8Array, StringToUint8Array, CreateTideMemory } from "../modules/tide-js/Cryptide/Serialization.js";
37
+ import { AuthorizedEncryptionFlow } from "../modules/tide-js/Flow/EncryptionFlows/AuthorizedEncryptionFlow.js";
38
+ import dVVKSigningFlow_DEPRECATED from "../modules/tide-js/Flow/SigningFlows/dVVKSigningFlow_DEPRECATED.js";
39
+ import CardanoTxBodySignRequest from "../modules/tide-js/Models/Transactions/CardanoTxBodySignRequest.js";
40
+ import RuleSettingsSignRequest from "../modules/tide-js/Models/Rules/RuleSettingSignRequest.js";
41
+ import AuthorizationBuilder from "../modules/tide-js/Models/AuthorizationBuilder.js";
42
+ import { GenSessKey, GetPublic } from "../modules/tide-js/Cryptide/Math.js";
43
+ import NetworkClient from "../modules/tide-js/Clients/NetworkClient.js";
44
+ import { ModelRegistry } from "../modules/tide-js/Models/ModelRegistry.js";
45
+ import processThresholdRules from "../modules/tide-js/RulesEngine/thresholdRules.js";
46
+ import dVVKDecryptionFlow from "../modules/tide-js/Flow/DecryptionFlows/dVVKDecryptionFlow.js";
47
+ import dVVKSigningFlow from "../modules/tide-js/Flow/SigningFlows/dVVKSigningFlow.js";
48
+ // MODIFIED: Refactored `Keycloak` class into `TideCloak`.
49
+ function TideCloak(config) {
50
+ if (!(this instanceof TideCloak)) {
51
+ throw new Error("The 'TideCloak' constructor must be invoked with 'new'.");
52
+ }
53
+ if (typeof config !== 'string' && !isObject(config)) {
54
+ throw new Error("The 'TideCloak' constructor must be provided with a configuration object, or a URL to a JSON configuration file.");
55
+ }
56
+ if (isObject(config)) {
57
+ const requiredProperties = 'oidcProvider' in config
58
+ ? ['clientId']
59
+ : ['url', 'realm', 'clientId', 'homeOrkUrl', 'vendorId', 'clientOriginAuth'];
60
+ for (const property of requiredProperties) {
61
+ if (!config[property]) {
62
+ throw new Error(`The configuration object is missing the required '${property}' property.`);
63
+ }
64
+ }
127
65
  }
128
- /**
129
- * @param {KeycloakInitOptions} initOptions
130
- * @returns {Promise<boolean>}
131
- */
132
- async init(initOptions = {}) {
133
- var _a;
134
- if (this.didInitialize) {
66
+ var kc = this;
67
+ var adapter;
68
+ var refreshQueue = [];
69
+ var callbackStorage;
70
+ var loginIframe = {
71
+ enable: true,
72
+ callbackList: [],
73
+ interval: 5
74
+ };
75
+ kc.didInitialize = false;
76
+ var useNonce = true;
77
+ var logInfo = createLogger(console.info);
78
+ var logWarn = createLogger(console.warn);
79
+ if (!globalThis.isSecureContext) {
80
+ logWarn("[TIDECLOAK] TideCloak-JS must be used in a 'secure context' to function properly as it relies on browser APIs that are otherwise not available.\n" +
81
+ "Continuing to run your application insecurely will lead to unexpected behavior and breakage.\n\n" +
82
+ "For more information see: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts");
83
+ }
84
+ kc.init = function (initOptions = {}) {
85
+ if (kc.didInitialize) {
135
86
  throw new Error("A 'TideCloak' instance can only be initialized once.");
136
87
  }
137
- this.didInitialize = true;
138
- __classPrivateFieldSet(this, _TideCloak_callbackStorage, createCallbackStorage(), "f");
139
- const adapters = ['default', 'cordova', 'cordova-native'];
140
- if (typeof initOptions.adapter === 'string' && adapters.includes(initOptions.adapter)) {
141
- __classPrivateFieldSet(this, _TideCloak_adapter, __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadAdapter).call(this, initOptions.adapter), "f");
88
+ kc.didInitialize = true;
89
+ kc.authenticated = false;
90
+ callbackStorage = createCallbackStorage();
91
+ var adapters = ['default', 'cordova', 'cordova-native'];
92
+ if (adapters.indexOf(initOptions.adapter) > -1) {
93
+ adapter = loadAdapter(initOptions.adapter);
142
94
  }
143
- else if (typeof initOptions.adapter === 'object') {
144
- __classPrivateFieldSet(this, _TideCloak_adapter, initOptions.adapter, "f");
145
- }
146
- else if ('Cordova' in window || 'cordova' in window) {
147
- __classPrivateFieldSet(this, _TideCloak_adapter, __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadAdapter).call(this, 'cordova'), "f");
95
+ else if (typeof initOptions.adapter === "object") {
96
+ adapter = initOptions.adapter;
148
97
  }
149
98
  else {
150
- __classPrivateFieldSet(this, _TideCloak_adapter, __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadAdapter).call(this, 'default'), "f");
99
+ if (window.Cordova || window.cordova) {
100
+ adapter = loadAdapter('cordova');
101
+ }
102
+ else {
103
+ adapter = loadAdapter();
104
+ }
151
105
  }
152
106
  if (typeof initOptions.useNonce !== 'undefined') {
153
- __classPrivateFieldSet(this, _TideCloak_useNonce, initOptions.useNonce, "f");
107
+ useNonce = initOptions.useNonce;
154
108
  }
155
109
  if (typeof initOptions.checkLoginIframe !== 'undefined') {
156
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable = initOptions.checkLoginIframe;
110
+ loginIframe.enable = initOptions.checkLoginIframe;
157
111
  }
158
112
  if (initOptions.checkLoginIframeInterval) {
159
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").interval = initOptions.checkLoginIframeInterval;
113
+ loginIframe.interval = initOptions.checkLoginIframeInterval;
160
114
  }
161
115
  if (initOptions.onLoad === 'login-required') {
162
- this.loginRequired = true;
116
+ kc.loginRequired = true;
163
117
  }
164
118
  if (initOptions.responseMode) {
165
119
  if (initOptions.responseMode === 'query' || initOptions.responseMode === 'fragment') {
166
- this.responseMode = initOptions.responseMode;
120
+ kc.responseMode = initOptions.responseMode;
167
121
  }
168
122
  else {
169
- throw new Error('Invalid value for responseMode');
123
+ throw 'Invalid value for responseMode';
170
124
  }
171
125
  }
172
126
  if (initOptions.flow) {
173
127
  switch (initOptions.flow) {
174
128
  case 'standard':
175
- this.responseType = 'code';
129
+ kc.responseType = 'code';
176
130
  break;
177
131
  case 'implicit':
178
- this.responseType = 'id_token token';
132
+ kc.responseType = 'id_token token';
179
133
  break;
180
134
  case 'hybrid':
181
- this.responseType = 'code id_token token';
135
+ kc.responseType = 'code id_token token';
182
136
  break;
183
137
  default:
184
- throw new Error('Invalid value for flow');
138
+ throw 'Invalid value for flow';
185
139
  }
186
- this.flow = initOptions.flow;
140
+ kc.flow = initOptions.flow;
187
141
  }
188
- if (typeof initOptions.timeSkew === 'number') {
189
- this.timeSkew = initOptions.timeSkew;
142
+ if (initOptions.timeSkew != null) {
143
+ kc.timeSkew = initOptions.timeSkew;
190
144
  }
191
145
  if (initOptions.redirectUri) {
192
- this.redirectUri = initOptions.redirectUri;
146
+ kc.redirectUri = initOptions.redirectUri;
193
147
  }
194
148
  if (initOptions.silentCheckSsoRedirectUri) {
195
- this.silentCheckSsoRedirectUri = initOptions.silentCheckSsoRedirectUri;
149
+ kc.silentCheckSsoRedirectUri = initOptions.silentCheckSsoRedirectUri;
196
150
  }
197
151
  if (typeof initOptions.silentCheckSsoFallback === 'boolean') {
198
- this.silentCheckSsoFallback = initOptions.silentCheckSsoFallback;
152
+ kc.silentCheckSsoFallback = initOptions.silentCheckSsoFallback;
153
+ }
154
+ else {
155
+ kc.silentCheckSsoFallback = true;
199
156
  }
200
- if (typeof initOptions.pkceMethod !== 'undefined') {
201
- if (initOptions.pkceMethod !== 'S256' && initOptions.pkceMethod !== false) {
157
+ if (typeof initOptions.pkceMethod !== "undefined") {
158
+ if (initOptions.pkceMethod !== "S256" && initOptions.pkceMethod !== false) {
202
159
  throw new TypeError(`Invalid value for pkceMethod', expected 'S256' or false but got ${initOptions.pkceMethod}.`);
203
160
  }
204
- this.pkceMethod = initOptions.pkceMethod;
161
+ kc.pkceMethod = initOptions.pkceMethod;
162
+ }
163
+ else {
164
+ kc.pkceMethod = "S256";
205
165
  }
206
166
  if (typeof initOptions.enableLogging === 'boolean') {
207
- this.enableLogging = initOptions.enableLogging;
167
+ kc.enableLogging = initOptions.enableLogging;
168
+ }
169
+ else {
170
+ kc.enableLogging = false;
208
171
  }
209
172
  if (initOptions.logoutMethod === 'POST') {
210
- this.logoutMethod = 'POST';
173
+ kc.logoutMethod = 'POST';
174
+ }
175
+ else {
176
+ kc.logoutMethod = 'GET';
211
177
  }
212
178
  if (typeof initOptions.scope === 'string') {
213
- this.scope = initOptions.scope;
179
+ kc.scope = initOptions.scope;
214
180
  }
215
181
  if (typeof initOptions.acrValues === 'string') {
216
- this.acrValues = initOptions.acrValues;
182
+ kc.acrValues = initOptions.acrValues;
217
183
  }
218
184
  if (typeof initOptions.messageReceiveTimeout === 'number' && initOptions.messageReceiveTimeout > 0) {
219
- this.messageReceiveTimeout = initOptions.messageReceiveTimeout;
220
- }
221
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadConfig).call(this);
222
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_check3pCookiesSupported).call(this);
223
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processInit).call(this, initOptions);
224
- (_a = this.onReady) === null || _a === void 0 ? void 0 : _a.call(this, this.authenticated);
225
- return this.authenticated;
226
- }
227
- ;
228
- /**
229
- * @param {KeycloakLoginOptions} [options]
230
- * @returns {Promise<void>}
231
- */
232
- login(options) {
233
- return __classPrivateFieldGet(this, _TideCloak_adapter, "f").login(options);
234
- }
235
- /**
236
- * Ensure the access token is valid, refreshing if needed.
237
- * @returns {Promise<void>}
238
- */
239
- async ensureTokenReady() {
240
- if (!this.tokenParsed)
241
- return;
242
- if (this.isTokenExpired()) {
243
- await this.updateToken(-1);
244
- }
245
- }
246
- /**
247
- * @param {KeycloakLoginOptions} [options]
248
- * @returns {Promise<string>}
249
- */
250
- async createLoginUrl(options) {
251
- const state = createUUID();
252
- const nonce = createUUID();
253
- const redirectUri = __classPrivateFieldGet(this, _TideCloak_adapter, "f").redirectUri(options);
254
- /** @type {CallbackState} */
255
- const callbackState = {
256
- state,
257
- nonce,
258
- redirectUri,
259
- loginOptions: options
260
- };
261
- if (options === null || options === void 0 ? void 0 : options.prompt) {
262
- callbackState.prompt = options.prompt;
263
- }
264
- const url = (options === null || options === void 0 ? void 0 : options.action) === 'register'
265
- ? this.endpoints.register()
266
- : this.endpoints.authorize();
267
- let scope = (options === null || options === void 0 ? void 0 : options.scope) || this.scope;
268
- const scopeValues = scope ? scope.split(' ') : [];
269
- // Ensure the 'openid' scope is always included.
270
- if (!scopeValues.includes('openid')) {
271
- scopeValues.unshift('openid');
272
- }
273
- scope = scopeValues.join(' ');
274
- const params = new URLSearchParams([
275
- ['client_id', /** @type {string} */ (this.clientId)],
276
- // The endpoint URI MUST NOT include a fragment component.
277
- // https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2
278
- ['redirect_uri', stripHash(redirectUri)],
279
- ['state', state],
280
- ['response_mode', this.responseMode],
281
- ['response_type', this.responseType],
282
- ['scope', scope]
283
- ]);
284
- if (__classPrivateFieldGet(this, _TideCloak_useNonce, "f")) {
285
- params.append('nonce', nonce);
286
- }
287
- if (options === null || options === void 0 ? void 0 : options.prompt) {
288
- params.append('prompt', options.prompt);
289
- }
290
- if (typeof (options === null || options === void 0 ? void 0 : options.maxAge) === 'number') {
291
- params.append('max_age', options.maxAge.toString());
292
- }
293
- if (options === null || options === void 0 ? void 0 : options.loginHint) {
294
- params.append('login_hint', options.loginHint);
295
- }
296
- if (options === null || options === void 0 ? void 0 : options.idpHint) {
297
- params.append('kc_idp_hint', options.idpHint);
298
- }
299
- if ((options === null || options === void 0 ? void 0 : options.action) && options.action !== 'register') {
300
- params.append('kc_action', options.action);
301
- }
302
- if (options === null || options === void 0 ? void 0 : options.locale) {
303
- params.append('ui_locales', options.locale);
304
- }
305
- if (options === null || options === void 0 ? void 0 : options.acr) {
306
- params.append('claims', buildClaimsParameter(options.acr));
307
- }
308
- if ((options === null || options === void 0 ? void 0 : options.acrValues) || this.acrValues) {
309
- params.append('acr_values', options.acrValues || this.acrValues);
310
- }
311
- if (this.pkceMethod) {
312
- try {
313
- const codeVerifier = generateCodeVerifier(96);
314
- const pkceChallenge = await generatePkceChallenge(this.pkceMethod, codeVerifier);
315
- callbackState.pkceCodeVerifier = codeVerifier;
316
- params.append('code_challenge', pkceChallenge);
317
- params.append('code_challenge_method', this.pkceMethod);
318
- }
319
- catch (error) {
320
- throw new Error('Failed to generate PKCE challenge.', { cause: error });
321
- }
322
- }
323
- __classPrivateFieldGet(this, _TideCloak_callbackStorage, "f").add(callbackState);
324
- return `${url}?${params.toString()}`;
325
- }
326
- /**
327
- * @param {KeycloakLogoutOptions} [options]
328
- * @returns {Promise<void>}
329
- */
330
- logout(options) {
331
- return __classPrivateFieldGet(this, _TideCloak_adapter, "f").logout(options);
332
- }
333
- /**
334
- * @param {KeycloakLogoutOptions} [options]
335
- * @returns {string}
336
- */
337
- createLogoutUrl(options) {
338
- var _a;
339
- const logoutMethod = (_a = options === null || options === void 0 ? void 0 : options.logoutMethod) !== null && _a !== void 0 ? _a : this.logoutMethod;
340
- const url = this.endpoints.logout();
341
- if (logoutMethod === 'POST') {
342
- return url;
343
- }
344
- const params = new URLSearchParams([
345
- ['client_id', /** @type {string} */ (this.clientId)],
346
- ['post_logout_redirect_uri', __classPrivateFieldGet(this, _TideCloak_adapter, "f").redirectUri(options)]
347
- ]);
348
- if (this.idToken) {
349
- params.append('id_token_hint', this.idToken);
350
- }
351
- return `${url}?${params.toString()}`;
352
- }
353
- /**
354
- * @param {KeycloakRegisterOptions} [options]
355
- * @returns {Promise<void>}
356
- */
357
- register(options) {
358
- return __classPrivateFieldGet(this, _TideCloak_adapter, "f").register(options);
359
- }
360
- /**
361
- * @param {KeycloakRegisterOptions} [options]
362
- * @returns {Promise<string>}
363
- */
364
- createRegisterUrl(options) {
365
- return this.createLoginUrl({ ...options, action: 'register' });
366
- }
367
- /**
368
- * @param {KeycloakAccountOptions} [options]
369
- * @returns {string}
370
- */
371
- createAccountUrl(options) {
372
- const url = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this);
373
- if (!url) {
374
- throw new Error('Unable to create account URL, make sure the adapter is not configured using a generic OIDC provider.');
375
- }
376
- const params = new URLSearchParams([
377
- ['referrer', /** @type {string} */ (this.clientId)],
378
- ['referrer_uri', __classPrivateFieldGet(this, _TideCloak_adapter, "f").redirectUri(options)]
379
- ]);
380
- return `${url}/account?${params.toString()}`;
381
- }
382
- /**
383
- * @returns {Promise<void>}
384
- */
385
- accountManagement() {
386
- return __classPrivateFieldGet(this, _TideCloak_adapter, "f").accountManagement();
387
- }
388
- /**
389
- * @param {string} role
390
- * @returns {boolean}
391
- */
392
- hasRealmRole(role) {
393
- const access = this.realmAccess;
394
- return !!access && access.roles.indexOf(role) >= 0;
395
- }
396
- /**
397
- * @param {string} role
398
- * @param {string} [resource]
399
- * @returns {boolean}
400
- */
401
- hasResourceRole(role, resource) {
402
- if (!this.resourceAccess) {
403
- return false;
185
+ kc.messageReceiveTimeout = initOptions.messageReceiveTimeout;
404
186
  }
405
- const access = this.resourceAccess[resource || /** @type {string} */ (this.clientId)];
406
- return !!access && access.roles.indexOf(role) >= 0;
407
- }
408
- /**
409
- * @returns {Promise<KeycloakProfile>}
410
- */
411
- async loadUserProfile() {
412
- const realmUrl = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this);
413
- if (!realmUrl) {
414
- throw new Error('Unable to load user profile, make sure the adapter is not configured using a generic OIDC provider.');
415
- }
416
- const url = `${realmUrl}/account`;
417
- /** @type {KeycloakProfile} */
418
- const profile = await fetchJSON(url, {
419
- headers: [buildAuthorizationHeader(this.token)]
420
- });
421
- return (this.profile = profile);
422
- }
423
- /**
424
- * @returns {Promise<KeycloakUserInfo>}
425
- */
426
- async loadUserInfo() {
427
- const url = this.endpoints.userinfo();
428
- /** @type {KeycloakUserInfo} */
429
- const userInfo = await fetchJSON(url, {
430
- headers: [buildAuthorizationHeader(this.token)]
187
+ else {
188
+ kc.messageReceiveTimeout = 10000;
189
+ }
190
+ if (!kc.responseMode) {
191
+ kc.responseMode = 'fragment';
192
+ }
193
+ if (!kc.responseType) {
194
+ kc.responseType = 'code';
195
+ kc.flow = 'standard';
196
+ }
197
+ var promise = createPromise();
198
+ var initPromise = createPromise();
199
+ initPromise.promise.then(function () {
200
+ kc.onReady && kc.onReady(kc.authenticated);
201
+ promise.setSuccess(kc.authenticated);
202
+ }).catch(function (error) {
203
+ promise.setError(error);
431
204
  });
432
- return (this.userInfo = userInfo);
433
- }
434
- /**
435
- * @param {number} [minValidity]
436
- * @returns {boolean}
437
- */
438
- isTokenExpired(minValidity) {
439
- if (!this.tokenParsed || (!this.refreshToken && this.flow !== 'implicit')) {
440
- throw new Error('Not authenticated');
441
- }
442
- if (this.timeSkew == null) {
443
- __classPrivateFieldGet(this, _TideCloak_logInfo, "f").call(this, '[TIDECLOAK] Unable to determine if token is expired as timeskew is not set');
444
- return true;
445
- }
446
- if (typeof this.tokenParsed.exp !== 'number') {
447
- return false;
448
- }
449
- let expiresIn = this.tokenParsed.exp - Math.ceil(new Date().getTime() / 1000) + this.timeSkew;
450
- if (minValidity) {
451
- if (isNaN(minValidity)) {
452
- throw new Error('Invalid minValidity');
453
- }
454
- expiresIn -= minValidity;
455
- }
456
- return expiresIn < 0;
457
- }
458
- /**
459
- * Matches Keycloak: minValidity is optional.
460
- * @param {number} [minValidity]
461
- * @returns {Promise<boolean>}
462
- */
463
- async updateToken(minValidity) {
464
- var _a, _b;
465
- if (!this.refreshToken) {
466
- throw new Error('Unable to update token, no refresh token available.');
467
- }
468
- minValidity = minValidity || 5;
469
- if (__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable) {
470
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_checkLoginIframe).call(this);
471
- }
472
- let refreshToken = false;
473
- if (minValidity === -1) {
474
- refreshToken = true;
475
- __classPrivateFieldGet(this, _TideCloak_logInfo, "f").call(this, '[TIDECLOAK] Refreshing token: forced refresh');
476
- }
477
- else if (!this.tokenParsed || this.isTokenExpired(minValidity)) {
478
- refreshToken = true;
479
- __classPrivateFieldGet(this, _TideCloak_logInfo, "f").call(this, '[TIDECLOAK] Refreshing token: token expired');
480
- }
481
- if (!refreshToken) {
482
- return false;
483
- }
484
- /** @type {PromiseWithResolvers<boolean>} */
485
- const { promise, resolve, reject } = Promise.withResolvers();
486
- __classPrivateFieldGet(this, _TideCloak_refreshQueue, "f").push({ resolve, reject });
487
- if (__classPrivateFieldGet(this, _TideCloak_refreshQueue, "f").length === 1) {
488
- const url = this.endpoints.token();
489
- let timeLocal = new Date().getTime();
490
- try {
491
- const response = await fetchRefreshToken(url, this.refreshToken, /** @type {string} */ (this.clientId));
492
- __classPrivateFieldGet(this, _TideCloak_logInfo, "f").call(this, '[TIDECLOAK] Token refreshed');
493
- timeLocal = (timeLocal + new Date().getTime()) / 2;
494
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setToken).call(this, response.access_token, response.refresh_token, response.id_token, timeLocal, response.doken);
495
- (_a = this.onAuthRefreshSuccess) === null || _a === void 0 ? void 0 : _a.call(this);
496
- for (let p = __classPrivateFieldGet(this, _TideCloak_refreshQueue, "f").pop(); p != null; p = __classPrivateFieldGet(this, _TideCloak_refreshQueue, "f").pop()) {
497
- p.resolve(true);
498
- }
499
- }
500
- catch (error) {
501
- __classPrivateFieldGet(this, _TideCloak_logWarn, "f").call(this, '[TIDECLOAK] Failed to refresh token');
502
- if (error instanceof NetworkError && error.response.status === 400) {
503
- this.clearToken();
205
+ var configPromise = loadConfig();
206
+ function onLoad() {
207
+ var doLogin = function (prompt) {
208
+ if (!prompt) {
209
+ options.prompt = 'none';
504
210
  }
505
- (_b = this.onAuthRefreshError) === null || _b === void 0 ? void 0 : _b.call(this);
506
- for (let p = __classPrivateFieldGet(this, _TideCloak_refreshQueue, "f").pop(); p != null; p = __classPrivateFieldGet(this, _TideCloak_refreshQueue, "f").pop()) {
507
- p.reject(error);
211
+ if (initOptions.locale) {
212
+ options.locale = initOptions.locale;
508
213
  }
214
+ kc.login(options).then(function () {
215
+ initPromise.setSuccess();
216
+ }).catch(function (error) {
217
+ initPromise.setError(error);
218
+ });
219
+ };
220
+ var checkSsoSilently = async function () {
221
+ var ifrm = document.createElement("iframe");
222
+ var src = await kc.createLoginUrl({ prompt: 'none', redirectUri: kc.silentCheckSsoRedirectUri });
223
+ ifrm.setAttribute("src", src);
224
+ ifrm.setAttribute("sandbox", "allow-storage-access-by-user-activation allow-scripts allow-same-origin");
225
+ ifrm.setAttribute("title", "keycloak-silent-check-sso");
226
+ ifrm.style.display = "none";
227
+ document.body.appendChild(ifrm);
228
+ var messageCallback = function (event) {
229
+ if (event.origin !== window.location.origin || ifrm.contentWindow !== event.source) {
230
+ return;
231
+ }
232
+ var oauth = parseCallback(event.data);
233
+ processCallback(oauth, initPromise);
234
+ document.body.removeChild(ifrm);
235
+ window.removeEventListener("message", messageCallback);
236
+ };
237
+ window.addEventListener("message", messageCallback);
238
+ };
239
+ var options = {};
240
+ switch (initOptions.onLoad) {
241
+ case 'check-sso':
242
+ if (loginIframe.enable) {
243
+ setupCheckLoginIframe().then(function () {
244
+ checkLoginIframe().then(function (unchanged) {
245
+ if (!unchanged) {
246
+ kc.silentCheckSsoRedirectUri ? checkSsoSilently() : doLogin(false);
247
+ }
248
+ else {
249
+ initPromise.setSuccess();
250
+ }
251
+ }).catch(function (error) {
252
+ initPromise.setError(error);
253
+ });
254
+ });
255
+ }
256
+ else {
257
+ kc.silentCheckSsoRedirectUri ? checkSsoSilently() : doLogin(false);
258
+ }
259
+ break;
260
+ case 'login-required':
261
+ doLogin(true);
262
+ break;
263
+ default:
264
+ throw 'Invalid value for onLoad';
509
265
  }
510
266
  }
511
- return await promise;
512
- }
513
- clearToken() {
514
- var _a;
515
- if (this.token) {
516
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setToken).call(this);
517
- (_a = this.onAuthLogout) === null || _a === void 0 ? void 0 : _a.call(this);
518
- if (this.loginRequired) {
519
- this.login();
267
+ function processInit() {
268
+ var callback = parseCallback(window.location.href);
269
+ if (callback) {
270
+ window.history.replaceState(window.history.state, null, callback.newUrl);
520
271
  }
521
- }
522
- }
523
- /**
524
- * Initialize Tide RequestEnclave.
525
- */
526
- initRequestEnclave() {
527
- if (!this.doken)
528
- throw new Error('[TIDECLOAK] No doken found');
529
- if (!this.dokenParsed)
530
- throw new Error('[TIDECLOAK] Token not parsed');
531
- if (!this.requestEnclave) {
532
- this.requestEnclave = new RequestEnclave({
533
- homeOrkOrigin: this.dokenParsed['t.uho'],
534
- signed_client_origin: __classPrivateFieldGet(this, _TideCloak_config, "f")['clientOriginAuth'],
535
- vendorId: __classPrivateFieldGet(this, _TideCloak_config, "f").vendorId,
536
- voucherURL: __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getVoucherUrl).call(this)
537
- }).init({
538
- doken: this.doken,
539
- dokenRefreshCallback: async () => {
540
- await this.ensureTokenReady();
541
- if (!this.doken)
542
- throw new Error('[TIDECLOAK] No doken found');
543
- return this.doken;
544
- },
545
- requireReloginCallback: async () => {
546
- await this.login({
547
- idpHint: 'tide',
548
- prompt: 'login',
549
- redirectUri: window.location.href
272
+ if (callback && callback.valid) {
273
+ return setupCheckLoginIframe().then(function () {
274
+ processCallback(callback, initPromise);
275
+ }).catch(function (error) {
276
+ initPromise.setError(error);
277
+ });
278
+ }
279
+ if (initOptions.token && initOptions.refreshToken) {
280
+ setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
281
+ if (loginIframe.enable) {
282
+ setupCheckLoginIframe().then(function () {
283
+ checkLoginIframe().then(function (unchanged) {
284
+ if (unchanged) {
285
+ kc.onAuthSuccess && kc.onAuthSuccess();
286
+ initPromise.setSuccess();
287
+ scheduleCheckIframe();
288
+ }
289
+ else {
290
+ initPromise.setSuccess();
291
+ }
292
+ }).catch(function (error) {
293
+ initPromise.setError(error);
294
+ });
550
295
  });
551
296
  }
552
- });
553
- }
554
- }
555
- /**
556
- * Initialize Tide ApprovalEnclave.
557
- */
558
- initApprovalEnclave() {
559
- if (!this.doken)
560
- throw new Error('[TIDECLOAK] No doken found');
561
- if (!this.dokenParsed)
562
- throw new Error('[TIDECLOAK] Token not parsed');
563
- if (!this.approvalEnclave) {
564
- this.approvalEnclave = new ApprovalEnclaveNew({
565
- homeOrkOrigin: this.dokenParsed['t.uho'],
566
- signed_client_origin: __classPrivateFieldGet(this, _TideCloak_config, "f")['clientOriginAuth'],
567
- vendorId: __classPrivateFieldGet(this, _TideCloak_config, "f").vendorId,
568
- voucherURL: __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getVoucherUrl).call(this)
569
- }).init({
570
- doken: this.doken,
571
- dokenRefreshCallback: async () => {
572
- await this.ensureTokenReady();
573
- if (!this.doken)
574
- throw new Error('[TIDECLOAK] No doken found');
575
- return this.doken;
576
- },
577
- requireReloginCallback: async () => {
578
- await this.login({
579
- idpHint: 'tide',
580
- prompt: 'login',
581
- redirectUri: window.location.href
297
+ else {
298
+ kc.updateToken(-1).then(function () {
299
+ kc.onAuthSuccess && kc.onAuthSuccess();
300
+ initPromise.setSuccess();
301
+ }).catch(function (error) {
302
+ kc.onAuthError && kc.onAuthError();
303
+ if (initOptions.onLoad) {
304
+ onLoad();
305
+ }
306
+ else {
307
+ initPromise.setError(error);
308
+ }
582
309
  });
583
310
  }
311
+ }
312
+ else if (initOptions.onLoad) {
313
+ onLoad();
314
+ }
315
+ else {
316
+ initPromise.setSuccess();
317
+ }
318
+ }
319
+ configPromise.then(function () {
320
+ check3pCookiesSupported()
321
+ .then(processInit)
322
+ .catch(function (error) {
323
+ promise.setError(error);
584
324
  });
325
+ });
326
+ configPromise.catch(function (error) {
327
+ promise.setError(error);
328
+ });
329
+ return promise.promise;
330
+ };
331
+ kc.login = function (options) {
332
+ return adapter.login(options);
333
+ };
334
+ kc.ensureTokenReady = async function () {
335
+ if (kc.isTokenExpired()) {
336
+ await kc.updateToken(-1);
585
337
  }
586
- }
587
- /**
588
- * Role-based encryption via Tide RequestEnclave.
589
- * @param {{ data: string | Uint8Array, tags: string[] }[]} toEncrypt
590
- * @returns {Promise<(string | Uint8Array)[]>}
591
- */
592
- async encrypt(toEncrypt) {
593
- await this.ensureTokenReady();
338
+ };
339
+ // MODIFIED: Added role-based encryption functionality.
340
+ kc.encrypt = async function (toEncrypt) {
341
+ await kc.ensureTokenReady();
342
+ // Check config
594
343
  if (!Array.isArray(toEncrypt)) {
595
- throw new Error('Pass array as parameter');
344
+ throw 'Pass array as parameter';
596
345
  }
597
- if (!this.tokenParsed) {
598
- throw new Error('Not authenticated');
346
+ // Check user authenticated
347
+ if (!kc.tokenParsed) {
348
+ throw 'Not authenticated';
599
349
  }
600
- const dataToSend = toEncrypt.map((e) => {
350
+ const dataToSend = toEncrypt.map(e => {
601
351
  if (!isObject(e))
602
- throw new Error('All entries must be an object to encrypt');
603
- for (const property of ['data', 'tags']) {
352
+ throw 'All entries must be an object to encrypt';
353
+ for (const property of ["data", "tags"]) {
604
354
  if (!e[property]) {
605
355
  throw new Error(`The configuration object is missing the required '${property}' property.`);
606
356
  }
607
357
  }
608
358
  if (!Array.isArray(e.tags))
609
- throw new Error('tags must be provided as a string array in object to encrypt');
610
- if (typeof e.data !== 'string' && !(e.data instanceof Uint8Array)) {
611
- throw new Error('data must be provided as string or Uint8Array in object to encrypt');
612
- }
359
+ throw 'tags must be provided as a string array in object to encrypt';
360
+ if (typeof e.data !== "string" && !(e.data instanceof Uint8Array))
361
+ throw 'data must be provded as string or Uint8Array in object to encrypt';
362
+ // Check that the user has the roles required to encrypt the datas
613
363
  for (const tag of e.tags) {
614
- if (typeof tag !== 'string')
615
- throw new Error('tags must be provided as an array of strings');
616
- const tagAccess = this.hasRealmRole(`_tide_${tag}.selfencrypt`);
364
+ if (typeof tag !== "string")
365
+ throw "tags must be provided as an array of strings";
366
+ var tagAccess = kc.hasRealmRole("_tide_" + tag + ".selfencrypt");
617
367
  if (!tagAccess)
618
- throw new Error(`User has not been given any access to '${tag}'`);
368
+ throw `'User has not been given any access to '${tag}'`;
619
369
  }
620
370
  return {
621
- data: typeof e.data === 'string' ? StringToUint8Array(e.data) : e.data,
371
+ data: typeof e.data === "string" ? StringToUint8Array(e.data) : e.data, // convert data to byte array or leave as is if its already a byte array
622
372
  tags: e.tags,
623
- isRaw: typeof e.data === 'string' ? false : true
373
+ isRaw: typeof e.data === "string" ? false : true // indicate whether this piece of data was encrypted raw or not
624
374
  };
625
375
  });
626
- this.initRequestEnclave();
627
- const encrypted = await this.requestEnclave.encrypt(dataToSend);
628
- return encrypted.map((cipher, i) => (dataToSend[i].isRaw ? cipher : bytesToBase64(cipher)));
629
- }
630
- /**
631
- * Initialize a Tide request that requires operator approvals.
632
- * @param {Uint8Array} encodedRequest
633
- * @returns {Promise<Uint8Array>}
634
- */
635
- async createTideRequest(encodedRequest) {
636
- await this.ensureTokenReady();
637
- this.initRequestEnclave();
638
- return await this.requestEnclave.initializeRequest(encodedRequest);
639
- }
640
- /**
641
- * Request Tide operator approval.
642
- * @param {{id: string, request: Uint8Array}[]} requests
643
- * @returns {Promise<{approved: {id: string, request: Uint8Array}[], denied: {id: string}[], pending: {id: string}[]}>}
644
- */
645
- async requestTideOperatorApproval(requests) {
646
- await this.ensureTokenReady();
647
- this.initApprovalEnclave();
648
- return await this.approvalEnclave.approve(requests);
649
- }
650
- /**
651
- * Execute a Tide Sign Request
652
- * @param {Uint8Array} request
653
- * @returns Array of signatures
654
- */
655
- async executeSignRequest(request) {
656
- await this.ensureTokenReady();
657
- this.initRequestEnclave();
658
- return await this.requestEnclave.execute(request);
659
- }
660
- /**
661
- * Role-based decryption via Tide RequestEnclave.
662
- * @param {{ encrypted: string | Uint8Array, tags: string[] }[]} toDecrypt
663
- * @returns {Promise<(string | Uint8Array)[]>}
664
- */
665
- async decrypt(toDecrypt) {
666
- await this.ensureTokenReady();
376
+ kc.initEnclave();
377
+ // Now lets actually encrypt
378
+ // Construct Tide serialized data payloads
379
+ return (await kc.requestEnclave.encrypt(dataToSend)).map((e, i) => dataToSend[i].isRaw ? e : bytesToBase64(e)); // return a byte array cipher if encrypted as byte array, or a string cipher if encrypted as a string
380
+ };
381
+ function StringToUint8Array(string) {
382
+ const enc = new TextEncoder();
383
+ return enc.encode(string);
384
+ }
385
+ function StringFromUint8Array(bytes) {
386
+ const decoder = new TextDecoder('utf-8');
387
+ return decoder.decode(bytes);
388
+ }
389
+ kc.initEnclave = function () {
390
+ if (!kc.doken)
391
+ throw '[TIDECLOAK] No doken found';
392
+ if (!kc.tokenParsed)
393
+ throw '[TIDECLOAK] Token not parsed';
394
+ // Now lets actually encrypt
395
+ if (!kc.requestEnclave) {
396
+ kc.requestEnclave = new RequestEnclave({
397
+ homeOrkOrigin: kc.dokenParsed["t.uho"],
398
+ signed_client_origin: config['clientOriginAuth'],
399
+ vendorId: config.vendorId,
400
+ voucherURL: getVoucherUrl()
401
+ }).init({
402
+ doken: kc.doken,
403
+ dokenRefreshCallback: async () => {
404
+ await kc.ensureTokenReady();
405
+ if (!kc.doken)
406
+ throw '[TIDECLOAK] No doken found';
407
+ return kc.doken;
408
+ },
409
+ requireReloginCallback: async () => {
410
+ kc.login({
411
+ idpHint: 'tide', // the “alias” of the IdP you’ve configured in the realm
412
+ prompt: 'login', // forces them to actually re-enter credentials
413
+ redirectUri: window.location.href // send them back to the exact same URL
414
+ });
415
+ }
416
+ });
417
+ }
418
+ };
419
+ // MODIFIED: Added Tide-based micro-vouchers.
420
+ function getVoucherUrl() {
421
+ if (!kc.tokenParsed)
422
+ throw 'User authentication required to access voucher service';
423
+ const sid = kc.tokenParsed["sid"];
424
+ return getRealmUrl() + '/tidevouchers/fromUserSession?sessionId=' + sid;
425
+ }
426
+ // MODIFIED: Added role-based decryption functionality.
427
+ kc.decrypt = async function (toDecrypt) {
428
+ await kc.ensureTokenReady();
429
+ // Check config
667
430
  if (!Array.isArray(toDecrypt)) {
668
- throw new Error('Pass array as parameter');
431
+ throw 'Pass array as parameter';
669
432
  }
670
- if (!this.tokenParsed) {
671
- throw new Error('Not authenticated');
433
+ // Check user authenticated
434
+ if (!kc.tokenParsed) {
435
+ throw 'Not authenticated';
672
436
  }
673
- const dataToSend = toDecrypt.map((e) => {
437
+ const dataToSend = toDecrypt.map(e => {
674
438
  if (!isObject(e))
675
- throw new Error('All entries must be an object to decrypt');
676
- for (const property of ['encrypted', 'tags']) {
439
+ throw 'All entries must be an object to decrypt';
440
+ for (const property of ["encrypted", "tags"]) {
677
441
  if (!e[property]) {
678
442
  throw new Error(`The configuration object is missing the required '${property}' property.`);
679
443
  }
680
444
  }
681
445
  if (!Array.isArray(e.tags))
682
- throw new Error('tags must be provided as a string array in object to decrypt');
683
- if (typeof e.encrypted !== 'string' && !(e.encrypted instanceof Uint8Array)) {
684
- throw new Error('encrypted must be provided as string or Uint8Array in object to decrypt');
685
- }
446
+ throw 'tags must be provided as a string array in object to decrypt';
447
+ if (typeof e.encrypted !== "string" && !(e.encrypted instanceof Uint8Array))
448
+ throw 'data must be provded as string or Uint8Array in object to decrypt';
449
+ // Check that the user has the roles required to encrypt the datas
686
450
  for (const tag of e.tags) {
687
- if (typeof tag !== 'string')
688
- throw new Error('tags must be provided as an array of strings');
689
- const tagAccess = this.hasRealmRole(`_tide_${tag}.selfdecrypt`);
451
+ if (typeof tag !== "string")
452
+ throw "tags must be provided as an array of strings";
453
+ var tagAccess = kc.hasRealmRole("_tide_" + tag + ".selfdecrypt");
690
454
  if (!tagAccess)
691
- throw new Error(`User has not been given any access to '${tag}'`);
455
+ throw `'User has not been given any access to '${tag}'`;
692
456
  }
693
457
  return {
694
- encrypted: typeof e.encrypted === 'string' ? base64ToBytes(e.encrypted) : e.encrypted,
458
+ encrypted: typeof e.encrypted === "string" ? base64ToBytes(e.encrypted) : e.encrypted,
695
459
  tags: e.tags,
696
- isRaw: typeof e.encrypted === 'string' ? false : true
460
+ isRaw: typeof e.encrypted === "string" ? false : true
697
461
  };
698
462
  });
699
- this.initRequestEnclave();
700
- const decrypted = await this.requestEnclave.decrypt(dataToSend);
701
- return decrypted.map((d, i) => (dataToSend[i].isRaw ? d : StringFromUint8Array(d)));
702
- }
703
- }
704
- _TideCloak_refreshQueue = new WeakMap(), _TideCloak_adapter = new WeakMap(), _TideCloak_useNonce = new WeakMap(), _TideCloak_callbackStorage = new WeakMap(), _TideCloak_logInfo = new WeakMap(), _TideCloak_logWarn = new WeakMap(), _TideCloak_loginIframe = new WeakMap(), _TideCloak_config = new WeakMap(), _TideCloak_instances = new WeakSet(), _TideCloak_loadAdapter = function _TideCloak_loadAdapter(type) {
705
- if (type === 'default') {
706
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadDefaultAdapter).call(this);
707
- }
708
- if (type === 'cordova') {
709
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable = false;
710
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadCordovaAdapter).call(this);
711
- }
712
- if (type === 'cordova-native') {
713
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable = false;
714
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadCordovaNativeAdapter).call(this);
715
- }
716
- throw new Error('invalid adapter type: ' + type);
717
- }, _TideCloak_loadDefaultAdapter = function _TideCloak_loadDefaultAdapter() {
718
- /** @type {KeycloakAdapter['redirectUri']}{} */
719
- const redirectUri = (options) => {
720
- return (options === null || options === void 0 ? void 0 : options.redirectUri) || this.redirectUri || globalThis.location.href;
463
+ kc.initEnclave();
464
+ // Now lets actually decrypt
465
+ // Construct Tide serialized data payloads
466
+ return (await kc.requestEnclave.decrypt(dataToSend)).map((d, i) => dataToSend[i].isRaw ? d : StringFromUint8Array(d));
721
467
  };
722
- return {
723
- login: async (options) => {
724
- window.location.assign(await this.createLoginUrl(options));
725
- return await new Promise(() => { });
726
- },
727
- logout: async (options) => {
728
- var _a;
729
- const logoutMethod = (_a = options === null || options === void 0 ? void 0 : options.logoutMethod) !== null && _a !== void 0 ? _a : this.logoutMethod;
730
- if (logoutMethod === 'GET') {
731
- window.location.replace(this.createLogoutUrl(options));
732
- return;
733
- }
734
- // Create form to send POST request.
735
- const form = document.createElement('form');
736
- form.setAttribute('method', 'POST');
737
- form.setAttribute('action', this.createLogoutUrl(options));
738
- form.style.display = 'none';
739
- // Add data to form as hidden input fields.
740
- const data = {
741
- id_token_hint: this.idToken,
742
- client_id: this.clientId,
743
- post_logout_redirect_uri: redirectUri(options)
744
- };
745
- for (const [name, value] of Object.entries(data)) {
746
- const input = document.createElement('input');
747
- input.setAttribute('type', 'hidden');
748
- input.setAttribute('name', name);
749
- input.setAttribute('value', /** @type {string} */ (value));
750
- form.appendChild(input);
751
- }
752
- // Append form to page and submit it to perform logout and redirect.
753
- document.body.appendChild(form);
754
- form.submit();
755
- },
756
- register: async (options) => {
757
- window.location.assign(await this.createRegisterUrl(options));
758
- return await new Promise(() => { });
759
- },
760
- accountManagement: async () => {
761
- const accountUrl = this.createAccountUrl();
762
- if (typeof accountUrl !== 'undefined') {
763
- window.location.href = accountUrl;
764
- }
765
- else {
766
- throw new Error('Not supported by the OIDC server');
468
+ function generateRandomData(len) {
469
+ if (typeof crypto === "undefined" || typeof crypto.getRandomValues === "undefined") {
470
+ throw new Error("Web Crypto API is not available.");
471
+ }
472
+ return crypto.getRandomValues(new Uint8Array(len));
473
+ }
474
+ function generateCodeVerifier(len) {
475
+ return generateRandomString(len, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
476
+ }
477
+ function generateRandomString(len, alphabet) {
478
+ var randomData = generateRandomData(len);
479
+ var chars = new Array(len);
480
+ for (var i = 0; i < len; i++) {
481
+ chars[i] = alphabet.charCodeAt(randomData[i] % alphabet.length);
482
+ }
483
+ return String.fromCharCode.apply(null, chars);
484
+ }
485
+ async function generatePkceChallenge(pkceMethod, codeVerifier) {
486
+ if (pkceMethod !== "S256") {
487
+ throw new TypeError(`Invalid value for 'pkceMethod', expected 'S256' but got '${pkceMethod}'.`);
488
+ }
489
+ // hash codeVerifier, then encode as url-safe base64 without padding
490
+ const hashBytes = new Uint8Array(await sha256Digest(codeVerifier));
491
+ const encodedHash = bytesToBase64(hashBytes)
492
+ .replace(/\+/g, '-')
493
+ .replace(/\//g, '_')
494
+ .replace(/\=/g, '');
495
+ return encodedHash;
496
+ }
497
+ function buildClaimsParameter(requestedAcr) {
498
+ var claims = {
499
+ id_token: {
500
+ acr: requestedAcr
767
501
  }
768
- return await new Promise(() => { });
769
- },
770
- redirectUri
771
- };
772
- }, _TideCloak_loadCordovaAdapter = function _TideCloak_loadCordovaAdapter() {
773
- /**
774
- * @param {string} loginUrl
775
- * @param {string} target
776
- * @param {string} options
777
- * @returns {WindowProxy | null}
778
- */
779
- const cordovaOpenWindowWrapper = (loginUrl, target, options) => {
780
- if (window.cordova && window.cordova.InAppBrowser) {
781
- // Use inappbrowser for IOS and Android if available
782
- return window.cordova.InAppBrowser.open(loginUrl, target, options);
502
+ };
503
+ return JSON.stringify(claims);
504
+ }
505
+ kc.createLoginUrl = async function (options) {
506
+ var state = createUUID();
507
+ var nonce = createUUID();
508
+ var redirectUri = adapter.redirectUri(options);
509
+ var callbackState = {
510
+ state: state,
511
+ nonce: nonce,
512
+ redirectUri: encodeURIComponent(redirectUri),
513
+ loginOptions: options
514
+ };
515
+ if (options && options.prompt) {
516
+ callbackState.prompt = options.prompt;
517
+ }
518
+ var baseUrl;
519
+ if (options && options.action == 'register') {
520
+ baseUrl = kc.endpoints.register();
783
521
  }
784
522
  else {
785
- return window.open(loginUrl, target, options);
523
+ baseUrl = kc.endpoints.authorize();
524
+ }
525
+ var scope = options && options.scope || kc.scope;
526
+ if (!scope) {
527
+ // if scope is not set, default to "openid"
528
+ scope = "openid";
529
+ }
530
+ else if (scope.indexOf("openid") === -1) {
531
+ // if openid scope is missing, prefix the given scopes with it
532
+ scope = "openid " + scope;
533
+ }
534
+ var url = baseUrl
535
+ + '?client_id=' + encodeURIComponent(kc.clientId)
536
+ + '&redirect_uri=' + encodeURIComponent(redirectUri)
537
+ + '&state=' + encodeURIComponent(state)
538
+ + '&response_mode=' + encodeURIComponent(kc.responseMode)
539
+ + '&response_type=' + encodeURIComponent(kc.responseType)
540
+ + '&scope=' + encodeURIComponent(scope);
541
+ if (useNonce) {
542
+ url = url + '&nonce=' + encodeURIComponent(nonce);
786
543
  }
544
+ if (options && options.prompt) {
545
+ url += '&prompt=' + encodeURIComponent(options.prompt);
546
+ }
547
+ if (options && typeof options.maxAge === 'number') {
548
+ url += '&max_age=' + encodeURIComponent(options.maxAge);
549
+ }
550
+ if (options && options.loginHint) {
551
+ url += '&login_hint=' + encodeURIComponent(options.loginHint);
552
+ }
553
+ if (options && options.idpHint) {
554
+ url += '&kc_idp_hint=' + encodeURIComponent(options.idpHint);
555
+ }
556
+ if (options && options.action && options.action != 'register') {
557
+ url += '&kc_action=' + encodeURIComponent(options.action);
558
+ }
559
+ if (options && options.locale) {
560
+ url += '&ui_locales=' + encodeURIComponent(options.locale);
561
+ }
562
+ if (options && options.acr) {
563
+ var claimsParameter = buildClaimsParameter(options.acr);
564
+ url += '&claims=' + encodeURIComponent(claimsParameter);
565
+ }
566
+ if ((options && options.acrValues) || kc.acrValues) {
567
+ url += '&acr_values=' + encodeURIComponent(options.acrValues || kc.acrValues);
568
+ }
569
+ if (kc.pkceMethod) {
570
+ try {
571
+ const codeVerifier = generateCodeVerifier(96);
572
+ const pkceChallenge = await generatePkceChallenge(kc.pkceMethod, codeVerifier);
573
+ callbackState.pkceCodeVerifier = codeVerifier;
574
+ url += '&code_challenge=' + pkceChallenge;
575
+ url += '&code_challenge_method=' + kc.pkceMethod;
576
+ }
577
+ catch (error) {
578
+ throw new Error("Failed to generate PKCE challenge.", { cause: error });
579
+ }
580
+ }
581
+ callbackStorage.add(callbackState);
582
+ return url;
583
+ };
584
+ kc.logout = function (options) {
585
+ return adapter.logout(options);
787
586
  };
788
- const shallowCloneCordovaOptions = (userOptions) => {
789
- if (userOptions && userOptions.cordovaOptions) {
790
- return Object.keys(userOptions.cordovaOptions).reduce((options, optionName) => {
791
- options[optionName] = userOptions.cordovaOptions[optionName];
792
- return options;
793
- }, {});
587
+ kc.createLogoutUrl = function (options) {
588
+ var _a;
589
+ const logoutMethod = (_a = options === null || options === void 0 ? void 0 : options.logoutMethod) !== null && _a !== void 0 ? _a : kc.logoutMethod;
590
+ if (logoutMethod === 'POST') {
591
+ return kc.endpoints.logout();
794
592
  }
795
- else {
796
- return {};
593
+ var url = kc.endpoints.logout()
594
+ + '?client_id=' + encodeURIComponent(kc.clientId)
595
+ + '&post_logout_redirect_uri=' + encodeURIComponent(adapter.redirectUri(options, false));
596
+ if (kc.idToken) {
597
+ url += '&id_token_hint=' + encodeURIComponent(kc.idToken);
797
598
  }
599
+ return url;
798
600
  };
799
- const formatCordovaOptions = (cordovaOptions) => {
800
- return Object.keys(cordovaOptions).reduce((options, optionName) => {
801
- options.push(optionName + '=' + cordovaOptions[optionName]);
802
- return options;
803
- }, []).join(',');
601
+ kc.register = function (options) {
602
+ return adapter.register(options);
804
603
  };
805
- const createCordovaOptions = (userOptions) => {
806
- const cordovaOptions = shallowCloneCordovaOptions(userOptions);
807
- cordovaOptions.location = 'no';
808
- if (userOptions && userOptions.prompt === 'none') {
809
- cordovaOptions.hidden = 'yes';
604
+ kc.createRegisterUrl = async function (options) {
605
+ if (!options) {
606
+ options = {};
810
607
  }
811
- return formatCordovaOptions(cordovaOptions);
608
+ options.action = 'register';
609
+ return await kc.createLoginUrl(options);
812
610
  };
813
- const getCordovaRedirectUri = () => {
814
- return this.redirectUri || 'http://localhost';
611
+ kc.createAccountUrl = function (options) {
612
+ var realm = getRealmUrl();
613
+ var url = undefined;
614
+ if (typeof realm !== 'undefined') {
615
+ url = realm
616
+ + '/account'
617
+ + '?referrer=' + encodeURIComponent(kc.clientId)
618
+ + '&referrer_uri=' + encodeURIComponent(adapter.redirectUri(options));
619
+ }
620
+ return url;
815
621
  };
816
- return {
817
- login: async (options) => {
818
- const cordovaOptions = createCordovaOptions(options);
819
- const loginUrl = await this.createLoginUrl(options);
820
- const ref = cordovaOpenWindowWrapper(loginUrl, '_blank', cordovaOptions);
821
- let completed = false;
822
- let closed = false;
823
- function closeBrowser() {
824
- closed = true;
825
- ref.close();
826
- }
827
- ;
828
- return await new Promise((resolve, reject) => {
829
- ref.addEventListener('loadstart', async (event) => {
830
- if (event.url.indexOf(getCordovaRedirectUri()) === 0) {
831
- const callback = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallback).call(this, event.url);
832
- try {
833
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processCallback).call(this, callback);
834
- resolve();
835
- }
836
- catch (error) {
837
- reject(error);
838
- }
839
- closeBrowser();
840
- completed = true;
841
- }
842
- });
843
- ref.addEventListener('loaderror', async (event) => {
844
- if (!completed) {
845
- if (event.url.indexOf(getCordovaRedirectUri()) === 0) {
846
- const callback = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallback).call(this, event.url);
847
- try {
848
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processCallback).call(this, callback);
849
- resolve();
850
- }
851
- catch (error) {
852
- reject(error);
853
- }
854
- closeBrowser();
855
- completed = true;
856
- }
857
- else {
858
- reject(new Error('Unable to process login.'));
859
- closeBrowser();
860
- }
861
- }
862
- });
863
- ref.addEventListener('exit', function (event) {
864
- if (!closed) {
865
- reject(new Error('User closed the login window.'));
866
- }
867
- });
868
- });
869
- },
870
- logout: async (options) => {
871
- const logoutUrl = this.createLogoutUrl(options);
872
- const ref = cordovaOpenWindowWrapper(logoutUrl, '_blank', 'location=no,hidden=yes,clearcache=yes');
873
- let error = false;
874
- ref.addEventListener('loadstart', (event) => {
875
- if (event.url.indexOf(getCordovaRedirectUri()) === 0) {
876
- ref.close();
622
+ kc.accountManagement = function () {
623
+ return adapter.accountManagement();
624
+ };
625
+ kc.hasRealmRole = function (role) {
626
+ var access = kc.realmAccess;
627
+ return !!access && access.roles.indexOf(role) >= 0;
628
+ };
629
+ kc.hasResourceRole = function (role, resource) {
630
+ if (!kc.resourceAccess) {
631
+ return false;
632
+ }
633
+ var access = kc.resourceAccess[resource || kc.clientId];
634
+ return !!access && access.roles.indexOf(role) >= 0;
635
+ };
636
+ kc.loadUserProfile = function () {
637
+ var url = getRealmUrl() + '/account';
638
+ var req = new XMLHttpRequest();
639
+ req.open('GET', url, true);
640
+ req.setRequestHeader('Accept', 'application/json');
641
+ req.setRequestHeader('Authorization', 'bearer ' + kc.token);
642
+ var promise = createPromise();
643
+ req.onreadystatechange = function () {
644
+ if (req.readyState == 4) {
645
+ if (req.status == 200) {
646
+ kc.profile = JSON.parse(req.responseText);
647
+ promise.setSuccess(kc.profile);
877
648
  }
878
- });
879
- ref.addEventListener('loaderror', (event) => {
880
- if (event.url.indexOf(getCordovaRedirectUri()) === 0) {
881
- ref.close();
649
+ else {
650
+ promise.setError();
651
+ }
652
+ }
653
+ };
654
+ req.send();
655
+ return promise.promise;
656
+ };
657
+ kc.loadUserInfo = function () {
658
+ var url = kc.endpoints.userinfo();
659
+ var req = new XMLHttpRequest();
660
+ req.open('GET', url, true);
661
+ req.setRequestHeader('Accept', 'application/json');
662
+ req.setRequestHeader('Authorization', 'bearer ' + kc.token);
663
+ var promise = createPromise();
664
+ req.onreadystatechange = function () {
665
+ if (req.readyState == 4) {
666
+ if (req.status == 200) {
667
+ kc.userInfo = JSON.parse(req.responseText);
668
+ promise.setSuccess(kc.userInfo);
882
669
  }
883
670
  else {
884
- error = true;
885
- ref.close();
671
+ promise.setError();
886
672
  }
887
- });
888
- await new Promise((resolve, reject) => {
889
- ref.addEventListener('exit', () => {
890
- if (error) {
891
- reject(new Error('User closed the login window.'));
892
- }
893
- else {
894
- this.clearToken();
895
- resolve();
896
- }
897
- });
898
- });
899
- },
900
- register: async (options) => {
901
- const registerUrl = await this.createRegisterUrl();
902
- const cordovaOptions = createCordovaOptions(options);
903
- const ref = cordovaOpenWindowWrapper(registerUrl, '_blank', cordovaOptions);
904
- /** @type {Promise<void>} */
905
- const promise = new Promise((resolve, reject) => {
906
- ref.addEventListener('loadstart', async (event) => {
907
- if (event.url.indexOf(getCordovaRedirectUri()) === 0) {
908
- ref.close();
909
- const oauth = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallback).call(this, event.url);
910
- try {
911
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processCallback).call(this, oauth);
912
- resolve();
913
- }
914
- catch (error) {
915
- reject(error);
916
- }
917
- }
918
- });
919
- });
920
- await promise;
921
- },
922
- accountManagement: async () => {
923
- const accountUrl = this.createAccountUrl();
924
- if (typeof accountUrl !== 'undefined') {
925
- const ref = cordovaOpenWindowWrapper(accountUrl, '_blank', 'location=no');
926
- ref.addEventListener('loadstart', function (event) {
927
- if (event.url.indexOf(getCordovaRedirectUri()) === 0) {
928
- ref.close();
929
- }
930
- });
931
673
  }
932
- else {
933
- throw new Error('Not supported by the OIDC server');
674
+ };
675
+ req.send();
676
+ return promise.promise;
677
+ };
678
+ kc.isTokenExpired = function (minValidity) {
679
+ if (!kc.tokenParsed || (!kc.refreshToken && kc.flow != 'implicit')) {
680
+ throw 'Not authenticated';
681
+ }
682
+ if (kc.timeSkew == null) {
683
+ logInfo('[TIDECLOAK] Unable to determine if token is expired as timeskew is not set');
684
+ return true;
685
+ }
686
+ var expiresIn = kc.tokenParsed['exp'] - Math.ceil(new Date().getTime() / 1000) + kc.timeSkew;
687
+ if (minValidity) {
688
+ if (isNaN(minValidity)) {
689
+ throw 'Invalid minValidity';
934
690
  }
935
- },
936
- redirectUri: () => {
937
- return getCordovaRedirectUri();
691
+ expiresIn -= minValidity;
938
692
  }
693
+ return expiresIn < 0;
939
694
  };
940
- }, _TideCloak_loadCordovaNativeAdapter = function _TideCloak_loadCordovaNativeAdapter() {
941
- /* global universalLinks */
942
- return {
943
- login: async (options) => {
944
- const loginUrl = await this.createLoginUrl(options);
945
- await new Promise((resolve, reject) => {
946
- universalLinks.subscribe('keycloak', async (event) => {
947
- universalLinks.unsubscribe('keycloak');
948
- window.cordova.plugins.browsertab.close();
949
- const oauth = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallback).call(this, event.url);
950
- try {
951
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processCallback).call(this, oauth);
952
- resolve();
953
- }
954
- catch (error) {
955
- reject(error);
956
- }
957
- });
958
- window.cordova.plugins.browsertab.openUrl(loginUrl);
959
- });
960
- },
961
- logout: async (options) => {
962
- const logoutUrl = this.createLogoutUrl(options);
963
- await new Promise((resolve) => {
964
- universalLinks.subscribe('keycloak', () => {
965
- universalLinks.unsubscribe('keycloak');
966
- window.cordova.plugins.browsertab.close();
967
- this.clearToken();
968
- resolve();
969
- });
970
- window.cordova.plugins.browsertab.openUrl(logoutUrl);
971
- });
972
- },
973
- register: async (options) => {
974
- const registerUrl = await this.createRegisterUrl(options);
975
- await new Promise((resolve, reject) => {
976
- universalLinks.subscribe('keycloak', async (event) => {
977
- universalLinks.unsubscribe('keycloak');
978
- window.cordova.plugins.browsertab.close();
979
- const oauth = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallback).call(this, event.url);
980
- try {
981
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processCallback).call(this, oauth);
982
- resolve();
983
- }
984
- catch (error) {
985
- reject(error);
986
- }
987
- });
988
- window.cordova.plugins.browsertab.openUrl(registerUrl);
989
- });
990
- },
991
- accountManagement: async () => {
992
- const accountUrl = this.createAccountUrl();
993
- if (typeof accountUrl !== 'undefined') {
994
- window.cordova.plugins.browsertab.openUrl(accountUrl);
995
- }
996
- else {
997
- throw new Error('Not supported by the OIDC server');
695
+ kc.updateToken = function (minValidity) {
696
+ var promise = createPromise();
697
+ if (!kc.refreshToken) {
698
+ promise.setError();
699
+ return promise.promise;
700
+ }
701
+ minValidity = minValidity || 5;
702
+ var exec = function () {
703
+ var refreshToken = false;
704
+ if (minValidity == -1) {
705
+ refreshToken = true;
706
+ logInfo('[TIDECLOAK] Refreshing token: forced refresh');
998
707
  }
999
- },
1000
- redirectUri: (options) => {
1001
- if (options && options.redirectUri) {
1002
- return options.redirectUri;
708
+ else if (!kc.tokenParsed || kc.isTokenExpired(minValidity)) {
709
+ refreshToken = true;
710
+ logInfo('[TIDECLOAK] Refreshing token: token expired');
1003
711
  }
1004
- else if (this.redirectUri) {
1005
- return this.redirectUri;
712
+ if (!refreshToken) {
713
+ promise.setSuccess(false);
1006
714
  }
1007
715
  else {
1008
- return 'http://localhost';
716
+ var params = 'grant_type=refresh_token&' + 'refresh_token=' + kc.refreshToken;
717
+ var url = kc.endpoints.token();
718
+ refreshQueue.push(promise);
719
+ if (refreshQueue.length == 1) {
720
+ var req = new XMLHttpRequest();
721
+ req.open('POST', url, true);
722
+ req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
723
+ req.withCredentials = true;
724
+ params += '&client_id=' + encodeURIComponent(kc.clientId);
725
+ var timeLocal = new Date().getTime();
726
+ req.onreadystatechange = function () {
727
+ if (req.readyState == 4) {
728
+ if (req.status == 200) {
729
+ logInfo('[TIDECLOAK] Token refreshed');
730
+ timeLocal = (timeLocal + new Date().getTime()) / 2;
731
+ var tokenResponse = JSON.parse(req.responseText);
732
+ setToken(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token'], timeLocal, tokenResponse['doken']);
733
+ kc.onAuthRefreshSuccess && kc.onAuthRefreshSuccess();
734
+ for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
735
+ p.setSuccess(true);
736
+ }
737
+ }
738
+ else {
739
+ logWarn('[TIDECLOAK] Failed to refresh token');
740
+ if (req.status == 400) {
741
+ kc.clearToken();
742
+ }
743
+ if (req.status == 500) {
744
+ // Check to see if error message tells us to reauthenticate the user
745
+ console.log("CHECKING REAUTH");
746
+ }
747
+ kc.onAuthRefreshError && kc.onAuthRefreshError();
748
+ for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
749
+ p.setError("Failed to refresh token: An unexpected HTTP error occurred while attempting to refresh the token.");
750
+ }
751
+ }
752
+ }
753
+ };
754
+ req.send(params);
755
+ }
1009
756
  }
757
+ };
758
+ if (loginIframe.enable) {
759
+ var iframePromise = checkLoginIframe();
760
+ iframePromise.then(function () {
761
+ exec();
762
+ }).catch(function (error) {
763
+ promise.setError(error);
764
+ });
765
+ }
766
+ else {
767
+ exec();
1010
768
  }
769
+ return promise.promise;
1011
770
  };
1012
- }, _TideCloak_loadConfig =
1013
- /**
1014
- * @returns {Promise<void>}
1015
- */
1016
- async function _TideCloak_loadConfig() {
1017
- if (typeof __classPrivateFieldGet(this, _TideCloak_config, "f") === 'string') {
1018
- const jsonConfig = await fetchJsonConfig(__classPrivateFieldGet(this, _TideCloak_config, "f"));
1019
- this.authServerUrl = jsonConfig['auth-server-url'];
1020
- this.realm = jsonConfig.realm;
1021
- this.clientId = jsonConfig.resource;
1022
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setupEndpoints).call(this);
1023
- }
1024
- else {
1025
- this.clientId = __classPrivateFieldGet(this, _TideCloak_config, "f").clientId;
1026
- if ('oidcProvider' in __classPrivateFieldGet(this, _TideCloak_config, "f")) {
1027
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_loadOidcConfig).call(this, __classPrivateFieldGet(this, _TideCloak_config, "f").oidcProvider);
771
+ kc.clearToken = function () {
772
+ if (kc.token) {
773
+ setToken(null, null, null);
774
+ kc.onAuthLogout && kc.onAuthLogout();
775
+ if (kc.loginRequired) {
776
+ kc.login();
777
+ }
778
+ }
779
+ };
780
+ // Add the checkThresholdRule function to the Heimdall instance.
781
+ // This function calls the generic threshold rule processor from the thresholdRules module.
782
+ kc.checkThresholdRule = function (key, idSubstring, ruleSettings, draftJson) {
783
+ // Process the threshold rules using the provided parameters and return the result.
784
+ return processThresholdRules(key, idSubstring, ruleSettings, draftJson);
785
+ };
786
+ kc.createCardanoTxDraft = function (txBody) {
787
+ const txBodyBytes = base64ToBytes(txBody);
788
+ return bytesToBase64(CreateTideMemory(txBodyBytes, txBodyBytes.length + 4));
789
+ };
790
+ kc.sign = async function (signModel, authFlow, draft, authorizers, ruleSetting, expiry) {
791
+ await kc.ensureTokenReady();
792
+ const signModelId = signModel.split(":");
793
+ if (signModelId.length !== 2 || !signModelId[0] || !signModelId[1]) {
794
+ throw "SignModel is not in the correct format. Expected format: 'ModelName:Version' (e.g. 'UserContext:1').";
795
+ }
796
+ const authFlowId = authFlow.split(":");
797
+ if (authFlowId.length !== 2 || !authFlowId[0] || !authFlowId[1]) {
798
+ throw "AuthFlow is not in the correct format. Expected format: 'ModelName:Version' (e.g. 'VRK:1').";
799
+ }
800
+ const sessKey = GenSessKey();
801
+ const gSessKey = GetPublic(sessKey);
802
+ const vvkInfo = await new NetworkClient(config.homeOrkUrl).GetKeyInfo(config.vendorId);
803
+ ;
804
+ // Check user authenticated
805
+ if (!kc.tokenParsed) {
806
+ throw 'Not authenticated';
807
+ }
808
+ // Check config
809
+ if (!Array.isArray(authorizers)) {
810
+ throw 'Pass authorizers in an array!';
811
+ }
812
+ const signRequest = new BaseTideRequest(signModelId[0], signModel[1], authFlow, draft);
813
+ if (expiry)
814
+ signRequest.setCustomExpiry(expiry);
815
+ new AuthorizationBuilder(signRequest, authorizers, ruleSetting).addAuthorization();
816
+ const signingFlow = new dVVKSigningFlow_DEPRECATED(config.vendorId, vvkInfo.UserPublic, vvkInfo.OrkInfo, sessKey, gSessKey, getVoucherUrl());
817
+ const result = (await signingFlow.start(signRequest));
818
+ return result;
819
+ };
820
+ kc.signCardanoTx = async function (txBody, authorizers, ruleSettings, expiry) {
821
+ await kc.ensureTokenReady();
822
+ const sessKey = GenSessKey();
823
+ const gSessKey = GetPublic(sessKey);
824
+ const vvkInfo = await new NetworkClient(config.homeOrkUrl).GetKeyInfo(config.vendorId);
825
+ ;
826
+ // Check user authenticated
827
+ if (!kc.tokenParsed) {
828
+ throw 'Not authenticated';
829
+ }
830
+ // Check config
831
+ if (!Array.isArray(authorizers)) {
832
+ throw 'Pass authorizers in an array!';
833
+ }
834
+ const cardanoSignRequest = new CardanoTxBodySignRequest("BlindSig:1");
835
+ cardanoSignRequest.setTxBody(txBody);
836
+ cardanoSignRequest.serializeDraft();
837
+ new AuthorizationBuilder(cardanoSignRequest, authorizers, ruleSettings).addAuthorization();
838
+ cardanoSignRequest.setCustomExpiry(expiry);
839
+ const txSigningFlow = new dVVKSigningFlow_DEPRECATED(config.vendorId, vvkInfo.UserPublic, vvkInfo.OrkInfo, sessKey, gSessKey, getVoucherUrl());
840
+ const result = (await txSigningFlow.start(cardanoSignRequest));
841
+ return bytesToBase64(result[0]);
842
+ };
843
+ kc.createRuleSettingsDraft = function (ruleSettings, previousRuleSetting, previousRuleSettingCert) {
844
+ const ruleReqDraft = new RuleSettingsSignRequest("Admin:1");
845
+ ruleReqDraft.setNewRuleSetting(StringToUint8Array(ruleSettings));
846
+ if (previousRuleSetting !== undefined && previousRuleSettingCert !== undefined) {
847
+ ruleReqDraft.setPreviousRuleSetting(StringToUint8Array(previousRuleSetting));
848
+ ruleReqDraft.setPreviousRuleSettingCert(base64ToBytes(previousRuleSettingCert));
849
+ }
850
+ return bytesToBase64(ruleReqDraft.getDraft());
851
+ };
852
+ function getRealmUrl() {
853
+ if (typeof kc.authServerUrl !== 'undefined') {
854
+ if (kc.authServerUrl.charAt(kc.authServerUrl.length - 1) == '/') {
855
+ return kc.authServerUrl + 'realms/' + encodeURIComponent(kc.realm);
856
+ }
857
+ else {
858
+ return kc.authServerUrl + '/realms/' + encodeURIComponent(kc.realm);
859
+ }
1028
860
  }
1029
861
  else {
1030
- this.authServerUrl = __classPrivateFieldGet(this, _TideCloak_config, "f").url;
1031
- this.realm = __classPrivateFieldGet(this, _TideCloak_config, "f").realm;
1032
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setupEndpoints).call(this);
862
+ return undefined;
1033
863
  }
1034
864
  }
1035
- }, _TideCloak_setupEndpoints = function _TideCloak_setupEndpoints() {
1036
- this.endpoints = {
1037
- authorize: () => {
1038
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this) + '/protocol/openid-connect/auth';
1039
- },
1040
- token: () => {
1041
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this) + '/protocol/openid-connect/token';
1042
- },
1043
- logout: () => {
1044
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this) + '/protocol/openid-connect/logout';
1045
- },
1046
- checkSessionIframe: () => {
1047
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this) + '/protocol/openid-connect/login-status-iframe.html';
1048
- },
1049
- thirdPartyCookiesIframe: () => {
1050
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this) + '/protocol/openid-connect/3p-cookies/step1.html';
1051
- },
1052
- register: () => {
1053
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this) + '/protocol/openid-connect/registrations';
1054
- },
1055
- userinfo: () => {
1056
- return __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this) + '/protocol/openid-connect/userinfo';
865
+ function getOrigin() {
866
+ if (!window.location.origin) {
867
+ return window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
1057
868
  }
1058
- };
1059
- }, _TideCloak_loadOidcConfig =
1060
- /**
1061
- * @param {string | OpenIdProviderMetadata} oidcProvider
1062
- * @returns {Promise<void>}
1063
- */
1064
- async function _TideCloak_loadOidcConfig(oidcProvider) {
1065
- if (typeof oidcProvider === 'string') {
1066
- const url = `${stripTrailingSlash(oidcProvider)}/.well-known/openid-configuration`;
1067
- const openIdConfig = await fetchOpenIdConfig(url);
1068
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setupOidcEndpoints).call(this, openIdConfig);
1069
- }
1070
- else {
1071
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setupOidcEndpoints).call(this, oidcProvider);
1072
- }
1073
- }, _TideCloak_setupOidcEndpoints = function _TideCloak_setupOidcEndpoints(config) {
1074
- this.endpoints = {
1075
- authorize() {
1076
- return config.authorization_endpoint;
1077
- },
1078
- token() {
1079
- return config.token_endpoint;
1080
- },
1081
- logout() {
1082
- if (!config.end_session_endpoint) {
1083
- throw new Error('Not supported by the OIDC server');
1084
- }
1085
- return config.end_session_endpoint;
1086
- },
1087
- checkSessionIframe() {
1088
- if (!config.check_session_iframe) {
1089
- throw new Error('Not supported by the OIDC server');
1090
- }
1091
- return config.check_session_iframe;
1092
- },
1093
- register() {
1094
- throw new Error('Redirection to "Register user" page not supported in standard OIDC mode');
1095
- },
1096
- userinfo() {
1097
- if (!config.userinfo_endpoint) {
1098
- throw new Error('Not supported by the OIDC server');
1099
- }
1100
- return config.userinfo_endpoint;
869
+ else {
870
+ return window.location.origin;
1101
871
  }
1102
- };
1103
- }, _TideCloak_check3pCookiesSupported =
1104
- /**
1105
- * @returns {Promise<void>}
1106
- */
1107
- async function _TideCloak_check3pCookiesSupported() {
1108
- if ((!__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable && !this.silentCheckSsoRedirectUri) || typeof this.endpoints.thirdPartyCookiesIframe !== 'function') {
1109
- return;
1110
872
  }
1111
- const iframe = document.createElement('iframe');
1112
- iframe.setAttribute('src', this.endpoints.thirdPartyCookiesIframe());
1113
- iframe.setAttribute('sandbox', 'allow-storage-access-by-user-activation allow-scripts allow-same-origin');
1114
- iframe.setAttribute('title', 'keycloak-3p-check-iframe');
1115
- iframe.style.display = 'none';
1116
- document.body.appendChild(iframe);
1117
- /** @type {Promise<void>} */
1118
- const promise = new Promise((resolve) => {
1119
- /**
1120
- * @param {MessageEvent} event
1121
- */
1122
- const messageCallback = (event) => {
1123
- if (iframe.contentWindow !== event.source) {
1124
- return;
873
+ function processCallback(oauth, promise) {
874
+ var code = oauth.code;
875
+ var error = oauth.error;
876
+ var prompt = oauth.prompt;
877
+ var timeLocal = new Date().getTime();
878
+ if (oauth['kc_action_status']) {
879
+ kc.onActionUpdate && kc.onActionUpdate(oauth['kc_action_status'], oauth['kc_action']);
880
+ }
881
+ if (error) {
882
+ if (prompt != 'none') {
883
+ if (oauth.error_description && oauth.error_description === "authentication_expired") {
884
+ kc.login(oauth.loginOptions);
885
+ }
886
+ else {
887
+ var errorData = { error: error, error_description: oauth.error_description };
888
+ kc.onAuthError && kc.onAuthError(errorData);
889
+ promise && promise.setError(errorData);
890
+ }
1125
891
  }
1126
- if (event.data !== 'supported' && event.data !== 'unsupported') {
1127
- return;
892
+ else {
893
+ promise && promise.setSuccess();
894
+ }
895
+ return;
896
+ }
897
+ else if ((kc.flow != 'standard') && (oauth.access_token || oauth.id_token)) {
898
+ authSuccess(oauth.access_token, null, oauth.id_token, true, oauth.doken);
899
+ }
900
+ if ((kc.flow != 'implicit') && code) {
901
+ var params = 'code=' + code + '&grant_type=authorization_code';
902
+ var url = kc.endpoints.token();
903
+ var req = new XMLHttpRequest();
904
+ req.open('POST', url, true);
905
+ req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
906
+ params += '&client_id=' + encodeURIComponent(kc.clientId);
907
+ params += '&redirect_uri=' + oauth.redirectUri;
908
+ if (oauth.pkceCodeVerifier) {
909
+ params += '&code_verifier=' + oauth.pkceCodeVerifier;
910
+ }
911
+ req.withCredentials = true;
912
+ req.onreadystatechange = function () {
913
+ if (req.readyState == 4) {
914
+ if (req.status == 200) {
915
+ var tokenResponse = JSON.parse(req.responseText);
916
+ authSuccess(tokenResponse['access_token'], tokenResponse['refresh_token'], tokenResponse['id_token'], kc.flow === 'standard', tokenResponse['doken']); // added doken field
917
+ scheduleCheckIframe();
918
+ }
919
+ else {
920
+ if (req.status == 500) {
921
+ // Check to see if error message tells us to reauthenticate the user
922
+ console.log("CHECKING REAUTH");
923
+ }
924
+ kc.onAuthError && kc.onAuthError();
925
+ promise && promise.setError();
926
+ }
927
+ }
928
+ };
929
+ req.onerror = function () {
930
+ // Try to log the user in again
931
+ kc.login({
932
+ idpHint: 'tide',
933
+ prompt: 'login', // forces them to actually re-enter credentials
934
+ redirectUri: window.location.href // send them back to the exact same URL
935
+ });
936
+ };
937
+ req.send(params);
938
+ }
939
+ function authSuccess(accessToken, refreshToken, idToken, fulfillPromise, doken = null) {
940
+ timeLocal = (timeLocal + new Date().getTime()) / 2;
941
+ setToken(accessToken, refreshToken, idToken, timeLocal, doken);
942
+ if (useNonce && (kc.idTokenParsed && kc.idTokenParsed.nonce != oauth.storedNonce)) {
943
+ logInfo('[TIDECLOAK] Invalid nonce, clearing token');
944
+ kc.clearToken();
945
+ promise && promise.setError();
1128
946
  }
1129
- else if (event.data === 'unsupported') {
1130
- __classPrivateFieldGet(this, _TideCloak_logWarn, "f").call(this, '[TIDECLOAK] Your browser is blocking access to 3rd-party cookies, this means:\n\n' +
1131
- ' - It is not possible to retrieve tokens without redirecting to the TideCloak server (a.k.a. no support for silent authentication).\n' +
1132
- ' - It is not possible to automatically detect changes to the session status (such as the user logging out in another tab).\n\n' +
1133
- 'For more information see: https://www.keycloak.org/securing-apps/javascript-adapter#_modern_browsers');
1134
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable = false;
1135
- if (this.silentCheckSsoFallback) {
1136
- this.silentCheckSsoRedirectUri = undefined;
947
+ else {
948
+ if (fulfillPromise) {
949
+ kc.onAuthSuccess && kc.onAuthSuccess();
950
+ promise && promise.setSuccess();
1137
951
  }
1138
952
  }
1139
- document.body.removeChild(iframe);
1140
- window.removeEventListener('message', messageCallback);
1141
- resolve();
1142
- };
1143
- window.addEventListener('message', messageCallback, false);
1144
- });
1145
- return await applyTimeoutToPromise(promise, this.messageReceiveTimeout, 'Timeout when waiting for 3rd party check iframe message.');
1146
- }, _TideCloak_processInit =
1147
- /**
1148
- * @param {KeycloakInitOptions} initOptions
1149
- * @returns {Promise<void>}
1150
- */
1151
- async function _TideCloak_processInit(initOptions) {
1152
- var _a, _b, _c;
1153
- const callback = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallback).call(this, window.location.href);
1154
- if (callback === null || callback === void 0 ? void 0 : callback.redirectUri) {
1155
- window.history.replaceState(window.history.state, '', callback.redirectUri);
1156
- }
1157
- if (callback && callback.valid) {
1158
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setupCheckLoginIframe).call(this);
1159
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processCallback).call(this, callback);
1160
- return;
953
+ }
1161
954
  }
1162
- /** @param {boolean} prompt */
1163
- const doLogin = async (prompt) => {
1164
- /** @type {KeycloakLoginOptions} */
1165
- const options = {};
1166
- if (!prompt) {
1167
- options.prompt = 'none';
955
+ function loadConfig() {
956
+ var promise = createPromise();
957
+ var configUrl;
958
+ if (typeof config === 'string') {
959
+ configUrl = config;
960
+ }
961
+ function setupOidcEndoints(oidcConfiguration) {
962
+ if (!oidcConfiguration) {
963
+ kc.endpoints = {
964
+ authorize: function () {
965
+ return getRealmUrl() + '/protocol/openid-connect/auth';
966
+ },
967
+ token: function () {
968
+ return getRealmUrl() + '/protocol/openid-connect/token';
969
+ },
970
+ logout: function () {
971
+ return getRealmUrl() + '/protocol/openid-connect/logout';
972
+ },
973
+ checkSessionIframe: function () {
974
+ return getRealmUrl() + '/protocol/openid-connect/login-status-iframe.html';
975
+ },
976
+ thirdPartyCookiesIframe: function () {
977
+ return getRealmUrl() + '/protocol/openid-connect/3p-cookies/step1.html';
978
+ },
979
+ register: function () {
980
+ return getRealmUrl() + '/protocol/openid-connect/registrations';
981
+ },
982
+ userinfo: function () {
983
+ return getRealmUrl() + '/protocol/openid-connect/userinfo';
984
+ }
985
+ };
986
+ }
987
+ else {
988
+ kc.endpoints = {
989
+ authorize: function () {
990
+ return oidcConfiguration.authorization_endpoint;
991
+ },
992
+ token: function () {
993
+ return oidcConfiguration.token_endpoint;
994
+ },
995
+ logout: function () {
996
+ if (!oidcConfiguration.end_session_endpoint) {
997
+ throw "Not supported by the OIDC server";
998
+ }
999
+ return oidcConfiguration.end_session_endpoint;
1000
+ },
1001
+ checkSessionIframe: function () {
1002
+ if (!oidcConfiguration.check_session_iframe) {
1003
+ throw "Not supported by the OIDC server";
1004
+ }
1005
+ return oidcConfiguration.check_session_iframe;
1006
+ },
1007
+ register: function () {
1008
+ throw 'Redirection to "Register user" page not supported in standard OIDC mode';
1009
+ },
1010
+ userinfo: function () {
1011
+ if (!oidcConfiguration.userinfo_endpoint) {
1012
+ throw "Not supported by the OIDC server";
1013
+ }
1014
+ return oidcConfiguration.userinfo_endpoint;
1015
+ }
1016
+ };
1017
+ }
1168
1018
  }
1169
- if (initOptions.locale) {
1170
- options.locale = initOptions.locale;
1019
+ if (configUrl) {
1020
+ var req = new XMLHttpRequest();
1021
+ req.open('GET', configUrl, true);
1022
+ req.setRequestHeader('Accept', 'application/json');
1023
+ req.onreadystatechange = function () {
1024
+ if (req.readyState == 4) {
1025
+ if (req.status == 200 || fileLoaded(req)) {
1026
+ var config = JSON.parse(req.responseText);
1027
+ kc.authServerUrl = config['auth-server-url'];
1028
+ kc.realm = config['realm'];
1029
+ kc.clientId = config['resource'];
1030
+ setupOidcEndoints(null);
1031
+ promise.setSuccess();
1032
+ }
1033
+ else {
1034
+ promise.setError();
1035
+ }
1036
+ }
1037
+ };
1038
+ req.send();
1171
1039
  }
1172
- await this.login(options);
1173
- };
1174
- const onLoad = async () => {
1175
- switch (initOptions.onLoad) {
1176
- case 'check-sso':
1177
- if (__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable) {
1178
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setupCheckLoginIframe).call(this);
1179
- const unchanged = await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_checkLoginIframe).call(this);
1180
- if (!unchanged) {
1181
- this.silentCheckSsoRedirectUri ? await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_checkSsoSilently).call(this) : await doLogin(false);
1040
+ else {
1041
+ kc.clientId = config.clientId;
1042
+ var oidcProvider = config['oidcProvider'];
1043
+ if (!oidcProvider) {
1044
+ kc.authServerUrl = config.url;
1045
+ kc.realm = config.realm;
1046
+ setupOidcEndoints(null);
1047
+ promise.setSuccess();
1048
+ }
1049
+ else {
1050
+ if (typeof oidcProvider === 'string') {
1051
+ var oidcProviderConfigUrl;
1052
+ if (oidcProvider.charAt(oidcProvider.length - 1) == '/') {
1053
+ oidcProviderConfigUrl = oidcProvider + '.well-known/openid-configuration';
1182
1054
  }
1055
+ else {
1056
+ oidcProviderConfigUrl = oidcProvider + '/.well-known/openid-configuration';
1057
+ }
1058
+ var req = new XMLHttpRequest();
1059
+ req.open('GET', oidcProviderConfigUrl, true);
1060
+ req.setRequestHeader('Accept', 'application/json');
1061
+ req.onreadystatechange = function () {
1062
+ if (req.readyState == 4) {
1063
+ if (req.status == 200 || fileLoaded(req)) {
1064
+ var oidcProviderConfig = JSON.parse(req.responseText);
1065
+ setupOidcEndoints(oidcProviderConfig);
1066
+ promise.setSuccess();
1067
+ }
1068
+ else {
1069
+ promise.setError();
1070
+ }
1071
+ }
1072
+ };
1073
+ req.send();
1183
1074
  }
1184
1075
  else {
1185
- this.silentCheckSsoRedirectUri ? await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_checkSsoSilently).call(this) : await doLogin(false);
1076
+ setupOidcEndoints(oidcProvider);
1077
+ promise.setSuccess();
1186
1078
  }
1187
- break;
1188
- case 'login-required':
1189
- await doLogin(true);
1190
- break;
1191
- default:
1192
- throw new Error('Invalid value for onLoad');
1193
- }
1194
- };
1195
- if (initOptions.token && initOptions.refreshToken) {
1196
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setToken).call(this, initOptions.token, initOptions.refreshToken, initOptions.idToken);
1197
- if (__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable) {
1198
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setupCheckLoginIframe).call(this);
1199
- const unchanged = await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_checkLoginIframe).call(this);
1200
- if (unchanged) {
1201
- (_a = this.onAuthSuccess) === null || _a === void 0 ? void 0 : _a.call(this);
1202
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_scheduleCheckIframe).call(this);
1203
1079
  }
1204
1080
  }
1081
+ return promise.promise;
1082
+ }
1083
+ function fileLoaded(xhr) {
1084
+ return xhr.status == 0 && xhr.responseText && xhr.responseURL.startsWith('file:');
1085
+ }
1086
+ function setToken(token, refreshToken, idToken, timeLocal, doken = null) {
1087
+ if (kc.tokenTimeoutHandle) {
1088
+ clearTimeout(kc.tokenTimeoutHandle);
1089
+ kc.tokenTimeoutHandle = null;
1090
+ }
1091
+ if (refreshToken) {
1092
+ kc.refreshToken = refreshToken;
1093
+ kc.refreshTokenParsed = decodeToken(refreshToken);
1094
+ }
1205
1095
  else {
1206
- try {
1207
- await this.updateToken(-1);
1208
- (_b = this.onAuthSuccess) === null || _b === void 0 ? void 0 : _b.call(this);
1096
+ delete kc.refreshToken;
1097
+ delete kc.refreshTokenParsed;
1098
+ }
1099
+ if (idToken) {
1100
+ kc.idToken = idToken;
1101
+ kc.idTokenParsed = decodeToken(idToken);
1102
+ }
1103
+ else {
1104
+ delete kc.idToken;
1105
+ delete kc.idTokenParsed;
1106
+ }
1107
+ if (token) {
1108
+ kc.token = token;
1109
+ kc.tokenParsed = decodeToken(token);
1110
+ kc.sessionId = kc.tokenParsed.sid;
1111
+ kc.authenticated = true;
1112
+ kc.subject = kc.tokenParsed.sub;
1113
+ kc.realmAccess = kc.tokenParsed.realm_access;
1114
+ kc.resourceAccess = kc.tokenParsed.resource_access;
1115
+ if (timeLocal) {
1116
+ kc.timeSkew = Math.floor(timeLocal / 1000) - kc.tokenParsed.iat;
1209
1117
  }
1210
- catch (error) {
1211
- (_c = this.onAuthError) === null || _c === void 0 ? void 0 : _c.call(this);
1212
- if (initOptions.onLoad) {
1213
- await onLoad();
1214
- }
1215
- else {
1216
- throw error;
1118
+ if (kc.timeSkew != null) {
1119
+ logInfo('[TIDECLOAK] Estimated time difference between browser and server is ' + kc.timeSkew + ' seconds');
1120
+ if (kc.onTokenExpired) {
1121
+ var expiresIn = (kc.tokenParsed['exp'] - (new Date().getTime() / 1000) + kc.timeSkew) * 1000;
1122
+ logInfo('[TIDECLOAK] Token expires in ' + Math.round(expiresIn / 1000) + ' s');
1123
+ if (expiresIn <= 0) {
1124
+ kc.onTokenExpired();
1125
+ }
1126
+ else {
1127
+ kc.tokenTimeoutHandle = setTimeout(kc.onTokenExpired, expiresIn);
1128
+ }
1217
1129
  }
1218
1130
  }
1219
1131
  }
1132
+ else {
1133
+ delete kc.token;
1134
+ delete kc.tokenParsed;
1135
+ delete kc.subject;
1136
+ delete kc.realmAccess;
1137
+ delete kc.resourceAccess;
1138
+ kc.authenticated = false;
1139
+ }
1140
+ if (doken) {
1141
+ kc.doken = doken;
1142
+ kc.dokenParsed = decodeToken(doken);
1143
+ // update heimdall's doken too
1144
+ if (kc.requestEnclave)
1145
+ kc.requestEnclave.updateDoken(kc.doken);
1146
+ }
1147
+ else {
1148
+ delete kc.doken;
1149
+ }
1220
1150
  }
1221
- else if (initOptions.onLoad) {
1222
- await onLoad();
1223
- }
1224
- }, _TideCloak_setupCheckLoginIframe =
1225
- /**
1226
- * @returns {Promise<void>}
1227
- */
1228
- async function _TideCloak_setupCheckLoginIframe() {
1229
- if (!__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable || __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframe) {
1230
- return;
1151
+ function createUUID() {
1152
+ if (typeof crypto === "undefined" || typeof crypto.randomUUID === "undefined") {
1153
+ throw new Error("Web Crypto API is not available.");
1154
+ }
1155
+ return crypto.randomUUID();
1231
1156
  }
1232
- const iframe = document.createElement('iframe');
1233
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframe = iframe;
1234
- iframe.setAttribute('src', this.endpoints.checkSessionIframe());
1235
- iframe.setAttribute('sandbox', 'allow-storage-access-by-user-activation allow-scripts allow-same-origin');
1236
- iframe.setAttribute('title', 'keycloak-session-iframe');
1237
- iframe.style.display = 'none';
1238
- document.body.appendChild(iframe);
1239
- /**
1240
- * @param {MessageEvent} event
1241
- */
1242
- const messageCallback = (event) => {
1243
- var _a;
1244
- if (event.origin !== __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframeOrigin || ((_a = __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframe) === null || _a === void 0 ? void 0 : _a.contentWindow) !== event.source) {
1157
+ function parseCallback(url) {
1158
+ var oauth = parseCallbackUrl(url);
1159
+ if (!oauth) {
1245
1160
  return;
1246
1161
  }
1247
- if (!(event.data === 'unchanged' || event.data === 'changed' || event.data === 'error')) {
1248
- return;
1162
+ var oauthState = callbackStorage.get(oauth.state);
1163
+ if (oauthState) {
1164
+ oauth.valid = true;
1165
+ oauth.redirectUri = oauthState.redirectUri;
1166
+ oauth.storedNonce = oauthState.nonce;
1167
+ oauth.prompt = oauthState.prompt;
1168
+ oauth.pkceCodeVerifier = oauthState.pkceCodeVerifier;
1169
+ oauth.loginOptions = oauthState.loginOptions;
1170
+ }
1171
+ return oauth;
1172
+ }
1173
+ function parseCallbackUrl(url) {
1174
+ var supportedParams;
1175
+ switch (kc.flow) {
1176
+ case 'standard':
1177
+ supportedParams = ['code', 'state', 'session_state', 'kc_action_status', 'kc_action', 'iss'];
1178
+ break;
1179
+ case 'implicit':
1180
+ supportedParams = ['access_token', 'token_type', 'id_token', 'state', 'session_state', 'expires_in', 'kc_action_status', 'kc_action', 'iss'];
1181
+ break;
1182
+ case 'hybrid':
1183
+ supportedParams = ['access_token', 'token_type', 'id_token', 'code', 'state', 'session_state', 'expires_in', 'kc_action_status', 'kc_action', 'iss'];
1184
+ break;
1249
1185
  }
1250
- if (event.data !== 'unchanged') {
1251
- this.clearToken();
1186
+ supportedParams.push('error');
1187
+ supportedParams.push('error_description');
1188
+ supportedParams.push('error_uri');
1189
+ var queryIndex = url.indexOf('?');
1190
+ var fragmentIndex = url.indexOf('#');
1191
+ var newUrl;
1192
+ var parsed;
1193
+ if (kc.responseMode === 'query' && queryIndex !== -1) {
1194
+ newUrl = url.substring(0, queryIndex);
1195
+ parsed = parseCallbackParams(url.substring(queryIndex + 1, fragmentIndex !== -1 ? fragmentIndex : url.length), supportedParams);
1196
+ if (parsed.paramsString !== '') {
1197
+ newUrl += '?' + parsed.paramsString;
1198
+ }
1199
+ if (fragmentIndex !== -1) {
1200
+ newUrl += url.substring(fragmentIndex);
1201
+ }
1252
1202
  }
1253
- const callbacks = __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").callbackList;
1254
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").callbackList = [];
1255
- for (const callback of callbacks.reverse()) {
1256
- if (event.data === 'error') {
1257
- callback(new Error('Error while checking login iframe'));
1203
+ else if (kc.responseMode === 'fragment' && fragmentIndex !== -1) {
1204
+ newUrl = url.substring(0, fragmentIndex);
1205
+ parsed = parseCallbackParams(url.substring(fragmentIndex + 1), supportedParams);
1206
+ if (parsed.paramsString !== '') {
1207
+ newUrl += '#' + parsed.paramsString;
1258
1208
  }
1259
- else {
1260
- callback(null, event.data === 'unchanged');
1209
+ }
1210
+ if (parsed && parsed.oauthParams) {
1211
+ if (kc.flow === 'standard' || kc.flow === 'hybrid') {
1212
+ if ((parsed.oauthParams.code || parsed.oauthParams.error) && parsed.oauthParams.state) {
1213
+ parsed.oauthParams.newUrl = newUrl;
1214
+ return parsed.oauthParams;
1215
+ }
1216
+ }
1217
+ else if (kc.flow === 'implicit') {
1218
+ if ((parsed.oauthParams.access_token || parsed.oauthParams.error) && parsed.oauthParams.state) {
1219
+ parsed.oauthParams.newUrl = newUrl;
1220
+ return parsed.oauthParams;
1221
+ }
1261
1222
  }
1262
1223
  }
1263
- };
1264
- window.addEventListener('message', messageCallback, false);
1265
- /** @type {Promise<void>} */
1266
- const promise = new Promise((resolve) => {
1267
- iframe.addEventListener('load', () => {
1268
- const authUrl = this.endpoints.authorize();
1269
- if (authUrl.startsWith('/')) {
1270
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframeOrigin = globalThis.location.origin;
1224
+ }
1225
+ function parseCallbackParams(paramsString, supportedParams) {
1226
+ var p = paramsString.split('&');
1227
+ var result = {
1228
+ paramsString: '',
1229
+ oauthParams: {}
1230
+ };
1231
+ for (var i = 0; i < p.length; i++) {
1232
+ var split = p[i].indexOf("=");
1233
+ var key = p[i].slice(0, split);
1234
+ if (supportedParams.indexOf(key) !== -1) {
1235
+ result.oauthParams[key] = p[i].slice(split + 1);
1271
1236
  }
1272
1237
  else {
1273
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframeOrigin = new URL(authUrl).origin;
1238
+ if (result.paramsString !== '') {
1239
+ result.paramsString += '&';
1240
+ }
1241
+ result.paramsString += p[i];
1242
+ }
1243
+ }
1244
+ return result;
1245
+ }
1246
+ function createPromise() {
1247
+ // Need to create a native Promise which also preserves the
1248
+ // interface of the custom promise type previously used by the API
1249
+ var p = {
1250
+ setSuccess: function (result) {
1251
+ p.resolve(result);
1252
+ },
1253
+ setError: function (result) {
1254
+ p.reject(result);
1274
1255
  }
1275
- resolve();
1256
+ };
1257
+ p.promise = new Promise(function (resolve, reject) {
1258
+ p.resolve = resolve;
1259
+ p.reject = reject;
1260
+ });
1261
+ return p;
1262
+ }
1263
+ // Function to extend existing native Promise with timeout
1264
+ function applyTimeoutToPromise(promise, timeout, errorMessage) {
1265
+ var timeoutHandle = null;
1266
+ var timeoutPromise = new Promise(function (resolve, reject) {
1267
+ timeoutHandle = setTimeout(function () {
1268
+ reject({ "error": errorMessage || "Promise is not settled within timeout of " + timeout + "ms" });
1269
+ }, timeout);
1270
+ });
1271
+ return Promise.race([promise, timeoutPromise]).finally(function () {
1272
+ clearTimeout(timeoutHandle);
1276
1273
  });
1277
- });
1278
- await promise;
1279
- }, _TideCloak_checkLoginIframe =
1280
- /**
1281
- * @returns {Promise<boolean | undefined>}
1282
- */
1283
- async function _TideCloak_checkLoginIframe() {
1284
- if (!__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframe || !__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframeOrigin) {
1285
- return;
1286
1274
  }
1287
- const message = `${this.clientId} ${(this.sessionId ? this.sessionId : '')}`;
1288
- const origin = __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframeOrigin;
1289
- /** @type {Promise<boolean>} */
1290
- const promise = new Promise((resolve, reject) => {
1291
- var _a, _b;
1292
- /** @type {(error: Error | null, value?: boolean) => void} */
1293
- const callback = (error, result) => error ? reject(error) : resolve(/** @type {boolean} */ (result));
1294
- __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").callbackList.push(callback);
1295
- if (__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").callbackList.length === 1) {
1296
- (_b = (_a = __classPrivateFieldGet(this, _TideCloak_loginIframe, "f").iframe) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.postMessage(message, origin);
1297
- }
1298
- });
1299
- return await promise;
1300
- }, _TideCloak_checkSsoSilently =
1301
- /**
1302
- * @returns {Promise<void>}
1303
- */
1304
- async function _TideCloak_checkSsoSilently() {
1305
- const iframe = document.createElement('iframe');
1306
- const src = await this.createLoginUrl({ prompt: 'none', redirectUri: this.silentCheckSsoRedirectUri });
1307
- iframe.setAttribute('src', src);
1308
- iframe.setAttribute('sandbox', 'allow-storage-access-by-user-activation allow-scripts allow-same-origin');
1309
- iframe.setAttribute('title', 'keycloak-silent-check-sso');
1310
- iframe.style.display = 'none';
1311
- document.body.appendChild(iframe);
1312
- return await new Promise((resolve, reject) => {
1313
- /**
1314
- * @param {MessageEvent} event
1315
- */
1316
- const messageCallback = async (event) => {
1317
- if (event.origin !== window.location.origin || iframe.contentWindow !== event.source) {
1318
- return;
1319
- }
1320
- const oauth = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallback).call(this, event.data);
1321
- try {
1322
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_processCallback).call(this, oauth);
1323
- resolve();
1275
+ function setupCheckLoginIframe() {
1276
+ var promise = createPromise();
1277
+ if (!loginIframe.enable) {
1278
+ promise.setSuccess();
1279
+ return promise.promise;
1280
+ }
1281
+ if (loginIframe.iframe) {
1282
+ promise.setSuccess();
1283
+ return promise.promise;
1284
+ }
1285
+ var iframe = document.createElement('iframe');
1286
+ loginIframe.iframe = iframe;
1287
+ iframe.onload = function () {
1288
+ var authUrl = kc.endpoints.authorize();
1289
+ if (authUrl.charAt(0) === '/') {
1290
+ loginIframe.iframeOrigin = getOrigin();
1324
1291
  }
1325
- catch (error) {
1326
- reject(error);
1292
+ else {
1293
+ loginIframe.iframeOrigin = authUrl.substring(0, authUrl.indexOf('/', 8));
1327
1294
  }
1328
- document.body.removeChild(iframe);
1329
- window.removeEventListener('message', messageCallback);
1295
+ promise.setSuccess();
1330
1296
  };
1331
- window.addEventListener('message', messageCallback);
1332
- });
1333
- }, _TideCloak_parseCallback = function _TideCloak_parseCallback(url) {
1334
- const oauth = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallbackUrl).call(this, url);
1335
- if (!oauth) {
1336
- return;
1337
- }
1338
- const oauthState = __classPrivateFieldGet(this, _TideCloak_callbackStorage, "f").get(oauth.state);
1339
- if (oauthState) {
1340
- oauth.valid = true;
1341
- oauth.redirectUri = oauthState.redirectUri;
1342
- oauth.storedNonce = oauthState.nonce;
1343
- oauth.prompt = oauthState.prompt;
1344
- oauth.pkceCodeVerifier = oauthState.pkceCodeVerifier;
1345
- oauth.loginOptions = oauthState.loginOptions;
1346
- }
1347
- return oauth;
1348
- }, _TideCloak_parseCallbackUrl = function _TideCloak_parseCallbackUrl(urlString) {
1349
- let supportedParams = [];
1350
- switch (this.flow) {
1351
- case 'standard':
1352
- supportedParams = ['code', 'state', 'session_state', 'kc_action_status', 'kc_action', 'iss', 'doken'];
1353
- break;
1354
- case 'implicit':
1355
- supportedParams = ['access_token', 'token_type', 'id_token', 'state', 'session_state', 'expires_in', 'kc_action_status', 'kc_action', 'iss', 'doken'];
1356
- break;
1357
- case 'hybrid':
1358
- supportedParams = ['access_token', 'token_type', 'id_token', 'code', 'state', 'session_state', 'expires_in', 'kc_action_status', 'kc_action', 'iss', 'doken'];
1359
- break;
1360
- }
1361
- supportedParams.push('error');
1362
- supportedParams.push('error_description');
1363
- supportedParams.push('error_uri');
1364
- const url = new URL(urlString);
1365
- let redirectUri = '';
1366
- let parsed;
1367
- if (this.responseMode === 'query' && url.searchParams.size > 0) {
1368
- parsed = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallbackParams).call(this, url.search, supportedParams);
1369
- url.search = parsed.paramsString;
1370
- redirectUri = url.toString();
1371
- }
1372
- else if (this.responseMode === 'fragment' && url.hash.length > 0) {
1373
- parsed = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_parseCallbackParams).call(this, url.hash.substring(1), supportedParams);
1374
- url.hash = '';
1375
- redirectUri = url.toString();
1376
- }
1377
- if (parsed === null || parsed === void 0 ? void 0 : parsed.oauthParams) {
1378
- if (this.flow === 'standard' || this.flow === 'hybrid') {
1379
- if ((parsed.oauthParams.code || parsed.oauthParams.error) && parsed.oauthParams.state) {
1380
- parsed.oauthParams.redirectUri = redirectUri;
1381
- return parsed.oauthParams;
1297
+ var src = kc.endpoints.checkSessionIframe();
1298
+ iframe.setAttribute('src', src);
1299
+ iframe.setAttribute('sandbox', 'allow-storage-access-by-user-activation allow-scripts allow-same-origin');
1300
+ iframe.setAttribute('title', 'keycloak-session-iframe');
1301
+ iframe.style.display = 'none';
1302
+ document.body.appendChild(iframe);
1303
+ var messageCallback = function (event) {
1304
+ if ((event.origin !== loginIframe.iframeOrigin) || (loginIframe.iframe.contentWindow !== event.source)) {
1305
+ return;
1382
1306
  }
1383
- }
1384
- else if (this.flow === 'implicit') {
1385
- if ((parsed.oauthParams.access_token || parsed.oauthParams.error) && parsed.oauthParams.state) {
1386
- parsed.oauthParams.redirectUri = redirectUri;
1387
- return parsed.oauthParams;
1307
+ if (!(event.data == 'unchanged' || event.data == 'changed' || event.data == 'error')) {
1308
+ return;
1388
1309
  }
1389
- }
1390
- }
1391
- }, _TideCloak_parseCallbackParams = function _TideCloak_parseCallbackParams(paramsString, supportedParams) {
1392
- const params = new URLSearchParams(paramsString);
1393
- /** @type {Record<string, string>} */
1394
- const oauthParams = {};
1395
- for (const [key, value] of Array.from(params.entries())) {
1396
- if (supportedParams.includes(key)) {
1397
- oauthParams[key] = value;
1398
- params.delete(key);
1399
- }
1400
- }
1401
- return {
1402
- paramsString: params.toString(),
1403
- oauthParams
1404
- };
1405
- }, _TideCloak_processCallback = async function _TideCloak_processCallback(oauth) {
1406
- var _a, _b, _c, _d;
1407
- const { code, error, prompt, doken } = oauth;
1408
- let timeLocal = new Date().getTime();
1409
- /**
1410
- * @param {string} accessToken
1411
- * @param {string=} refreshToken
1412
- * @param {string=} idToken
1413
- * @param {string=} dokenValue
1414
- */
1415
- const authSuccess = (accessToken, refreshToken, idToken, dokenValue) => {
1416
- timeLocal = (timeLocal + new Date().getTime()) / 2;
1417
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_setToken).call(this, accessToken, refreshToken, idToken, timeLocal, dokenValue);
1418
- if (__classPrivateFieldGet(this, _TideCloak_useNonce, "f") && (this.idTokenParsed && this.idTokenParsed.nonce !== oauth.storedNonce)) {
1419
- __classPrivateFieldGet(this, _TideCloak_logInfo, "f").call(this, '[TIDECLOAK] Invalid nonce, clearing token');
1420
- this.clearToken();
1421
- throw new Error('Invalid nonce.');
1422
- }
1423
- };
1424
- if (oauth.kc_action_status) {
1425
- this.onActionUpdate && this.onActionUpdate(oauth.kc_action_status, oauth.kc_action);
1426
- }
1427
- if (error) {
1428
- if (prompt !== 'none') {
1429
- if (oauth.error_description && oauth.error_description === 'authentication_expired') {
1430
- await this.login(oauth.loginOptions);
1310
+ if (event.data != 'unchanged') {
1311
+ kc.clearToken();
1431
1312
  }
1432
- else {
1433
- const errorData = { error, error_description: oauth.error_description };
1434
- (_a = this.onAuthError) === null || _a === void 0 ? void 0 : _a.call(this, errorData);
1435
- throw errorData;
1313
+ var callbacks = loginIframe.callbackList.splice(0, loginIframe.callbackList.length);
1314
+ for (var i = callbacks.length - 1; i >= 0; --i) {
1315
+ var promise = callbacks[i];
1316
+ if (event.data == 'error') {
1317
+ promise.setError();
1318
+ }
1319
+ else {
1320
+ promise.setSuccess(event.data == 'unchanged');
1321
+ }
1322
+ }
1323
+ };
1324
+ window.addEventListener('message', messageCallback, false);
1325
+ return promise.promise;
1326
+ }
1327
+ function scheduleCheckIframe() {
1328
+ if (loginIframe.enable) {
1329
+ if (kc.token) {
1330
+ setTimeout(function () {
1331
+ checkLoginIframe().then(function (unchanged) {
1332
+ if (unchanged) {
1333
+ scheduleCheckIframe();
1334
+ }
1335
+ });
1336
+ }, loginIframe.interval * 1000);
1436
1337
  }
1437
1338
  }
1438
- return;
1439
1339
  }
1440
- else if ((this.flow !== 'standard') && (oauth.access_token || oauth.id_token)) {
1441
- authSuccess(oauth.access_token, undefined, oauth.id_token, doken);
1442
- (_b = this.onAuthSuccess) === null || _b === void 0 ? void 0 : _b.call(this);
1443
- }
1444
- if ((this.flow !== 'implicit') && code) {
1445
- try {
1446
- const response = await fetchAccessToken(this.endpoints.token(), code, /** @type {string} */ (this.clientId), oauth.redirectUri, oauth.pkceCodeVerifier);
1447
- authSuccess(response.access_token, response.refresh_token, response.id_token, response.doken);
1448
- if (this.flow === 'standard') {
1449
- (_c = this.onAuthSuccess) === null || _c === void 0 ? void 0 : _c.call(this);
1340
+ function checkLoginIframe() {
1341
+ var promise = createPromise();
1342
+ if (loginIframe.iframe && loginIframe.iframeOrigin) {
1343
+ var msg = kc.clientId + ' ' + (kc.sessionId ? kc.sessionId : '');
1344
+ loginIframe.callbackList.push(promise);
1345
+ var origin = loginIframe.iframeOrigin;
1346
+ if (loginIframe.callbackList.length == 1) {
1347
+ loginIframe.iframe.contentWindow.postMessage(msg, origin);
1450
1348
  }
1451
- __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_scheduleCheckIframe).call(this);
1452
1349
  }
1453
- catch (error) {
1454
- (_d = this.onAuthError) === null || _d === void 0 ? void 0 : _d.call(this);
1455
- throw error;
1350
+ else {
1351
+ promise.setSuccess();
1352
+ }
1353
+ return promise.promise;
1354
+ }
1355
+ function check3pCookiesSupported() {
1356
+ var promise = createPromise();
1357
+ if ((loginIframe.enable || kc.silentCheckSsoRedirectUri) && typeof kc.endpoints.thirdPartyCookiesIframe === 'function') {
1358
+ var iframe = document.createElement('iframe');
1359
+ iframe.setAttribute('src', kc.endpoints.thirdPartyCookiesIframe());
1360
+ iframe.setAttribute('sandbox', 'allow-storage-access-by-user-activation allow-scripts allow-same-origin');
1361
+ iframe.setAttribute('title', 'keycloak-3p-check-iframe');
1362
+ iframe.style.display = 'none';
1363
+ document.body.appendChild(iframe);
1364
+ var messageCallback = function (event) {
1365
+ if (iframe.contentWindow !== event.source) {
1366
+ return;
1367
+ }
1368
+ if (event.data !== "supported" && event.data !== "unsupported") {
1369
+ return;
1370
+ }
1371
+ else if (event.data === "unsupported") {
1372
+ logWarn("[TIDECLOAK] Your browser is blocking access to 3rd-party cookies, this means:\n\n" +
1373
+ " - It is not possible to retrieve tokens without redirecting to the TideCloak server (a.k.a. no support for silent authentication).\n" +
1374
+ " - It is not possible to automatically detect changes to the session status (such as the user logging out in another tab).\n\n" +
1375
+ "For more information see: https://www.keycloak.org/securing-apps/javascript-adapter#_modern_browsers");
1376
+ loginIframe.enable = false;
1377
+ if (kc.silentCheckSsoFallback) {
1378
+ kc.silentCheckSsoRedirectUri = false;
1379
+ }
1380
+ }
1381
+ document.body.removeChild(iframe);
1382
+ window.removeEventListener("message", messageCallback);
1383
+ promise.setSuccess();
1384
+ };
1385
+ window.addEventListener('message', messageCallback, false);
1456
1386
  }
1457
- }
1458
- }, _TideCloak_scheduleCheckIframe = async function _TideCloak_scheduleCheckIframe() {
1459
- if (__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").enable && this.token) {
1460
- await waitForTimeout(__classPrivateFieldGet(this, _TideCloak_loginIframe, "f").interval * 1000);
1461
- const unchanged = await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_checkLoginIframe).call(this);
1462
- if (unchanged) {
1463
- await __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_scheduleCheckIframe).call(this);
1387
+ else {
1388
+ promise.setSuccess();
1464
1389
  }
1390
+ return applyTimeoutToPromise(promise.promise, kc.messageReceiveTimeout, "Timeout when waiting for 3rd party check iframe message.");
1465
1391
  }
1466
- }, _TideCloak_getVoucherUrl = function _TideCloak_getVoucherUrl() {
1467
- if (!this.tokenParsed)
1468
- throw new Error('User authentication required to access voucher service');
1469
- const sid = this.tokenParsed['sid'];
1470
- const realmUrl = __classPrivateFieldGet(this, _TideCloak_instances, "m", _TideCloak_getRealmUrl).call(this);
1471
- if (!realmUrl)
1472
- throw new Error('Unable to build voucher URL, realm URL not configured');
1473
- return `${realmUrl}/tidevouchers/fromUserSession?sessionId=${encodeURIComponent(sid)}`;
1474
- }, _TideCloak_setToken = function _TideCloak_setToken(token, refreshToken, idToken, timeLocal, doken) {
1475
- if (this.tokenTimeoutHandle) {
1476
- clearTimeout(this.tokenTimeoutHandle);
1477
- this.tokenTimeoutHandle = undefined;
1478
- }
1479
- if (refreshToken) {
1480
- this.refreshToken = refreshToken;
1481
- this.refreshTokenParsed = decodeToken(refreshToken);
1482
- }
1483
- else {
1484
- delete this.refreshToken;
1485
- delete this.refreshTokenParsed;
1486
- }
1487
- if (idToken) {
1488
- this.idToken = idToken;
1489
- this.idTokenParsed = decodeToken(idToken);
1490
- }
1491
- else {
1492
- delete this.idToken;
1493
- delete this.idTokenParsed;
1494
- }
1495
- if (token) {
1496
- this.token = token;
1497
- this.tokenParsed = decodeToken(token);
1498
- this.sessionId = this.tokenParsed.sid;
1499
- this.authenticated = true;
1500
- this.subject = this.tokenParsed.sub;
1501
- this.realmAccess = this.tokenParsed.realm_access;
1502
- this.resourceAccess = this.tokenParsed.resource_access;
1503
- if (timeLocal) {
1504
- this.timeSkew = Math.floor(timeLocal / 1000) - this.tokenParsed.iat;
1505
- }
1506
- if (typeof this.timeSkew === 'number') {
1507
- __classPrivateFieldGet(this, _TideCloak_logInfo, "f").call(this, '[TIDECLOAK] Estimated time difference between browser and server is ' + this.timeSkew + ' seconds');
1508
- if (this.onTokenExpired) {
1509
- const expiresIn = (this.tokenParsed.exp - (new Date().getTime() / 1000) + this.timeSkew) * 1000;
1510
- __classPrivateFieldGet(this, _TideCloak_logInfo, "f").call(this, '[TIDECLOAK] Token expires in ' + Math.round(expiresIn / 1000) + ' s');
1511
- if (expiresIn <= 0) {
1512
- this.onTokenExpired();
1392
+ function loadAdapter(type) {
1393
+ if (!type || type == 'default') {
1394
+ return {
1395
+ login: async function (options) {
1396
+ window.location.assign(await kc.createLoginUrl(options));
1397
+ return createPromise().promise;
1398
+ },
1399
+ logout: async function (options) {
1400
+ var _a;
1401
+ const logoutMethod = (_a = options === null || options === void 0 ? void 0 : options.logoutMethod) !== null && _a !== void 0 ? _a : kc.logoutMethod;
1402
+ if (logoutMethod === "GET") {
1403
+ window.location.replace(kc.createLogoutUrl(options));
1404
+ return;
1405
+ }
1406
+ // Create form to send POST request.
1407
+ const form = document.createElement("form");
1408
+ form.setAttribute("method", "POST");
1409
+ form.setAttribute("action", kc.createLogoutUrl(options));
1410
+ form.style.display = "none";
1411
+ // Add data to form as hidden input fields.
1412
+ const data = {
1413
+ id_token_hint: kc.idToken,
1414
+ client_id: kc.clientId,
1415
+ post_logout_redirect_uri: adapter.redirectUri(options, false)
1416
+ };
1417
+ for (const [name, value] of Object.entries(data)) {
1418
+ const input = document.createElement("input");
1419
+ input.setAttribute("type", "hidden");
1420
+ input.setAttribute("name", name);
1421
+ input.setAttribute("value", value);
1422
+ form.appendChild(input);
1423
+ }
1424
+ // Append form to page and submit it to perform logout and redirect.
1425
+ document.body.appendChild(form);
1426
+ form.submit();
1427
+ },
1428
+ register: async function (options) {
1429
+ window.location.assign(await kc.createRegisterUrl(options));
1430
+ return createPromise().promise;
1431
+ },
1432
+ accountManagement: function () {
1433
+ var accountUrl = kc.createAccountUrl();
1434
+ if (typeof accountUrl !== 'undefined') {
1435
+ window.location.href = accountUrl;
1436
+ }
1437
+ else {
1438
+ throw "Not supported by the OIDC server";
1439
+ }
1440
+ return createPromise().promise;
1441
+ },
1442
+ redirectUri: function (options, encodeHash) {
1443
+ if (arguments.length == 1) {
1444
+ encodeHash = true;
1445
+ }
1446
+ if (options && options.redirectUri) {
1447
+ return options.redirectUri;
1448
+ }
1449
+ else if (kc.redirectUri) {
1450
+ return kc.redirectUri;
1451
+ }
1452
+ else {
1453
+ return location.href;
1454
+ }
1455
+ }
1456
+ };
1457
+ }
1458
+ if (type == 'cordova') {
1459
+ loginIframe.enable = false;
1460
+ var cordovaOpenWindowWrapper = function (loginUrl, target, options) {
1461
+ if (window.cordova && window.cordova.InAppBrowser) {
1462
+ // Use inappbrowser for IOS and Android if available
1463
+ return window.cordova.InAppBrowser.open(loginUrl, target, options);
1513
1464
  }
1514
1465
  else {
1515
- this.tokenTimeoutHandle = window.setTimeout(this.onTokenExpired, expiresIn);
1466
+ return window.open(loginUrl, target, options);
1516
1467
  }
1517
- }
1468
+ };
1469
+ var shallowCloneCordovaOptions = function (userOptions) {
1470
+ if (userOptions && userOptions.cordovaOptions) {
1471
+ return Object.keys(userOptions.cordovaOptions).reduce(function (options, optionName) {
1472
+ options[optionName] = userOptions.cordovaOptions[optionName];
1473
+ return options;
1474
+ }, {});
1475
+ }
1476
+ else {
1477
+ return {};
1478
+ }
1479
+ };
1480
+ var formatCordovaOptions = function (cordovaOptions) {
1481
+ return Object.keys(cordovaOptions).reduce(function (options, optionName) {
1482
+ options.push(optionName + "=" + cordovaOptions[optionName]);
1483
+ return options;
1484
+ }, []).join(",");
1485
+ };
1486
+ var createCordovaOptions = function (userOptions) {
1487
+ var cordovaOptions = shallowCloneCordovaOptions(userOptions);
1488
+ cordovaOptions.location = 'no';
1489
+ if (userOptions && userOptions.prompt == 'none') {
1490
+ cordovaOptions.hidden = 'yes';
1491
+ }
1492
+ return formatCordovaOptions(cordovaOptions);
1493
+ };
1494
+ var getCordovaRedirectUri = function () {
1495
+ return kc.redirectUri || 'http://localhost';
1496
+ };
1497
+ return {
1498
+ login: async function (options) {
1499
+ var promise = createPromise();
1500
+ var cordovaOptions = createCordovaOptions(options);
1501
+ var loginUrl = await kc.createLoginUrl(options);
1502
+ var ref = cordovaOpenWindowWrapper(loginUrl, '_blank', cordovaOptions);
1503
+ var completed = false;
1504
+ var closed = false;
1505
+ var closeBrowser = function () {
1506
+ closed = true;
1507
+ ref.close();
1508
+ };
1509
+ ref.addEventListener('loadstart', function (event) {
1510
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1511
+ var callback = parseCallback(event.url);
1512
+ processCallback(callback, promise);
1513
+ closeBrowser();
1514
+ completed = true;
1515
+ }
1516
+ });
1517
+ ref.addEventListener('loaderror', function (event) {
1518
+ if (!completed) {
1519
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1520
+ var callback = parseCallback(event.url);
1521
+ processCallback(callback, promise);
1522
+ closeBrowser();
1523
+ completed = true;
1524
+ }
1525
+ else {
1526
+ promise.setError();
1527
+ closeBrowser();
1528
+ }
1529
+ }
1530
+ });
1531
+ ref.addEventListener('exit', function (event) {
1532
+ if (!closed) {
1533
+ promise.setError({
1534
+ reason: "closed_by_user"
1535
+ });
1536
+ }
1537
+ });
1538
+ return promise.promise;
1539
+ },
1540
+ logout: function (options) {
1541
+ var promise = createPromise();
1542
+ var logoutUrl = kc.createLogoutUrl(options);
1543
+ var ref = cordovaOpenWindowWrapper(logoutUrl, '_blank', 'location=no,hidden=yes,clearcache=yes');
1544
+ var error;
1545
+ ref.addEventListener('loadstart', function (event) {
1546
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1547
+ ref.close();
1548
+ }
1549
+ });
1550
+ ref.addEventListener('loaderror', function (event) {
1551
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1552
+ ref.close();
1553
+ }
1554
+ else {
1555
+ error = true;
1556
+ ref.close();
1557
+ }
1558
+ });
1559
+ ref.addEventListener('exit', function (event) {
1560
+ if (error) {
1561
+ promise.setError();
1562
+ }
1563
+ else {
1564
+ kc.clearToken();
1565
+ promise.setSuccess();
1566
+ }
1567
+ });
1568
+ return promise.promise;
1569
+ },
1570
+ register: async function (options) {
1571
+ var promise = createPromise();
1572
+ var registerUrl = await kc.createRegisterUrl();
1573
+ var cordovaOptions = createCordovaOptions(options);
1574
+ var ref = cordovaOpenWindowWrapper(registerUrl, '_blank', cordovaOptions);
1575
+ ref.addEventListener('loadstart', function (event) {
1576
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1577
+ ref.close();
1578
+ var oauth = parseCallback(event.url);
1579
+ processCallback(oauth, promise);
1580
+ }
1581
+ });
1582
+ return promise.promise;
1583
+ },
1584
+ accountManagement: function () {
1585
+ var accountUrl = kc.createAccountUrl();
1586
+ if (typeof accountUrl !== 'undefined') {
1587
+ var ref = cordovaOpenWindowWrapper(accountUrl, '_blank', 'location=no');
1588
+ ref.addEventListener('loadstart', function (event) {
1589
+ if (event.url.indexOf(getCordovaRedirectUri()) == 0) {
1590
+ ref.close();
1591
+ }
1592
+ });
1593
+ }
1594
+ else {
1595
+ throw "Not supported by the OIDC server";
1596
+ }
1597
+ },
1598
+ redirectUri: function (options) {
1599
+ return getCordovaRedirectUri();
1600
+ }
1601
+ };
1518
1602
  }
1519
- }
1520
- else {
1521
- delete this.token;
1522
- delete this.tokenParsed;
1523
- delete this.subject;
1524
- delete this.realmAccess;
1525
- delete this.resourceAccess;
1526
- this.authenticated = false;
1527
- }
1528
- // Tide doken handling
1529
- if (doken) {
1530
- this.doken = doken;
1531
- this.dokenParsed = decodeToken(doken);
1532
- if (this.requestEnclave && typeof this.requestEnclave.updateDoken === 'function') {
1533
- this.requestEnclave.updateDoken(this.doken);
1603
+ if (type == 'cordova-native') {
1604
+ loginIframe.enable = false;
1605
+ return {
1606
+ login: async function (options) {
1607
+ var promise = createPromise();
1608
+ var loginUrl = await kc.createLoginUrl(options);
1609
+ universalLinks.subscribe('keycloak', function (event) {
1610
+ universalLinks.unsubscribe('keycloak');
1611
+ window.cordova.plugins.browsertab.close();
1612
+ var oauth = parseCallback(event.url);
1613
+ processCallback(oauth, promise);
1614
+ });
1615
+ window.cordova.plugins.browsertab.openUrl(loginUrl);
1616
+ return promise.promise;
1617
+ },
1618
+ logout: function (options) {
1619
+ var promise = createPromise();
1620
+ var logoutUrl = kc.createLogoutUrl(options);
1621
+ universalLinks.subscribe('keycloak', function (event) {
1622
+ universalLinks.unsubscribe('keycloak');
1623
+ window.cordova.plugins.browsertab.close();
1624
+ kc.clearToken();
1625
+ promise.setSuccess();
1626
+ });
1627
+ window.cordova.plugins.browsertab.openUrl(logoutUrl);
1628
+ return promise.promise;
1629
+ },
1630
+ register: async function (options) {
1631
+ var promise = createPromise();
1632
+ var registerUrl = await kc.createRegisterUrl(options);
1633
+ universalLinks.subscribe('keycloak', function (event) {
1634
+ universalLinks.unsubscribe('keycloak');
1635
+ window.cordova.plugins.browsertab.close();
1636
+ var oauth = parseCallback(event.url);
1637
+ processCallback(oauth, promise);
1638
+ });
1639
+ window.cordova.plugins.browsertab.openUrl(registerUrl);
1640
+ return promise.promise;
1641
+ },
1642
+ accountManagement: function () {
1643
+ var accountUrl = kc.createAccountUrl();
1644
+ if (typeof accountUrl !== 'undefined') {
1645
+ window.cordova.plugins.browsertab.openUrl(accountUrl);
1646
+ }
1647
+ else {
1648
+ throw "Not supported by the OIDC server";
1649
+ }
1650
+ },
1651
+ redirectUri: function (options) {
1652
+ if (options && options.redirectUri) {
1653
+ return options.redirectUri;
1654
+ }
1655
+ else if (kc.redirectUri) {
1656
+ return kc.redirectUri;
1657
+ }
1658
+ else {
1659
+ return "http://localhost";
1660
+ }
1661
+ }
1662
+ };
1534
1663
  }
1664
+ throw 'invalid adapter type: ' + type;
1535
1665
  }
1536
- else {
1537
- delete this.doken;
1538
- delete this.dokenParsed;
1539
- if (this.requestEnclave && typeof this.requestEnclave.updateDoken === 'function') {
1540
- this.requestEnclave.updateDoken(undefined);
1666
+ const STORAGE_KEY_PREFIX = 'kc-callback-';
1667
+ var LocalStorage = function () {
1668
+ if (!(this instanceof LocalStorage)) {
1669
+ return new LocalStorage();
1541
1670
  }
1542
- }
1543
- }, _TideCloak_getRealmUrl = function _TideCloak_getRealmUrl() {
1544
- if (typeof this.authServerUrl === 'undefined') {
1545
- return;
1546
- }
1547
- return `${stripTrailingSlash(this.authServerUrl)}/realms/${encodeURIComponent(/** @type {string} */ (this.realm))}`;
1548
- }, _TideCloak_createLogger = function _TideCloak_createLogger(fn) {
1549
- return (message) => {
1550
- if (this.enableLogging) {
1551
- fn.call(console, message);
1671
+ localStorage.setItem('kc-test', 'test');
1672
+ localStorage.removeItem('kc-test');
1673
+ var cs = this;
1674
+ /**
1675
+ * Clears all values from local storage that are no longer valid.
1676
+ */
1677
+ function clearInvalidValues() {
1678
+ const currentTime = Date.now();
1679
+ for (const [key, value] of getStoredEntries()) {
1680
+ // Attempt to parse the expiry time from the value.
1681
+ const expiry = parseExpiry(value);
1682
+ // Discard the value if it is malformed or expired.
1683
+ if (expiry === null || expiry < currentTime) {
1684
+ localStorage.removeItem(key);
1685
+ }
1686
+ }
1552
1687
  }
1553
- };
1554
- };
1555
- export default TideCloak;
1556
- /**
1557
- * @returns {string}
1558
- */
1559
- function createUUID() {
1560
- if (typeof crypto === 'undefined' || typeof crypto.randomUUID === 'undefined') {
1561
- throw new Error('Web Crypto API is not available.');
1562
- }
1563
- return crypto.randomUUID();
1564
- }
1565
- /**
1566
- * @param {Acr} requestedAcr
1567
- * @returns {string}
1568
- */
1569
- function buildClaimsParameter(requestedAcr) {
1570
- return JSON.stringify({
1571
- id_token: {
1572
- acr: requestedAcr
1688
+ /**
1689
+ * Clears all known values from local storage.
1690
+ */
1691
+ function clearAllValues() {
1692
+ for (const [key] of getStoredEntries()) {
1693
+ localStorage.removeItem(key);
1694
+ }
1573
1695
  }
1574
- });
1575
- }
1576
- /**
1577
- * @param {number} len
1578
- * @returns {string}
1579
- */
1580
- function generateCodeVerifier(len) {
1581
- return generateRandomString(len, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
1582
- }
1583
- /**
1584
- * @param {string} pkceMethod
1585
- * @param {string} codeVerifier
1586
- * @returns {Promise<string>}
1587
- */
1588
- async function generatePkceChallenge(pkceMethod, codeVerifier) {
1589
- if (pkceMethod !== 'S256') {
1590
- throw new TypeError(`Invalid value for 'pkceMethod', expected 'S256' but got '${pkceMethod}'.`);
1591
- }
1592
- // hash codeVerifier, then encode as url-safe base64 without padding
1593
- const hashBytes = new Uint8Array(await sha256Digest(codeVerifier));
1594
- const encodedHash = bytesToBase64(hashBytes)
1595
- .replace(/\+/g, '-')
1596
- .replace(/\//g, '_')
1597
- .replace(/=/g, '');
1598
- return encodedHash;
1599
- }
1600
- /**
1601
- * @param {number} len
1602
- * @param {string} alphabet
1603
- * @returns {string}
1604
- */
1605
- function generateRandomString(len, alphabet) {
1606
- const randomData = generateRandomData(len);
1607
- const chars = new Array(len);
1608
- for (let i = 0; i < len; i++) {
1609
- chars[i] = alphabet.charCodeAt(randomData[i] % alphabet.length);
1610
- }
1611
- return String.fromCharCode.apply(null, chars);
1612
- }
1613
- /**
1614
- * @param {number} len
1615
- * @returns {Uint8Array<ArrayBuffer>}
1616
- */
1617
- function generateRandomData(len) {
1618
- if (typeof crypto === 'undefined' || typeof crypto.getRandomValues === 'undefined') {
1619
- throw new Error('Web Crypto API is not available.');
1620
- }
1621
- return crypto.getRandomValues(new Uint8Array(len));
1622
- }
1623
- /**
1624
- * Function to extend existing native Promise with timeout
1625
- *
1626
- * @template T
1627
- * @param {Promise<T>} promise
1628
- * @param {number} timeout
1629
- * @param {string} errorMessage
1630
- * @returns {Promise<T>}
1631
- */
1632
- function applyTimeoutToPromise(promise, timeout, errorMessage) {
1633
- /** @type {number} */
1634
- let timeoutHandle;
1635
- const timeoutPromise = new Promise(function (resolve, reject) {
1636
- timeoutHandle = window.setTimeout(function () {
1637
- reject(new Error(errorMessage || 'Promise is not settled within timeout of ' + timeout + 'ms'));
1638
- }, timeout);
1639
- });
1640
- return Promise.race([promise, timeoutPromise]).finally(function () {
1641
- clearTimeout(timeoutHandle);
1642
- });
1643
- }
1644
- /**
1645
- * @returns {CallbackStorage}
1646
- */
1647
- function createCallbackStorage() {
1648
- try {
1649
- return new LocalStorage();
1650
- }
1651
- catch (err) {
1652
- return new CookieStorage();
1653
- }
1654
- }
1655
- const STORAGE_KEY_PREFIX = 'kc-callback-';
1656
- /**
1657
- * @typedef {Object} CallbackState
1658
- * @property {string} state
1659
- * @property {string} nonce
1660
- * @property {string} redirectUri
1661
- * @property {KeycloakLoginOptions} [loginOptions]
1662
- * @property {KeycloakLoginOptions['prompt']} [prompt]
1663
- * @property {string} [pkceCodeVerifier]
1664
- */
1665
- /**
1666
- * @typedef {Object} CallbackStorage
1667
- * @property {(state?: string) => CallbackState | null} get
1668
- * @property {(state: CallbackState) => void} add
1669
- */
1670
- /**
1671
- * @implements {CallbackStorage}
1672
- */
1673
- class LocalStorage {
1674
- constructor() {
1675
- _LocalStorage_instances.add(this);
1676
- globalThis.localStorage.setItem('kc-test', 'test');
1677
- globalThis.localStorage.removeItem('kc-test');
1678
- }
1679
- /**
1680
- * @param {string} [state]
1681
- * @returns {CallbackState | null}
1682
- */
1683
- get(state) {
1684
- if (!state) {
1696
+ /**
1697
+ * Gets all entries stored in local storage that are known to be managed by this class.
1698
+ * @returns {Array<[string, unknown]>} An array of key-value pairs.
1699
+ */
1700
+ function getStoredEntries() {
1701
+ return Object.entries(localStorage).filter(([key]) => key.startsWith(STORAGE_KEY_PREFIX));
1702
+ }
1703
+ /**
1704
+ * Parses the expiry time from a value stored in local storage.
1705
+ * @param {unknown} value
1706
+ * @returns {number | null} The expiry time in milliseconds, or `null` if the value is malformed.
1707
+ */
1708
+ function parseExpiry(value) {
1709
+ let parsedValue;
1710
+ // Attempt to parse the value as JSON.
1711
+ try {
1712
+ parsedValue = JSON.parse(value);
1713
+ }
1714
+ catch (error) {
1715
+ return null;
1716
+ }
1717
+ // Attempt to extract the 'expires' property.
1718
+ if (isObject(parsedValue) && 'expires' in parsedValue && typeof parsedValue.expires === 'number') {
1719
+ return parsedValue.expires;
1720
+ }
1685
1721
  return null;
1686
1722
  }
1687
- __classPrivateFieldGet(this, _LocalStorage_instances, "m", _LocalStorage_clearInvalidValues).call(this);
1688
- const key = STORAGE_KEY_PREFIX + state;
1689
- const value = globalThis.localStorage.getItem(key);
1690
- if (value) {
1691
- globalThis.localStorage.removeItem(key);
1692
- return JSON.parse(value);
1723
+ cs.get = function (state) {
1724
+ if (!state) {
1725
+ return;
1726
+ }
1727
+ var key = STORAGE_KEY_PREFIX + state;
1728
+ var value = localStorage.getItem(key);
1729
+ if (value) {
1730
+ localStorage.removeItem(key);
1731
+ value = JSON.parse(value);
1732
+ }
1733
+ clearInvalidValues();
1734
+ return value;
1735
+ };
1736
+ cs.add = function (state) {
1737
+ clearInvalidValues();
1738
+ const key = STORAGE_KEY_PREFIX + state.state;
1739
+ const value = JSON.stringify({
1740
+ ...state,
1741
+ // Set the expiry time to 1 hour from now.
1742
+ expires: Date.now() + (60 * 60 * 1000)
1743
+ });
1744
+ try {
1745
+ localStorage.setItem(key, value);
1746
+ }
1747
+ catch (error) {
1748
+ // If the storage is full, clear all known values and try again.
1749
+ clearAllValues();
1750
+ localStorage.setItem(key, value);
1751
+ }
1752
+ };
1753
+ };
1754
+ var CookieStorage = function () {
1755
+ if (!(this instanceof CookieStorage)) {
1756
+ return new CookieStorage();
1693
1757
  }
1694
- return null;
1695
- }
1696
- ;
1697
- /**
1698
- * @param {CallbackState} state
1699
- */
1700
- add(state) {
1701
- __classPrivateFieldGet(this, _LocalStorage_instances, "m", _LocalStorage_clearInvalidValues).call(this);
1702
- const key = STORAGE_KEY_PREFIX + state.state;
1703
- const value = JSON.stringify({
1704
- ...state,
1705
- // Set the expiry time to 1 hour from now.
1706
- expires: Date.now() + (60 * 60 * 1000)
1707
- });
1758
+ var cs = this;
1759
+ cs.get = function (state) {
1760
+ if (!state) {
1761
+ return;
1762
+ }
1763
+ var value = getCookie(STORAGE_KEY_PREFIX + state);
1764
+ setCookie(STORAGE_KEY_PREFIX + state, '', cookieExpiration(-100));
1765
+ if (value) {
1766
+ return JSON.parse(value);
1767
+ }
1768
+ };
1769
+ cs.add = function (state) {
1770
+ setCookie(STORAGE_KEY_PREFIX + state.state, JSON.stringify(state), cookieExpiration(60));
1771
+ };
1772
+ cs.removeItem = function (key) {
1773
+ setCookie(key, '', cookieExpiration(-100));
1774
+ };
1775
+ var cookieExpiration = function (minutes) {
1776
+ var exp = new Date();
1777
+ exp.setTime(exp.getTime() + (minutes * 60 * 1000));
1778
+ return exp;
1779
+ };
1780
+ var getCookie = function (key) {
1781
+ var name = key + '=';
1782
+ var ca = document.cookie.split(';');
1783
+ for (var i = 0; i < ca.length; i++) {
1784
+ var c = ca[i];
1785
+ while (c.charAt(0) == ' ') {
1786
+ c = c.substring(1);
1787
+ }
1788
+ if (c.indexOf(name) == 0) {
1789
+ return c.substring(name.length, c.length);
1790
+ }
1791
+ }
1792
+ return '';
1793
+ };
1794
+ var setCookie = function (key, value, expirationDate) {
1795
+ var cookie = key + '=' + value + '; '
1796
+ + 'expires=' + expirationDate.toUTCString() + '; ';
1797
+ document.cookie = cookie;
1798
+ };
1799
+ };
1800
+ function createCallbackStorage() {
1708
1801
  try {
1709
- globalThis.localStorage.setItem(key, value);
1710
- }
1711
- catch (error) {
1712
- // If the storage is full, clear all known values and try again.
1713
- __classPrivateFieldGet(this, _LocalStorage_instances, "m", _LocalStorage_clearAllValues).call(this);
1714
- globalThis.localStorage.setItem(key, value);
1715
- }
1716
- }
1717
- ;
1718
- }
1719
- _LocalStorage_instances = new WeakSet(), _LocalStorage_clearInvalidValues = function _LocalStorage_clearInvalidValues() {
1720
- const currentTime = Date.now();
1721
- for (const [key, value] of __classPrivateFieldGet(this, _LocalStorage_instances, "m", _LocalStorage_getStoredEntries).call(this)) {
1722
- // Attempt to parse the expiry time from the value.
1723
- const expiry = __classPrivateFieldGet(this, _LocalStorage_instances, "m", _LocalStorage_parseExpiry).call(this, value);
1724
- // Discard the value if it is malformed or expired.
1725
- if (expiry === null || expiry < currentTime) {
1726
- globalThis.localStorage.removeItem(key);
1727
- }
1728
- }
1729
- }, _LocalStorage_clearAllValues = function _LocalStorage_clearAllValues() {
1730
- for (const [key] of __classPrivateFieldGet(this, _LocalStorage_instances, "m", _LocalStorage_getStoredEntries).call(this)) {
1731
- globalThis.localStorage.removeItem(key);
1732
- }
1733
- }, _LocalStorage_getStoredEntries = function _LocalStorage_getStoredEntries() {
1734
- return Object.entries(globalThis.localStorage).filter(([key]) => key.startsWith(STORAGE_KEY_PREFIX));
1735
- }, _LocalStorage_parseExpiry = function _LocalStorage_parseExpiry(value) {
1736
- let parsedValue;
1737
- // Attempt to parse the value as JSON.
1738
- try {
1739
- parsedValue = JSON.parse(value);
1740
- }
1741
- catch (error) {
1742
- return null;
1743
- }
1744
- // Attempt to extract the 'expires' property.
1745
- if (isObject(parsedValue) && 'expires' in parsedValue && typeof parsedValue.expires === 'number') {
1746
- return parsedValue.expires;
1747
- }
1748
- return null;
1749
- };
1750
- /**
1751
- * @implements {CallbackStorage}
1752
- */
1753
- class CookieStorage {
1754
- constructor() {
1755
- _CookieStorage_instances.add(this);
1756
- }
1757
- /**
1758
- * @param {string} [state]
1759
- * @returns {CallbackState | null}
1760
- */
1761
- get(state) {
1762
- if (!state) {
1763
- return null;
1802
+ return new LocalStorage();
1764
1803
  }
1765
- const value = __classPrivateFieldGet(this, _CookieStorage_instances, "m", _CookieStorage_getCookie).call(this, STORAGE_KEY_PREFIX + state);
1766
- __classPrivateFieldGet(this, _CookieStorage_instances, "m", _CookieStorage_setCookie).call(this, STORAGE_KEY_PREFIX + state, '', __classPrivateFieldGet(this, _CookieStorage_instances, "m", _CookieStorage_cookieExpiration).call(this, -100));
1767
- if (value) {
1768
- return JSON.parse(value);
1804
+ catch (err) {
1769
1805
  }
1770
- return null;
1806
+ return new CookieStorage();
1771
1807
  }
1772
- /**
1773
- * @param {CallbackState} state
1774
- */
1775
- add(state) {
1776
- __classPrivateFieldGet(this, _CookieStorage_instances, "m", _CookieStorage_setCookie).call(this, STORAGE_KEY_PREFIX + state.state, JSON.stringify(state), __classPrivateFieldGet(this, _CookieStorage_instances, "m", _CookieStorage_cookieExpiration).call(this, 60));
1808
+ function createLogger(fn) {
1809
+ return function () {
1810
+ if (kc.enableLogging) {
1811
+ fn.apply(console, Array.prototype.slice.call(arguments));
1812
+ }
1813
+ };
1777
1814
  }
1778
1815
  }
1779
- _CookieStorage_instances = new WeakSet(), _CookieStorage_getCookie = function _CookieStorage_getCookie(key) {
1780
- const name = key + '=';
1781
- const ca = document.cookie.split(';');
1782
- for (let i = 0; i < ca.length; i++) {
1783
- let c = ca[i];
1784
- while (c.charAt(0) === ' ') {
1785
- c = c.substring(1);
1786
- }
1787
- if (c.indexOf(name) === 0) {
1788
- return c.substring(name.length, c.length);
1789
- }
1790
- }
1791
- return '';
1792
- }, _CookieStorage_setCookie = function _CookieStorage_setCookie(key, value, expirationDate) {
1793
- const cookie = key + '=' + value + '; ' +
1794
- 'expires=' + expirationDate.toUTCString() + '; ';
1795
- document.cookie = cookie;
1796
- }, _CookieStorage_cookieExpiration = function _CookieStorage_cookieExpiration(minutes) {
1797
- const exp = new Date();
1798
- exp.setTime(exp.getTime() + (minutes * 60 * 1000));
1799
- return exp;
1800
- };
1816
+ export default TideCloak;
1817
+ export { RequestEnclave, ApprovalEnclave } from "heimdall-tide";
1801
1818
  /**
1802
- * @param {Uint8Array<ArrayBuffer>} bytes
1819
+ * @param {ArrayBuffer} bytes
1803
1820
  * @see https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
1804
1821
  */
1805
1822
  function bytesToBase64(bytes) {
@@ -1809,30 +1826,19 @@ function bytesToBase64(bytes) {
1809
1826
  /**
1810
1827
  * @param {string} base64
1811
1828
  * @returns {Uint8Array}
1829
+ * @see https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
1812
1830
  */
1813
1831
  function base64ToBytes(base64) {
1832
+ // Decode to “binary” JS string where each char’s code point 0–255 is one byte
1814
1833
  const binString = atob(base64);
1815
1834
  const len = binString.length;
1816
1835
  const bytes = new Uint8Array(len);
1817
1836
  for (let i = 0; i < len; i++) {
1837
+ // codePointAt is safe here because each char was originally from 0–255
1818
1838
  bytes[i] = binString.codePointAt(i);
1819
1839
  }
1820
1840
  return bytes;
1821
1841
  }
1822
- /**
1823
- * @param {string} string
1824
- */
1825
- function StringToUint8Array(string) {
1826
- const enc = new TextEncoder();
1827
- return enc.encode(string);
1828
- }
1829
- /**
1830
- * @param {Uint8Array} bytes
1831
- */
1832
- function StringFromUint8Array(bytes) {
1833
- const decoder = new TextDecoder('utf-8');
1834
- return decoder.decode(bytes);
1835
- }
1836
1842
  /**
1837
1843
  * @param {string} message
1838
1844
  * @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#basic_example
@@ -1840,32 +1846,31 @@ function StringFromUint8Array(bytes) {
1840
1846
  async function sha256Digest(message) {
1841
1847
  const encoder = new TextEncoder();
1842
1848
  const data = encoder.encode(message);
1843
- if (typeof crypto === 'undefined' || typeof crypto.subtle === 'undefined') {
1844
- throw new Error('Web Crypto API is not available.');
1849
+ if (typeof crypto === "undefined" || typeof crypto.subtle === "undefined") {
1850
+ throw new Error("Web Crypto API is not available.");
1845
1851
  }
1846
- return await crypto.subtle.digest('SHA-256', data);
1852
+ return await crypto.subtle.digest("SHA-256", data);
1847
1853
  }
1848
1854
  /**
1849
1855
  * @param {string} token
1850
- * @returns {KeycloakTokenParsed}
1851
1856
  */
1852
1857
  function decodeToken(token) {
1853
- const [, payload] = token.split('.');
1854
- if (typeof payload !== 'string') {
1855
- throw new Error('Unable to decode token, payload not found.');
1858
+ const [header, payload] = token.split(".");
1859
+ if (typeof payload !== "string") {
1860
+ throw new Error("Unable to decode token, payload not found.");
1856
1861
  }
1857
1862
  let decoded;
1858
1863
  try {
1859
1864
  decoded = base64UrlDecode(payload);
1860
1865
  }
1861
1866
  catch (error) {
1862
- throw new Error('Unable to decode token, payload is not a valid Base64URL value.', { cause: error });
1867
+ throw new Error("Unable to decode token, payload is not a valid Base64URL value.", { cause: error });
1863
1868
  }
1864
1869
  try {
1865
1870
  return JSON.parse(decoded);
1866
1871
  }
1867
1872
  catch (error) {
1868
- throw new Error('Unable to decode token, payload is not a valid JSON value.', { cause: error });
1873
+ throw new Error("Unable to decode token, payload is not a valid JSON value.", { cause: error });
1869
1874
  }
1870
1875
  }
1871
1876
  /**
@@ -1873,19 +1878,19 @@ function decodeToken(token) {
1873
1878
  */
1874
1879
  function base64UrlDecode(input) {
1875
1880
  let output = input
1876
- .replaceAll('-', '+')
1877
- .replaceAll('_', '/');
1881
+ .replaceAll("-", "+")
1882
+ .replaceAll("_", "/");
1878
1883
  switch (output.length % 4) {
1879
1884
  case 0:
1880
1885
  break;
1881
1886
  case 2:
1882
- output += '==';
1887
+ output += "==";
1883
1888
  break;
1884
1889
  case 3:
1885
- output += '=';
1890
+ output += "=";
1886
1891
  break;
1887
1892
  default:
1888
- throw new Error('Input is not of the correct length.');
1893
+ throw new Error("Input is not of the correct length.");
1889
1894
  }
1890
1895
  try {
1891
1896
  return b64DecodeUnicode(output);
@@ -1901,9 +1906,9 @@ function b64DecodeUnicode(input) {
1901
1906
  return decodeURIComponent(atob(input).replace(/(.)/g, (m, p) => {
1902
1907
  let code = p.charCodeAt(0).toString(16).toUpperCase();
1903
1908
  if (code.length < 2) {
1904
- code = '0' + code;
1909
+ code = "0" + code;
1905
1910
  }
1906
- return '%' + code;
1911
+ return "%" + code;
1907
1912
  }));
1908
1913
  }
1909
1914
  /**
@@ -1913,152 +1918,8 @@ function b64DecodeUnicode(input) {
1913
1918
  function isObject(input) {
1914
1919
  return typeof input === 'object' && input !== null;
1915
1920
  }
1916
- /**
1917
- * @typedef {Object} JsonConfig The JSON version of the adapter configuration.
1918
- * @property {string} auth-server-url The URL of the authentication server.
1919
- * @property {string} realm The name of the realm.
1920
- * @property {string} resource The name of the resource, usually the client ID.
1921
- */
1922
- /**
1923
- * Fetch the adapter configuration from the given URL.
1924
- * @param {string} url
1925
- * @returns {Promise<JsonConfig>}
1926
- */
1927
- async function fetchJsonConfig(url) {
1928
- return await fetchJSON(url);
1929
- }
1930
- /**
1931
- * Fetch the OpenID configuration from the given URL.
1932
- * @param {string} url
1933
- * @returns {Promise<OpenIdProviderMetadata>}
1934
- */
1935
- async function fetchOpenIdConfig(url) {
1936
- return await fetchJSON(url);
1921
+ export function getHumanReadableObject(modelId, data, expiry) {
1922
+ return ModelRegistry.getHumanReadableModelBuilder(modelId, data, expiry).getHumanReadableObject();
1937
1923
  }
1938
- /**
1939
- * @typedef {Object} AccessTokenResponse The successful token response from the authorization server, based on the {@link https://datatracker.ietf.org/doc/html/rfc6749#section-5.1 OAuth 2.0 Authorization Framework specification}.
1940
- * @property {string} access_token The access token issued by the authorization server.
1941
- * @property {string} token_type The type of the token issued by the authorization server.
1942
- * @property {number} [expires_in] The lifetime in seconds of the access token.
1943
- * @property {string} [refresh_token] The refresh token issued by the authorization server.
1944
- * @property {string} [id_token] The ID token issued by the authorization server, if requested.
1945
- * @property {string} [scope] The scope of the access token.
1946
- */
1947
- /**
1948
- * Fetch the access token from the given URL.
1949
- * @param {string} url
1950
- * @param {string} code
1951
- * @param {string} clientId
1952
- * @param {string} redirectUri
1953
- * @param {string} [pkceCodeVerifier]
1954
- * @returns {Promise<AccessTokenResponse>}
1955
- */
1956
- async function fetchAccessToken(url, code, clientId, redirectUri, pkceCodeVerifier) {
1957
- const body = new URLSearchParams([
1958
- ['code', code],
1959
- ['grant_type', 'authorization_code'],
1960
- ['client_id', clientId],
1961
- ['redirect_uri', stripHash(redirectUri)]
1962
- ]);
1963
- if (pkceCodeVerifier) {
1964
- body.append('code_verifier', pkceCodeVerifier);
1965
- }
1966
- return await fetchJSON(url, {
1967
- method: 'POST',
1968
- credentials: 'include',
1969
- body
1970
- });
1971
- }
1972
- /**
1973
- * Fetch the refresh token from the given URL.
1974
- * @param {string} url
1975
- * @param {string} refreshToken
1976
- * @param {string} clientId
1977
- * @returns {Promise<AccessTokenResponse>}
1978
- */
1979
- async function fetchRefreshToken(url, refreshToken, clientId) {
1980
- const body = new URLSearchParams([
1981
- ['grant_type', 'refresh_token'],
1982
- ['refresh_token', refreshToken],
1983
- ['client_id', clientId]
1984
- ]);
1985
- return await fetchJSON(url, {
1986
- method: 'POST',
1987
- credentials: 'include',
1988
- body
1989
- });
1990
- }
1991
- /**
1992
- * @template [T=unknown]
1993
- * @param {string} url
1994
- * @param {RequestInit} init
1995
- * @returns {Promise<T>}
1996
- */
1997
- async function fetchJSON(url, init = {}) {
1998
- const headers = new Headers(init.headers);
1999
- headers.set('Accept', CONTENT_TYPE_JSON);
2000
- const response = await fetchWithErrorHandling(url, {
2001
- ...init,
2002
- headers
2003
- });
2004
- return await response.json();
2005
- }
2006
- /**
2007
- * @param {string} url
2008
- * @param {RequestInit} [init]
2009
- * @returns {Promise<Response>}
2010
- */
2011
- async function fetchWithErrorHandling(url, init) {
2012
- const response = await fetch(url, init);
2013
- if (!response.ok) {
2014
- throw new NetworkError('Server responded with an invalid status.', { response });
2015
- }
2016
- return response;
2017
- }
2018
- /**
2019
- * @param {string} [token]
2020
- * @returns {[string, string]}
2021
- */
2022
- function buildAuthorizationHeader(token) {
2023
- if (!token) {
2024
- throw new Error('Unable to build authorization header, token is not set, make sure the user is authenticated.');
2025
- }
2026
- return ['Authorization', `bearer ${token}`];
2027
- }
2028
- /**
2029
- * @param {string} url
2030
- * @returns {string}
2031
- */
2032
- function stripTrailingSlash(url) {
2033
- return url.endsWith('/') ? url.slice(0, -1) : url;
2034
- }
2035
- /**
2036
- * @param {string} url
2037
- * @returns {string}
2038
- */
2039
- function stripHash(url) {
2040
- const parsedUrl = new URL(url);
2041
- parsedUrl.hash = '';
2042
- return parsedUrl.toString();
2043
- }
2044
- /**
2045
- * @typedef {Object} NetworkErrorOptionsProperties
2046
- * @property {Response} response
2047
- * @typedef {ErrorOptions & NetworkErrorOptionsProperties} NetworkErrorOptions
2048
- */
2049
- export class NetworkError extends Error {
2050
- /**
2051
- * @param {string} message
2052
- * @param {NetworkErrorOptions} options
2053
- */
2054
- constructor(message, options) {
2055
- super(message, options);
2056
- this.response = options.response;
2057
- }
2058
- }
2059
- /**
2060
- * @param {number} delay
2061
- * @returns {Promise<void>}
2062
- */
2063
- const waitForTimeout = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
1924
+ export { bytesToBase64, base64ToBytes } from "../modules/tide-js/Cryptide/Serialization.js";
2064
1925
  //# sourceMappingURL=tidecloak.js.map