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