@qlik/api 1.32.0 → 1.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api-keys.d.ts +13 -12
- package/api-keys.js +64 -50
- package/apps.d.ts +56 -56
- package/apps.js +392 -304
- package/assistants.d.ts +34 -34
- package/assistants.js +257 -201
- package/audits.d.ts +10 -10
- package/audits.js +48 -36
- package/{auth-types-DqfMuSRX.d.ts → auth-types-Cj5bM3Yk.d.ts} +29 -9
- package/auth.d.ts +17 -4
- package/auth.js +4 -2
- package/automation-connections.d.ts +12 -12
- package/automation-connections.js +75 -59
- package/automations.d.ts +29 -29
- package/automations.js +159 -123
- package/automl-deployments.d.ts +4 -4
- package/automl-deployments.js +14 -12
- package/automl-predictions.d.ts +13 -13
- package/automl-predictions.js +56 -44
- package/brands.d.ts +18 -18
- package/brands.js +107 -83
- package/chunks/{LY7RP2HA.js → 4V6T7Y4L.js} +26 -8
- package/chunks/{RCLKKVYB.js → 6C6WMV7V.js} +9 -2
- package/chunks/{VVD2DPKQ.js → 6WNP7HZQ.js} +3 -3
- package/chunks/7MMXU6EL.js +86 -0
- package/chunks/{6ZONDHRN.js → EEE42MLS.js} +11 -4
- package/chunks/{FKDGGR2O.js → I2HA7WJB.js} +1362 -1366
- package/chunks/{M64RLKVG.js → M7AINAXZ.js} +7 -5
- package/chunks/{LTNGXTXG.js → QAOVZB27.js} +3 -3
- package/chunks/{YTT2FEVE.js → QZKOA6VR.js} +1 -1
- package/chunks/{UZTIZ4H5.js → VUYZKBT5.js} +74 -74
- package/chunks/{3RGGGGAR.js → ZCTVPXGO.js} +1 -1
- package/collections.d.ts +16 -15
- package/collections.js +98 -76
- package/conditions.d.ts +13 -13
- package/conditions.js +97 -75
- package/consumption.d.ts +4 -4
- package/consumption.js +11 -9
- package/csp-origins.d.ts +9 -9
- package/csp-origins.js +53 -41
- package/csrf-token.d.ts +3 -3
- package/csrf-token.js +10 -8
- package/data-alerts.d.ts +22 -22
- package/data-alerts.js +139 -107
- package/data-assets.d.ts +8 -8
- package/data-assets.js +50 -40
- package/data-connections.d.ts +16 -16
- package/data-connections.js +87 -69
- package/data-credentials.d.ts +11 -11
- package/data-credentials.js +52 -42
- package/data-files.d.ts +18 -18
- package/data-files.js +107 -83
- package/data-qualities.d.ts +6 -6
- package/data-qualities.js +28 -22
- package/data-sets.d.ts +10 -10
- package/data-sets.js +59 -47
- package/data-sources.d.ts +7 -7
- package/data-sources.js +28 -22
- package/data-stores.d.ts +16 -16
- package/data-stores.js +92 -72
- package/dcaas.d.ts +6 -6
- package/dcaas.js +28 -22
- package/di-projects.d.ts +22 -22
- package/di-projects.js +148 -116
- package/direct-access-agents.d.ts +328 -0
- package/direct-access-agents.js +108 -0
- package/encryption.d.ts +12 -12
- package/encryption.js +82 -62
- package/extensions.d.ts +11 -11
- package/extensions.js +61 -47
- package/glossaries.d.ts +33 -33
- package/glossaries.js +221 -173
- package/groups.d.ts +12 -12
- package/groups.js +72 -56
- package/identity-providers.d.ts +11 -11
- package/identity-providers.js +67 -51
- package/index.d.ts +9 -4
- package/index.js +102 -67
- package/interceptors.d.ts +9 -2
- package/interceptors.js +2 -2
- package/invoke-fetch-types-BYCD4pc9.d.ts +98 -0
- package/items.d.ts +14 -13
- package/items.js +71 -55
- package/knowledgebases.d.ts +23 -23
- package/knowledgebases.js +153 -119
- package/licenses.d.ts +16 -14
- package/licenses.js +76 -58
- package/lineage-graphs.d.ts +17 -17
- package/lineage-graphs.js +76 -60
- package/ml.d.ts +238 -60
- package/ml.js +391 -286
- package/notes.d.ts +4 -4
- package/notes.js +19 -15
- package/notifications.d.ts +4 -4
- package/notifications.js +11 -9
- package/oauth-clients.d.ts +14 -14
- package/oauth-clients.js +96 -74
- package/oauth-tokens.d.ts +5 -5
- package/oauth-tokens.js +19 -15
- package/package.json +8 -6
- package/qix.d.ts +145 -4
- package/qix.js +2 -2
- package/questions.d.ts +5 -5
- package/questions.js +22 -18
- package/quotas.d.ts +6 -6
- package/quotas.js +20 -16
- package/reload-tasks.d.ts +8 -8
- package/reload-tasks.js +46 -36
- package/reloads.d.ts +7 -7
- package/reloads.js +36 -28
- package/report-templates.d.ts +10 -10
- package/report-templates.js +64 -50
- package/reports.d.ts +4 -4
- package/reports.js +20 -16
- package/roles.d.ts +8 -8
- package/roles.js +46 -36
- package/sharing-tasks.d.ts +14 -14
- package/sharing-tasks.js +89 -69
- package/spaces.d.ts +27 -23
- package/spaces.js +153 -119
- package/tasks.d.ts +17 -17
- package/tasks.js +90 -70
- package/temp-contents.d.ts +7 -7
- package/temp-contents.js +30 -24
- package/tenants.d.ts +8 -8
- package/tenants.js +57 -45
- package/themes.d.ts +11 -11
- package/themes.js +61 -47
- package/transports.d.ts +8 -8
- package/transports.js +49 -37
- package/ui-config.d.ts +9 -9
- package/ui-config.js +61 -47
- package/users.d.ts +15 -15
- package/users.js +81 -63
- package/web-integrations.d.ts +8 -8
- package/web-integrations.js +46 -36
- package/web-notifications.d.ts +9 -9
- package/web-notifications.js +53 -41
- package/webhooks.d.ts +14 -14
- package/webhooks.js +88 -68
- package/chunks/2ZQ3ZX7F.js +0 -33
- package/invoke-fetch-types-Cq7bjkqn.d.ts +0 -243
|
@@ -1,49 +1,55 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getInterceptors
|
|
3
|
-
} from "./
|
|
3
|
+
} from "./ZCTVPXGO.js";
|
|
4
4
|
import {
|
|
5
|
+
cleanFalsyValues,
|
|
5
6
|
isBrowser,
|
|
6
|
-
isNode
|
|
7
|
-
|
|
7
|
+
isNode,
|
|
8
|
+
sortKeys
|
|
9
|
+
} from "./7MMXU6EL.js";
|
|
8
10
|
|
|
9
|
-
// src/
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
function unregisterHostConfigInternal(name) {
|
|
21
|
-
if (registeredHostConfigs[name]) {
|
|
22
|
-
delete registeredHostConfigs[name];
|
|
23
|
-
} else {
|
|
24
|
-
console.warn(`unregisterHostConfig: Host config with name "${name}" not found.`);
|
|
11
|
+
// src/invoke-fetch/invoke-fetch-errors.ts
|
|
12
|
+
var InvokeFetchError = class extends Error {
|
|
13
|
+
status;
|
|
14
|
+
headers;
|
|
15
|
+
data;
|
|
16
|
+
constructor(errorMessage, status, headers, data) {
|
|
17
|
+
super(errorMessage);
|
|
18
|
+
this.status = status;
|
|
19
|
+
this.headers = headers;
|
|
20
|
+
this.data = data;
|
|
21
|
+
this.stack = cleanStack(this.stack);
|
|
25
22
|
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
};
|
|
24
|
+
var EncodingError = class extends Error {
|
|
25
|
+
contentType;
|
|
26
|
+
data;
|
|
27
|
+
constructor(errorMessage, contentType, data) {
|
|
28
|
+
super(errorMessage);
|
|
29
|
+
this.contentType = contentType;
|
|
30
|
+
this.data = data;
|
|
31
|
+
this.stack = cleanStack(this.stack);
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (hostConfig?.reference) {
|
|
41
|
-
return getRegisteredHostConfigInternal(hostConfig.reference);
|
|
33
|
+
};
|
|
34
|
+
var regex = /^.+\/qmfe-api(?:\.js)?:(\d+)(?::\d+)?$/gim;
|
|
35
|
+
var isFromQmfeApi = (line) => {
|
|
36
|
+
const matches = line.match(regex);
|
|
37
|
+
return Boolean(matches && matches.length > 0);
|
|
38
|
+
};
|
|
39
|
+
function cleanStack(stack) {
|
|
40
|
+
if (!stack) {
|
|
41
|
+
return stack;
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const newStack = [];
|
|
44
|
+
const lines = stack.split("\n");
|
|
45
|
+
lines.reverse();
|
|
46
|
+
for (const line of lines) {
|
|
47
|
+
if (isFromQmfeApi(line)) {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
newStack.unshift(line);
|
|
45
51
|
}
|
|
46
|
-
return
|
|
52
|
+
return newStack.join("\n");
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
// src/platform/platform-functions.ts
|
|
@@ -151,943 +157,920 @@ var result = (data) => ({
|
|
|
151
157
|
...data
|
|
152
158
|
});
|
|
153
159
|
|
|
154
|
-
// src/auth/
|
|
155
|
-
var
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
160
|
+
// src/auth/auth-types.ts
|
|
161
|
+
var hostConfigCommonProperties = [
|
|
162
|
+
"authType",
|
|
163
|
+
"autoRedirect",
|
|
164
|
+
"authRedirectUserConfirmation",
|
|
165
|
+
"embedRuntimeUrl",
|
|
166
|
+
"host",
|
|
167
|
+
"onAuthFailed"
|
|
168
|
+
];
|
|
169
|
+
var authTypesThatCanBeOmitted = [
|
|
170
|
+
"apikey",
|
|
171
|
+
"oauth2",
|
|
172
|
+
"cookie",
|
|
173
|
+
"windowscookie",
|
|
174
|
+
"reference",
|
|
175
|
+
"anonymous"
|
|
176
|
+
];
|
|
177
|
+
|
|
178
|
+
// src/utils/random.ts
|
|
179
|
+
import { customAlphabet, nanoid } from "nanoid";
|
|
180
|
+
function generateRandomString(targetLength) {
|
|
181
|
+
return nanoid(targetLength);
|
|
165
182
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const authType = await determineAuthType(hostConfigToUse);
|
|
169
|
-
if (ongoingAuthModuleLoading) {
|
|
170
|
-
await ongoingAuthModuleLoading;
|
|
171
|
-
}
|
|
172
|
-
let authModule = getRegisteredAuthModule(authType);
|
|
173
|
-
if (!authModule) {
|
|
174
|
-
ongoingAuthModuleLoading = (async () => {
|
|
175
|
-
authModule = await resolveGloballyDefinedAuthModule(authType);
|
|
176
|
-
if (authModule) {
|
|
177
|
-
registerAuthModule(authType, authModule);
|
|
178
|
-
}
|
|
179
|
-
})();
|
|
180
|
-
await ongoingAuthModuleLoading;
|
|
181
|
-
}
|
|
182
|
-
if (!authModule) {
|
|
183
|
-
throw new InvalidAuthTypeError(authType);
|
|
184
|
-
}
|
|
185
|
-
if (authModule.validateHostConfig) {
|
|
186
|
-
authModule.validateHostConfig({ authType, ...hostConfigToUse });
|
|
187
|
-
}
|
|
188
|
-
return authModule;
|
|
183
|
+
function generateRandomHexString(targetLength) {
|
|
184
|
+
return customAlphabet("1234567890abcdef", targetLength)();
|
|
189
185
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
} else {
|
|
198
|
-
potentialAuthModule = globalVariable;
|
|
199
|
-
}
|
|
200
|
-
if (potentialAuthModule && potentialAuthModule.getRestCallAuthParams && potentialAuthModule.getWebSocketAuthParams && potentialAuthModule.handleAuthenticationError) {
|
|
201
|
-
return potentialAuthModule;
|
|
186
|
+
|
|
187
|
+
// src/utils/expose-internal-test-apis.ts
|
|
188
|
+
var internalApisName = "__QLIK_INTERNAL__DO_NOT_USE_OR_YOU_WILL_BE_FIRED";
|
|
189
|
+
function exposeInternalApiOnWindow(name, fn) {
|
|
190
|
+
if (globalThis.location?.origin.startsWith("https://localhost:") || globalThis.location?.origin?.endsWith("qlik-stage.com")) {
|
|
191
|
+
if (globalThis[internalApisName] === void 0) {
|
|
192
|
+
globalThis[internalApisName] = {};
|
|
202
193
|
}
|
|
203
|
-
|
|
204
|
-
throw new InvalidAuthTypeError(authType);
|
|
194
|
+
globalThis[internalApisName][name] = fn;
|
|
205
195
|
}
|
|
206
|
-
return Promise.resolve(void 0);
|
|
207
196
|
}
|
|
208
197
|
|
|
209
|
-
// src/auth/auth-
|
|
210
|
-
var
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
};
|
|
216
|
-
var UnexpectedAuthTypeError = class extends Error {
|
|
217
|
-
constructor(...expectedAuthTypes) {
|
|
218
|
-
const ors = expectedAuthTypes.map((item, index) => index === 0 ? `"${item}"` : `or "${item}"`).join(" ");
|
|
219
|
-
super(`HostConfig is not properly configured. authType is expected to be ${ors}`);
|
|
220
|
-
this.name = "UnexpectedAuthTypeError";
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
var InvalidAuthTypeError = class extends Error {
|
|
224
|
-
constructor(authType) {
|
|
225
|
-
const validAuthModules = getRegisteredAuthModules();
|
|
226
|
-
super(
|
|
227
|
-
`Not a valid auth type: ${authType}, valid auth types are; '${validAuthModules.filter((name) => name.toLowerCase() !== "qmfeembedframerauthmodule").join("', '")}'`
|
|
228
|
-
);
|
|
229
|
-
this.name = "InvalidAuthTypeError";
|
|
198
|
+
// src/auth/internal/default-auth-modules/oauth/storage-helpers.ts
|
|
199
|
+
var storagePrefix = "qlik-qmfe-api";
|
|
200
|
+
function getTopicFromOauthHostConfig(hostConfig) {
|
|
201
|
+
let topic = hostConfig.clientId + (hostConfig.scope ? `_${hostConfig.scope}` : "_user_default");
|
|
202
|
+
if (hostConfig.subject) {
|
|
203
|
+
topic += `_${hostConfig.subject}`;
|
|
230
204
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (detail) {
|
|
234
|
-
return `${title} - ${detail} (Status: ${status}, Code: ${code})`;
|
|
205
|
+
if (hostConfig.userId) {
|
|
206
|
+
topic += `_${hostConfig.userId}`;
|
|
235
207
|
}
|
|
236
|
-
return
|
|
208
|
+
return topic;
|
|
237
209
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
constructor(errors) {
|
|
241
|
-
if (typeof errors !== "object") {
|
|
242
|
-
super("Unknown error");
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
const errorArray = Array.isArray(errors) ? errors : [errors];
|
|
246
|
-
super(errorArray.map(errorToString).join(", "));
|
|
247
|
-
this.errors = errorArray;
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
// src/auth/auth-functions.ts
|
|
252
|
-
var lastErrorMessage = "";
|
|
253
|
-
function logToConsole({ message }) {
|
|
254
|
-
if (message !== lastErrorMessage) {
|
|
255
|
-
lastErrorMessage = message;
|
|
256
|
-
console.error(message);
|
|
257
|
-
}
|
|
210
|
+
function getTopicFromAnonHostConfig(hostConfig) {
|
|
211
|
+
return `${hostConfig.accessCode}_${hostConfig.clientId}`;
|
|
258
212
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const hostConfigToUse = withResolvedHostConfig(hostConfig);
|
|
264
|
-
if (Object.keys(hostConfigToUse).length === 0) {
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
try {
|
|
268
|
-
const locationUrl = new URL(toValidLocationUrl(hostConfigToUse));
|
|
269
|
-
return locationUrl.origin !== globalThis.location.origin;
|
|
270
|
-
} catch {
|
|
213
|
+
var cachedTokens = {};
|
|
214
|
+
function clearAllCachedTokens() {
|
|
215
|
+
for (const key in cachedTokens) {
|
|
216
|
+
delete cachedTokens[key];
|
|
271
217
|
}
|
|
272
|
-
return false;
|
|
273
218
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
219
|
+
exposeInternalApiOnWindow("clearAllAccessTokens", () => {
|
|
220
|
+
console.log("Clearing tokens", cachedTokens);
|
|
221
|
+
Object.keys(cachedTokens).forEach((key) => {
|
|
222
|
+
console.log("Clearing access tokens for", key);
|
|
223
|
+
deleteFromLocalStorage(key, ["access-token", "refresh-token"]);
|
|
224
|
+
deleteFromSessionStorage(key, ["access-token", "refresh-token"]);
|
|
225
|
+
});
|
|
226
|
+
clearAllCachedTokens();
|
|
227
|
+
});
|
|
228
|
+
function saveInLocalStorage(topic, name, value) {
|
|
229
|
+
localStorage.setItem(`${storagePrefix}-${topic}-${name}`, value);
|
|
230
|
+
}
|
|
231
|
+
function saveInSessionStorage(topic, name, value) {
|
|
232
|
+
sessionStorage.setItem(`${storagePrefix}-${topic}-${name}`, value);
|
|
233
|
+
}
|
|
234
|
+
function loadFromLocalStorage(topic, name) {
|
|
235
|
+
return localStorage.getItem(`${storagePrefix}-${topic}-${name}`) || void 0;
|
|
236
|
+
}
|
|
237
|
+
function loadFromSessionStorage(topic, name) {
|
|
238
|
+
return sessionStorage.getItem(`${storagePrefix}-${topic}-${name}`) || void 0;
|
|
239
|
+
}
|
|
240
|
+
function deleteFromLocalStorage(topic, names) {
|
|
241
|
+
names.forEach((name) => localStorage.removeItem(`${storagePrefix}-${topic}-${name}`));
|
|
242
|
+
}
|
|
243
|
+
function deleteFromSessionStorage(topic, names) {
|
|
244
|
+
names.forEach((name) => sessionStorage.removeItem(`${storagePrefix}-${topic}-${name}`));
|
|
245
|
+
}
|
|
246
|
+
function loadAndDeleteFromSessionStorage(topic, name) {
|
|
247
|
+
const id = `${storagePrefix}-${topic}-${name}`;
|
|
248
|
+
const result2 = sessionStorage.getItem(id) || void 0;
|
|
249
|
+
sessionStorage.removeItem(id);
|
|
250
|
+
return result2;
|
|
251
|
+
}
|
|
252
|
+
function loadOauthTokensFromStorage(topic, accessTokenStorage) {
|
|
253
|
+
let accessToken;
|
|
254
|
+
let refreshToken;
|
|
255
|
+
if (accessTokenStorage === "local") {
|
|
256
|
+
accessToken = loadFromLocalStorage(topic, "access-token");
|
|
257
|
+
refreshToken = loadFromLocalStorage(topic, "refresh-token");
|
|
258
|
+
} else if (accessTokenStorage === "session") {
|
|
259
|
+
accessToken = loadFromSessionStorage(topic, "access-token");
|
|
260
|
+
refreshToken = loadFromSessionStorage(topic, "refresh-token");
|
|
278
261
|
}
|
|
279
|
-
if (
|
|
280
|
-
return
|
|
262
|
+
if (accessToken) {
|
|
263
|
+
return {
|
|
264
|
+
accessToken,
|
|
265
|
+
refreshToken
|
|
266
|
+
};
|
|
281
267
|
}
|
|
282
|
-
|
|
283
|
-
|
|
268
|
+
return void 0;
|
|
269
|
+
}
|
|
270
|
+
async function loadCachedOauthTokens(hostConfig) {
|
|
271
|
+
return cachedTokens[getTopicFromOauthHostConfig(hostConfig)];
|
|
272
|
+
}
|
|
273
|
+
async function loadOrAcquireAccessTokenOauth(hostConfig, acquireTokens) {
|
|
274
|
+
if (!hostConfig.clientId) {
|
|
275
|
+
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
284
276
|
}
|
|
285
|
-
|
|
277
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
278
|
+
return loadOrAcquireAccessToken(topic, acquireTokens, hostConfig.noCache, hostConfig.accessTokenStorage);
|
|
286
279
|
}
|
|
287
|
-
function
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
} else if (url.toLowerCase().startsWith("https://") || url.toLowerCase().startsWith("http://")) {
|
|
293
|
-
locationUrl = url;
|
|
294
|
-
} else {
|
|
295
|
-
locationUrl = `https://${url}`;
|
|
296
|
-
}
|
|
297
|
-
while (locationUrl[locationUrl.length - 1] === "/") {
|
|
298
|
-
locationUrl = locationUrl.substring(0, locationUrl.length - 1);
|
|
280
|
+
async function loadOrAcquireAccessTokenAnon(hostConfig, acquireTokens) {
|
|
281
|
+
if (!hostConfig.accessCode) {
|
|
282
|
+
throw new InvalidHostConfigError(
|
|
283
|
+
'A host config with authType set to "anonymous" has to also provide an accessCode'
|
|
284
|
+
);
|
|
299
285
|
}
|
|
300
|
-
|
|
286
|
+
const topic = getTopicFromAnonHostConfig(hostConfig);
|
|
287
|
+
return loadOrAcquireAccessToken(topic, acquireTokens, false, void 0);
|
|
301
288
|
}
|
|
302
|
-
function
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (!url) {
|
|
306
|
-
locationUrl = globalThis.location.origin;
|
|
307
|
-
} else if (url.toLowerCase().startsWith("https://") || url.toLowerCase().startsWith("http://")) {
|
|
308
|
-
locationUrl = url;
|
|
309
|
-
} else {
|
|
310
|
-
locationUrl = `https://${url}`;
|
|
311
|
-
}
|
|
312
|
-
while (locationUrl[locationUrl.length - 1] === "/") {
|
|
313
|
-
locationUrl = locationUrl.substring(0, locationUrl.length - 1);
|
|
289
|
+
async function loadOrAcquireAccessToken(topic, acquireTokens, noCache, accessTokenStorage) {
|
|
290
|
+
if (noCache) {
|
|
291
|
+
return acquireTokens();
|
|
314
292
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const authModule = await getAuthModule(hostConfigToUse);
|
|
321
|
-
return await authModule.getWebSocketAuthParams({
|
|
322
|
-
...props,
|
|
323
|
-
hostConfig: hostConfigToUse
|
|
324
|
-
});
|
|
325
|
-
} catch (err) {
|
|
326
|
-
(hostConfigToUse.onAuthFailed || logToConsole)(normalizeAuthModuleError(err));
|
|
327
|
-
throw err;
|
|
293
|
+
const mayUseStorage = isBrowser();
|
|
294
|
+
const storedOauthTokens = cachedTokens[topic] || (mayUseStorage ? loadOauthTokensFromStorage(topic, accessTokenStorage) : void 0);
|
|
295
|
+
if (storedOauthTokens) {
|
|
296
|
+
cachedTokens[topic] = storedOauthTokens;
|
|
297
|
+
return Promise.resolve(storedOauthTokens);
|
|
328
298
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
299
|
+
const tokensPromise = acquireTokens();
|
|
300
|
+
cachedTokens[topic] = tokensPromise;
|
|
301
|
+
if (mayUseStorage) {
|
|
302
|
+
const tokens = await tokensPromise;
|
|
303
|
+
if (accessTokenStorage === "local" && tokens) {
|
|
304
|
+
if (tokens.accessToken) {
|
|
305
|
+
saveInLocalStorage(topic, "access-token", tokens.accessToken);
|
|
306
|
+
}
|
|
307
|
+
if (tokens.refreshToken) {
|
|
308
|
+
saveInLocalStorage(topic, "refresh-token", tokens.refreshToken);
|
|
309
|
+
}
|
|
310
|
+
} else if (accessTokenStorage === "session" && tokens) {
|
|
311
|
+
if (tokens.accessToken) {
|
|
312
|
+
saveInSessionStorage(topic, "access-token", tokens.accessToken);
|
|
313
|
+
}
|
|
314
|
+
if (tokens.refreshToken) {
|
|
315
|
+
saveInSessionStorage(topic, "refresh-token", tokens.refreshToken);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
341
318
|
}
|
|
319
|
+
return tokensPromise;
|
|
342
320
|
}
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
});
|
|
350
|
-
const willRetry = props.canRetry && result2.retry;
|
|
351
|
-
const willHangUntilANewPageIsLoaded = result2.preventDefault;
|
|
352
|
-
if (!willRetry && !willHangUntilANewPageIsLoaded) {
|
|
353
|
-
const { status, errorBody } = props;
|
|
354
|
-
(hostConfigToUse.onAuthFailed || logToConsole)(normalizeInbandAuthError({ status, errorBody }));
|
|
321
|
+
function clearStoredOauthTokens(hostConfig) {
|
|
322
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
323
|
+
delete cachedTokens[topic];
|
|
324
|
+
if (isBrowser()) {
|
|
325
|
+
deleteFromLocalStorage(topic, ["access-token", "refresh-token"]);
|
|
326
|
+
deleteFromSessionStorage(topic, ["access-token", "refresh-token"]);
|
|
355
327
|
}
|
|
356
|
-
return result2;
|
|
357
328
|
}
|
|
358
|
-
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
hostConfig: hostConfigToUse
|
|
365
|
-
});
|
|
366
|
-
} catch (err) {
|
|
367
|
-
(hostConfigToUse.onAuthFailed || logToConsole)(normalizeAuthModuleError(err));
|
|
368
|
-
throw err;
|
|
329
|
+
function clearStoredAnonymousTokens(hostConfig) {
|
|
330
|
+
const topic = getTopicFromAnonHostConfig(hostConfig);
|
|
331
|
+
delete cachedTokens[topic];
|
|
332
|
+
if (isBrowser()) {
|
|
333
|
+
deleteFromLocalStorage(topic, ["access-token", "refresh-token"]);
|
|
334
|
+
deleteFromSessionStorage(topic, ["access-token", "refresh-token"]);
|
|
369
335
|
}
|
|
370
336
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
if (
|
|
375
|
-
|
|
337
|
+
|
|
338
|
+
// src/auth/internal/default-auth-modules/oauth/oauth-utils.ts
|
|
339
|
+
function toPerformInteractiveLoginFunction(performInteractiveLogin) {
|
|
340
|
+
if (typeof performInteractiveLogin === "string") {
|
|
341
|
+
const fn = lookupInteractiveLoginFn(performInteractiveLogin);
|
|
342
|
+
if (!fn) {
|
|
343
|
+
throw new Error(`No such function: ${performInteractiveLogin}`);
|
|
344
|
+
}
|
|
345
|
+
return fn;
|
|
376
346
|
}
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
function registerAuthModule2(name, authModule) {
|
|
380
|
-
registerAuthModule(name, authModule);
|
|
381
|
-
}
|
|
382
|
-
function setDefaultHostConfig(hostConfig) {
|
|
383
|
-
setDefaultHostConfigInternal(hostConfig);
|
|
384
|
-
}
|
|
385
|
-
function registerHostConfig(name, hostConfig) {
|
|
386
|
-
registerHostConfigInternal(name, hostConfig);
|
|
347
|
+
return performInteractiveLogin;
|
|
387
348
|
}
|
|
388
|
-
function
|
|
389
|
-
|
|
349
|
+
function lookupGetAccessFn(getAccessToken) {
|
|
350
|
+
return globalThis[getAccessToken];
|
|
390
351
|
}
|
|
391
|
-
function
|
|
392
|
-
|
|
393
|
-
return JSON.stringify(hostConfigToUse, hostConfigPropertyIgnorer);
|
|
352
|
+
function lookupInteractiveLoginFn(name) {
|
|
353
|
+
return globalThis[name];
|
|
394
354
|
}
|
|
395
|
-
|
|
396
|
-
if (
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
if (hostConfig.apiKey) {
|
|
400
|
-
return "apikey";
|
|
401
|
-
}
|
|
402
|
-
if (hostConfig.accessCode) {
|
|
403
|
-
return "anonymous";
|
|
404
|
-
}
|
|
405
|
-
if (hostConfig.clientId) {
|
|
406
|
-
return "oauth2";
|
|
407
|
-
}
|
|
408
|
-
if (hostConfig.webIntegrationId) {
|
|
409
|
-
return "cookie";
|
|
410
|
-
}
|
|
411
|
-
if (hostConfig.reference) {
|
|
412
|
-
return "reference";
|
|
413
|
-
}
|
|
414
|
-
if (await isWindows(hostConfig)) {
|
|
415
|
-
return "windowscookie";
|
|
355
|
+
function handlePossibleErrors(data) {
|
|
356
|
+
if (data.errors) {
|
|
357
|
+
throw new AuthorizationError(data.errors);
|
|
416
358
|
}
|
|
417
|
-
return "cookie";
|
|
418
359
|
}
|
|
419
|
-
function
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
if (!hostConfigToUse.host) {
|
|
426
|
-
throw new InvalidHostConfigError("A 'host' must be set in host config when making a cross domain request");
|
|
427
|
-
}
|
|
428
|
-
}
|
|
360
|
+
function toQueryString(queryParams) {
|
|
361
|
+
const queryParamsKeys = Object.keys(queryParams);
|
|
362
|
+
queryParamsKeys.sort();
|
|
363
|
+
const query = queryParamsKeys.map((k) => `${k}=${queryParams[k]}`).join("&");
|
|
364
|
+
return query;
|
|
429
365
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
return { message: err.message };
|
|
366
|
+
function byteArrayToBase64(hashArray) {
|
|
367
|
+
let result2 = "";
|
|
368
|
+
if (isBrowser()) {
|
|
369
|
+
const byteArrayToString = String.fromCharCode.apply(null, hashArray);
|
|
370
|
+
result2 = btoa(byteArrayToString);
|
|
371
|
+
} else if (isNode()) {
|
|
372
|
+
result2 = Buffer.from(hashArray).toString("base64");
|
|
373
|
+
} else {
|
|
374
|
+
throw new Error("Environment not supported for oauth2 authentication");
|
|
440
375
|
}
|
|
441
|
-
return
|
|
376
|
+
return result2;
|
|
442
377
|
}
|
|
443
|
-
function
|
|
444
|
-
|
|
378
|
+
async function sha256(message) {
|
|
379
|
+
const msgBuffer = new TextEncoder().encode(message);
|
|
380
|
+
const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", msgBuffer);
|
|
381
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
382
|
+
const hashBase64 = byteArrayToBase64(hashArray);
|
|
383
|
+
return hashBase64.replaceAll(/\+/g, "-").replaceAll(/\//g, "_").replace(/=+$/, "");
|
|
445
384
|
}
|
|
446
|
-
function
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
385
|
+
async function createInteractiveLoginUrl(hostConfig, redirectUri, state, verifier) {
|
|
386
|
+
const clientId = hostConfig.clientId || "";
|
|
387
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
388
|
+
const codeChallenge = await sha256(verifier);
|
|
389
|
+
const queryParams = {
|
|
390
|
+
response_type: "code",
|
|
391
|
+
client_id: clientId,
|
|
392
|
+
redirect_uri: redirectUri,
|
|
393
|
+
scope: hostConfig.scope || "user_default",
|
|
394
|
+
state,
|
|
395
|
+
code_challenge: codeChallenge,
|
|
396
|
+
code_challenge_method: "S256"
|
|
397
|
+
};
|
|
398
|
+
return `${locationUrl}/oauth/authorize?${toQueryString(queryParams)}`;
|
|
458
399
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
400
|
+
async function startFullPageLoginFlow(hostConfig) {
|
|
401
|
+
const clientId = hostConfig.clientId || "";
|
|
402
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
403
|
+
const verifier = generateRandomString(128);
|
|
404
|
+
const state = generateRandomString(43);
|
|
405
|
+
const codeChallenge = await sha256(verifier);
|
|
406
|
+
const redirectUri = hostConfig.redirectUri || globalThis.location.href;
|
|
407
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
408
|
+
clearStoredOauthTokens(hostConfig);
|
|
409
|
+
saveInSessionStorage(topic, "state", state);
|
|
410
|
+
saveInSessionStorage(topic, "verifier", verifier);
|
|
411
|
+
saveInSessionStorage(topic, "href", globalThis.location.href);
|
|
412
|
+
saveInSessionStorage("", "client-in-progress", topic);
|
|
413
|
+
const queryParams = {
|
|
414
|
+
response_type: "code",
|
|
415
|
+
client_id: clientId,
|
|
416
|
+
redirect_uri: redirectUri,
|
|
417
|
+
scope: hostConfig.scope || "user_default",
|
|
418
|
+
state,
|
|
419
|
+
code_challenge: codeChallenge,
|
|
420
|
+
code_challenge_method: "S256"
|
|
421
|
+
};
|
|
422
|
+
const url = `${locationUrl}/oauth/authorize?${toQueryString(queryParams)}`;
|
|
423
|
+
globalThis.location.replace(url);
|
|
464
424
|
}
|
|
465
|
-
function
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
425
|
+
async function exchangeCodeAndVerifierForAccessTokenData(hostConfig, code, verifier, redirectUri) {
|
|
426
|
+
try {
|
|
427
|
+
const result2 = await fetch(`${toValidLocationUrl(hostConfig)}/oauth/token`, {
|
|
428
|
+
method: "POST",
|
|
429
|
+
credentials: "include",
|
|
430
|
+
mode: "cors",
|
|
431
|
+
headers: { "content-type": "application/json" },
|
|
432
|
+
redirect: "follow",
|
|
433
|
+
body: JSON.stringify({
|
|
434
|
+
grant_type: "authorization_code",
|
|
435
|
+
scope: hostConfig.scope || "user_default",
|
|
436
|
+
...code ? { code } : {},
|
|
437
|
+
...{ redirect_uri: redirectUri || globalThis.location.href },
|
|
438
|
+
...verifier ? { code_verifier: verifier } : {},
|
|
439
|
+
client_id: hostConfig.clientId
|
|
440
|
+
})
|
|
441
|
+
});
|
|
442
|
+
const data = await result2.json();
|
|
443
|
+
handlePossibleErrors(data);
|
|
444
|
+
return {
|
|
445
|
+
accessToken: data.access_token,
|
|
446
|
+
refreshToken: data.refresh_token,
|
|
447
|
+
errors: data.errors
|
|
448
|
+
};
|
|
449
|
+
} catch (err) {
|
|
450
|
+
console.error(err);
|
|
451
|
+
return new Promise(() => {
|
|
452
|
+
});
|
|
476
453
|
}
|
|
477
|
-
return "same-origin";
|
|
478
454
|
}
|
|
479
|
-
function
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
455
|
+
function createBodyWithCredentialsEtc(clientId, clientSecret, scope, subject, userId) {
|
|
456
|
+
const commonProps = {
|
|
457
|
+
client_id: clientId,
|
|
458
|
+
client_secret: clientSecret,
|
|
459
|
+
scope
|
|
460
|
+
};
|
|
461
|
+
if (subject) {
|
|
462
|
+
return {
|
|
463
|
+
...commonProps,
|
|
464
|
+
grant_type: "urn:qlik:oauth:user-impersonation",
|
|
465
|
+
user_lookup: {
|
|
466
|
+
field: "subject",
|
|
467
|
+
value: subject
|
|
468
|
+
}
|
|
469
|
+
};
|
|
490
470
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
];
|
|
501
|
-
const invalidKeys = [];
|
|
502
|
-
Object.keys(hostConfig).forEach((key) => {
|
|
503
|
-
if (!validProps.some((k) => k === key)) {
|
|
504
|
-
invalidKeys.push(key);
|
|
505
|
-
}
|
|
506
|
-
});
|
|
507
|
-
if (invalidKeys.length > 0) {
|
|
508
|
-
throw new InvalidHostConfigError(`unknown properties in host config; '${invalidKeys.join("', '")}'`);
|
|
471
|
+
if (userId) {
|
|
472
|
+
return {
|
|
473
|
+
...commonProps,
|
|
474
|
+
grant_type: "urn:qlik:oauth:user-impersonation",
|
|
475
|
+
user_lookup: {
|
|
476
|
+
field: "userId",
|
|
477
|
+
value: userId
|
|
478
|
+
}
|
|
479
|
+
};
|
|
509
480
|
}
|
|
510
|
-
return
|
|
481
|
+
return {
|
|
482
|
+
...commonProps,
|
|
483
|
+
grant_type: "client_credentials"
|
|
484
|
+
};
|
|
511
485
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
486
|
+
async function getOauthTokensWithCredentials(baseUrl, clientId, clientSecret, scope = "user_default", subject, userId) {
|
|
487
|
+
const result2 = await fetch(`${baseUrl}/oauth/token`, {
|
|
488
|
+
method: "POST",
|
|
489
|
+
mode: "cors",
|
|
490
|
+
headers: { "content-type": "application/json" },
|
|
491
|
+
body: JSON.stringify(createBodyWithCredentialsEtc(clientId, clientSecret, scope, subject, userId))
|
|
492
|
+
});
|
|
493
|
+
const data = await result2.json();
|
|
494
|
+
return {
|
|
495
|
+
accessToken: data.access_token,
|
|
496
|
+
refreshToken: data.refresh_token,
|
|
497
|
+
errors: data.errors
|
|
498
|
+
};
|
|
522
499
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
|
|
500
|
+
async function getOauthTokensWithRefreshToken(baseUrl, refreshToken, clientSecret) {
|
|
501
|
+
const result2 = await fetch(`${baseUrl}/oauth/token`, {
|
|
502
|
+
method: "POST",
|
|
503
|
+
mode: "cors",
|
|
504
|
+
headers: { "content-type": "application/json" },
|
|
505
|
+
body: JSON.stringify({
|
|
506
|
+
grant_type: "refresh_token",
|
|
507
|
+
refresh_token: refreshToken,
|
|
508
|
+
client_secret: clientSecret
|
|
509
|
+
})
|
|
510
|
+
});
|
|
511
|
+
const data = await result2.json();
|
|
512
|
+
return {
|
|
513
|
+
accessToken: data.access_token,
|
|
514
|
+
refreshToken: data.refresh_token,
|
|
515
|
+
errors: data.errors
|
|
516
|
+
};
|
|
535
517
|
}
|
|
536
|
-
function
|
|
537
|
-
|
|
518
|
+
async function getAnonymousOauthAccessToken(baseUrl, accessCode, clientId, trackingCode) {
|
|
519
|
+
const result2 = await fetch(`${baseUrl}/oauth/token/anonymous-embed`, {
|
|
520
|
+
method: "POST",
|
|
521
|
+
mode: "cors",
|
|
522
|
+
headers: { "content-type": "application/json" },
|
|
523
|
+
body: JSON.stringify({
|
|
524
|
+
eac: accessCode,
|
|
525
|
+
client_id: clientId,
|
|
526
|
+
grant_type: "urn:qlik:oauth:anonymous-embed",
|
|
527
|
+
tracking_code: trackingCode
|
|
528
|
+
})
|
|
529
|
+
});
|
|
530
|
+
const data = await result2.json();
|
|
531
|
+
return {
|
|
532
|
+
accessToken: data.access_token,
|
|
533
|
+
refreshToken: data.refresh_token,
|
|
534
|
+
errors: data.errors
|
|
535
|
+
};
|
|
538
536
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
537
|
+
async function getOAuthTokensForNode(hostConfig) {
|
|
538
|
+
const { clientId, clientSecret } = hostConfig;
|
|
539
|
+
if (!clientId || !clientSecret) {
|
|
540
|
+
throw new InvalidHostConfigError(
|
|
541
|
+
'A host config with authType set to "oauth2" has to provide a clientId and a clientSecret'
|
|
542
|
+
);
|
|
543
543
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
544
|
+
const oauthTokens = await loadOrAcquireAccessTokenOauth(hostConfig, async () => {
|
|
545
|
+
if (!hostConfig.clientId || !hostConfig.clientSecret) {
|
|
546
|
+
throw new InvalidHostConfigError(
|
|
547
|
+
'A host config with authType set to "oauth2" has to provide a clientId and a clientSecret'
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
return getOauthTokensWithCredentials(
|
|
551
|
+
toValidLocationUrl(hostConfig),
|
|
552
|
+
hostConfig.clientId,
|
|
553
|
+
hostConfig.clientSecret,
|
|
554
|
+
hostConfig.scope,
|
|
555
|
+
hostConfig.subject,
|
|
556
|
+
hostConfig.userId
|
|
557
|
+
);
|
|
551
558
|
});
|
|
552
|
-
|
|
553
|
-
});
|
|
554
|
-
function saveInLocalStorage(topic, name, value) {
|
|
555
|
-
localStorage.setItem(`${storagePrefix}-${topic}-${name}`, value);
|
|
556
|
-
}
|
|
557
|
-
function saveInSessionStorage(topic, name, value) {
|
|
558
|
-
sessionStorage.setItem(`${storagePrefix}-${topic}-${name}`, value);
|
|
559
|
-
}
|
|
560
|
-
function loadFromLocalStorage(topic, name) {
|
|
561
|
-
return localStorage.getItem(`${storagePrefix}-${topic}-${name}`) || void 0;
|
|
562
|
-
}
|
|
563
|
-
function loadFromSessionStorage(topic, name) {
|
|
564
|
-
return sessionStorage.getItem(`${storagePrefix}-${topic}-${name}`) || void 0;
|
|
565
|
-
}
|
|
566
|
-
function deleteFromLocalStorage(topic, names) {
|
|
567
|
-
names.forEach((name) => localStorage.removeItem(`${storagePrefix}-${topic}-${name}`));
|
|
568
|
-
}
|
|
569
|
-
function deleteFromSessionStorage(topic, names) {
|
|
570
|
-
names.forEach((name) => sessionStorage.removeItem(`${storagePrefix}-${topic}-${name}`));
|
|
571
|
-
}
|
|
572
|
-
function loadAndDeleteFromSessionStorage(topic, name) {
|
|
573
|
-
const id = `${storagePrefix}-${topic}-${name}`;
|
|
574
|
-
const result2 = sessionStorage.getItem(id) || void 0;
|
|
575
|
-
sessionStorage.removeItem(id);
|
|
576
|
-
return result2;
|
|
559
|
+
return oauthTokens;
|
|
577
560
|
}
|
|
578
|
-
function
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
accessToken = loadFromLocalStorage(topic, "access-token");
|
|
583
|
-
refreshToken = loadFromLocalStorage(topic, "refresh-token");
|
|
584
|
-
} else if (accessTokenStorage === "session") {
|
|
585
|
-
accessToken = loadFromSessionStorage(topic, "access-token");
|
|
586
|
-
refreshToken = loadFromSessionStorage(topic, "refresh-token");
|
|
561
|
+
async function getOAuthTokensForBrowser(hostConfig) {
|
|
562
|
+
const { clientId } = hostConfig;
|
|
563
|
+
if (!clientId) {
|
|
564
|
+
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
587
565
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
566
|
+
const oauthTokens = await loadOrAcquireAccessTokenOauth(hostConfig, async () => {
|
|
567
|
+
if (hostConfig.getAccessToken) {
|
|
568
|
+
try {
|
|
569
|
+
const tokenFetchedFromRemote = typeof hostConfig.getAccessToken === "string" ? await lookupGetAccessFn(hostConfig.getAccessToken)() : await hostConfig.getAccessToken();
|
|
570
|
+
return {
|
|
571
|
+
accessToken: tokenFetchedFromRemote,
|
|
572
|
+
refreshToken: void 0,
|
|
573
|
+
errors: void 0
|
|
574
|
+
};
|
|
575
|
+
} catch {
|
|
576
|
+
return errorMessageToAuthData("Could not fetch access token using custom function");
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
if (hostConfig.performInteractiveLogin) {
|
|
580
|
+
let usedRedirectUri;
|
|
581
|
+
try {
|
|
582
|
+
const verifier2 = generateRandomString(128);
|
|
583
|
+
const originalState = generateRandomString(43);
|
|
584
|
+
const { code: code2, state } = extractCodeAndState(
|
|
585
|
+
await toPerformInteractiveLoginFunction(hostConfig.performInteractiveLogin)({
|
|
586
|
+
getLoginUrl: async ({ redirectUri }) => {
|
|
587
|
+
usedRedirectUri = redirectUri;
|
|
588
|
+
return createInteractiveLoginUrl(hostConfig, redirectUri, originalState, verifier2);
|
|
589
|
+
}
|
|
590
|
+
})
|
|
591
|
+
);
|
|
592
|
+
if (!usedRedirectUri) {
|
|
593
|
+
return errorMessageToAuthData("No redirect uri provided");
|
|
594
|
+
}
|
|
595
|
+
if (originalState !== state) {
|
|
596
|
+
return errorMessageToAuthData("State returned by custom interactive login function does not match original");
|
|
597
|
+
}
|
|
598
|
+
if (!code2) {
|
|
599
|
+
return errorMessageToAuthData("No code found in response from custom interactive login function");
|
|
600
|
+
}
|
|
601
|
+
const tokenResponse = await exchangeCodeAndVerifierForAccessTokenData(
|
|
602
|
+
hostConfig,
|
|
603
|
+
code2,
|
|
604
|
+
verifier2,
|
|
605
|
+
usedRedirectUri
|
|
606
|
+
);
|
|
607
|
+
return tokenResponse;
|
|
608
|
+
} catch (error) {
|
|
609
|
+
return {
|
|
610
|
+
accessToken: void 0,
|
|
611
|
+
refreshToken: void 0,
|
|
612
|
+
errors: [
|
|
613
|
+
{
|
|
614
|
+
code: "",
|
|
615
|
+
status: 401,
|
|
616
|
+
title: "Could not perform custom interactive login",
|
|
617
|
+
detail: `${error}`
|
|
618
|
+
}
|
|
619
|
+
]
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
624
|
+
const code = loadAndDeleteFromSessionStorage(topic, "code");
|
|
625
|
+
const verifier = loadAndDeleteFromSessionStorage(topic, "verifier");
|
|
626
|
+
if (code && verifier) {
|
|
627
|
+
const tokenResponse = await exchangeCodeAndVerifierForAccessTokenData(
|
|
628
|
+
hostConfig,
|
|
629
|
+
code,
|
|
630
|
+
verifier,
|
|
631
|
+
hostConfig.redirectUri
|
|
632
|
+
);
|
|
633
|
+
if (tokenResponse) {
|
|
634
|
+
return tokenResponse;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
return void 0;
|
|
638
|
+
});
|
|
639
|
+
if (oauthTokens) {
|
|
640
|
+
return oauthTokens;
|
|
593
641
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
return cachedTokens[getTopicFromOauthHostConfig(hostConfig)];
|
|
598
|
-
}
|
|
599
|
-
async function loadOrAcquireAccessTokenOauth(hostConfig, acquireTokens) {
|
|
600
|
-
if (!hostConfig.clientId) {
|
|
601
|
-
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
642
|
+
if (hostConfig.performInteractiveLogin) {
|
|
643
|
+
return new Promise(() => {
|
|
644
|
+
});
|
|
602
645
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}
|
|
606
|
-
async function loadOrAcquireAccessTokenAnon(hostConfig, acquireTokens) {
|
|
607
|
-
if (!hostConfig.accessCode) {
|
|
608
|
-
throw new InvalidHostConfigError(
|
|
609
|
-
'A host config with authType set to "anonymous" has to also provide an accessCode'
|
|
610
|
-
);
|
|
646
|
+
if (hostConfig.authRedirectUserConfirmation) {
|
|
647
|
+
await hostConfig.authRedirectUserConfirmation();
|
|
611
648
|
}
|
|
612
|
-
|
|
613
|
-
return
|
|
649
|
+
startFullPageLoginFlow(hostConfig);
|
|
650
|
+
return new Promise(() => {
|
|
651
|
+
});
|
|
614
652
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
return
|
|
653
|
+
var lastOauthTokensCall = Promise.resolve("");
|
|
654
|
+
async function getOAuthAccessToken(hostConfig) {
|
|
655
|
+
if (isNode()) {
|
|
656
|
+
const tokens = await getOAuthTokensForNode(hostConfig);
|
|
657
|
+
if (tokens) {
|
|
658
|
+
handlePossibleErrors(tokens);
|
|
659
|
+
return tokens.accessToken || "";
|
|
660
|
+
}
|
|
661
|
+
return "";
|
|
624
662
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
saveInLocalStorage(topic, "access-token", tokens.accessToken);
|
|
632
|
-
}
|
|
633
|
-
if (tokens.refreshToken) {
|
|
634
|
-
saveInLocalStorage(topic, "refresh-token", tokens.refreshToken);
|
|
635
|
-
}
|
|
636
|
-
} else if (accessTokenStorage === "session" && tokens) {
|
|
637
|
-
if (tokens.accessToken) {
|
|
638
|
-
saveInSessionStorage(topic, "access-token", tokens.accessToken);
|
|
663
|
+
if (isBrowser()) {
|
|
664
|
+
lastOauthTokensCall = lastOauthTokensCall.then(async () => {
|
|
665
|
+
const tokens = await getOAuthTokensForBrowser(hostConfig);
|
|
666
|
+
if (tokens) {
|
|
667
|
+
handlePossibleErrors(tokens);
|
|
668
|
+
return tokens.accessToken || "";
|
|
639
669
|
}
|
|
640
|
-
|
|
641
|
-
|
|
670
|
+
return "";
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
return lastOauthTokensCall;
|
|
674
|
+
}
|
|
675
|
+
async function refreshAccessToken(hostConfig) {
|
|
676
|
+
const tokens = await loadCachedOauthTokens(hostConfig);
|
|
677
|
+
clearStoredOauthTokens(hostConfig);
|
|
678
|
+
if (tokens && tokens.refreshToken && hostConfig.clientSecret) {
|
|
679
|
+
const refreshedTokens = await loadOrAcquireAccessTokenOauth(hostConfig, async () => {
|
|
680
|
+
if (!tokens || !tokens.refreshToken || !hostConfig.clientSecret) {
|
|
681
|
+
throw new Error("Trying to refresh tokens without refreshToken or clientSecret");
|
|
642
682
|
}
|
|
683
|
+
return getOauthTokensWithRefreshToken(
|
|
684
|
+
toValidLocationUrl(hostConfig),
|
|
685
|
+
tokens.refreshToken,
|
|
686
|
+
hostConfig.clientSecret
|
|
687
|
+
);
|
|
688
|
+
});
|
|
689
|
+
if (refreshedTokens) {
|
|
690
|
+
handlePossibleErrors(refreshedTokens);
|
|
643
691
|
}
|
|
644
692
|
}
|
|
645
|
-
return tokensPromise;
|
|
646
693
|
}
|
|
647
|
-
function
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
694
|
+
function extractCodeAndState(input) {
|
|
695
|
+
if (typeof input === "string") {
|
|
696
|
+
const queryParams = new URLSearchParams(new URL(input).search);
|
|
697
|
+
return {
|
|
698
|
+
code: queryParams.get("code") || "",
|
|
699
|
+
state: queryParams.get("state") || ""
|
|
700
|
+
};
|
|
653
701
|
}
|
|
702
|
+
return input;
|
|
654
703
|
}
|
|
655
|
-
function
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
704
|
+
function errorMessageToAuthData(message) {
|
|
705
|
+
return {
|
|
706
|
+
accessToken: void 0,
|
|
707
|
+
refreshToken: void 0,
|
|
708
|
+
errors: [
|
|
709
|
+
{
|
|
710
|
+
code: "",
|
|
711
|
+
status: 401,
|
|
712
|
+
title: message,
|
|
713
|
+
detail: ""
|
|
714
|
+
}
|
|
715
|
+
]
|
|
716
|
+
};
|
|
662
717
|
}
|
|
663
718
|
|
|
664
|
-
// src/auth/internal/default-auth-modules/oauth/
|
|
665
|
-
function
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
}
|
|
671
|
-
|
|
719
|
+
// src/auth/internal/default-auth-modules/oauth/temporary-token.ts
|
|
720
|
+
async function exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, purpose) {
|
|
721
|
+
const response = await fetch(`${toValidLocationUrl(hostConfig)}/oauth/token`, {
|
|
722
|
+
method: "POST",
|
|
723
|
+
credentials: "include",
|
|
724
|
+
mode: "cors",
|
|
725
|
+
headers: { "content-type": "application/json" },
|
|
726
|
+
redirect: "follow",
|
|
727
|
+
body: JSON.stringify({
|
|
728
|
+
subject_token: accessToken,
|
|
729
|
+
subject_token_type: "urn:ietf:params:oauth:token-type:access_token",
|
|
730
|
+
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
731
|
+
purpose,
|
|
732
|
+
redirect_uri: globalThis.location?.href,
|
|
733
|
+
client_id: hostConfig.clientId
|
|
734
|
+
})
|
|
735
|
+
});
|
|
736
|
+
if (response.status !== 200) {
|
|
737
|
+
throw await toError(response);
|
|
672
738
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
function lookupGetAccessFn(getAccessToken2) {
|
|
676
|
-
return globalThis[getAccessToken2];
|
|
677
|
-
}
|
|
678
|
-
function lookupInteractiveLoginFn(name) {
|
|
679
|
-
return globalThis[name];
|
|
739
|
+
const data = await response.json();
|
|
740
|
+
return data.access_token;
|
|
680
741
|
}
|
|
681
|
-
function
|
|
682
|
-
|
|
683
|
-
|
|
742
|
+
async function toError(response) {
|
|
743
|
+
const body = await response.text();
|
|
744
|
+
try {
|
|
745
|
+
const data = JSON.parse(body);
|
|
746
|
+
return new AuthorizationError(data.errors);
|
|
747
|
+
} catch {
|
|
748
|
+
return new AuthorizationError([
|
|
749
|
+
{
|
|
750
|
+
code: "unknown",
|
|
751
|
+
status: response.status,
|
|
752
|
+
detail: body,
|
|
753
|
+
title: "Unknown authentication error"
|
|
754
|
+
}
|
|
755
|
+
]);
|
|
684
756
|
}
|
|
685
757
|
}
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
758
|
+
|
|
759
|
+
// src/auth/internal/default-auth-modules/anonymous.ts
|
|
760
|
+
async function handlePotentialAuthenticationErrorAndRetry(hostConfig, fn) {
|
|
761
|
+
try {
|
|
762
|
+
return await fn();
|
|
763
|
+
} catch (err) {
|
|
764
|
+
const { retry } = await handleAuthenticationError({
|
|
765
|
+
hostConfig,
|
|
766
|
+
canRetry: true
|
|
767
|
+
});
|
|
768
|
+
if (retry) {
|
|
769
|
+
return fn();
|
|
770
|
+
}
|
|
771
|
+
throw err;
|
|
772
|
+
}
|
|
691
773
|
}
|
|
692
|
-
function
|
|
693
|
-
let
|
|
774
|
+
async function getOrCreateTrackingCode(hostConfig) {
|
|
775
|
+
let trackingCode;
|
|
694
776
|
if (isBrowser()) {
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
777
|
+
const topic = getTopicFromAnonHostConfig(hostConfig);
|
|
778
|
+
trackingCode = loadFromLocalStorage(topic, "tracking-code");
|
|
779
|
+
if (!trackingCode) {
|
|
780
|
+
trackingCode = createTrackingCode();
|
|
781
|
+
}
|
|
782
|
+
saveInLocalStorage(topic, "tracking-code", trackingCode);
|
|
699
783
|
} else {
|
|
700
|
-
|
|
784
|
+
trackingCode = createTrackingCode();
|
|
701
785
|
}
|
|
702
|
-
return
|
|
703
|
-
}
|
|
704
|
-
async function sha256(message) {
|
|
705
|
-
const msgBuffer = new TextEncoder().encode(message);
|
|
706
|
-
const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", msgBuffer);
|
|
707
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
708
|
-
const hashBase64 = byteArrayToBase64(hashArray);
|
|
709
|
-
return hashBase64.replaceAll(/\+/g, "-").replaceAll(/\//g, "_").replace(/=+$/, "");
|
|
710
|
-
}
|
|
711
|
-
async function createInteractiveLoginUrl(hostConfig, redirectUri, state, verifier) {
|
|
712
|
-
const clientId = hostConfig.clientId || "";
|
|
713
|
-
const locationUrl = toValidLocationUrl(hostConfig);
|
|
714
|
-
const codeChallenge = await sha256(verifier);
|
|
715
|
-
const queryParams = {
|
|
716
|
-
response_type: "code",
|
|
717
|
-
client_id: clientId,
|
|
718
|
-
redirect_uri: redirectUri,
|
|
719
|
-
scope: hostConfig.scope || "user_default",
|
|
720
|
-
state,
|
|
721
|
-
code_challenge: codeChallenge,
|
|
722
|
-
code_challenge_method: "S256"
|
|
723
|
-
};
|
|
724
|
-
return `${locationUrl}/oauth/authorize?${toQueryString(queryParams)}`;
|
|
786
|
+
return trackingCode;
|
|
725
787
|
}
|
|
726
|
-
|
|
727
|
-
const
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
const state = generateRandomString(43);
|
|
731
|
-
const codeChallenge = await sha256(verifier);
|
|
732
|
-
const redirectUri = hostConfig.redirectUri || globalThis.location.href;
|
|
733
|
-
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
734
|
-
clearStoredOauthTokens(hostConfig);
|
|
735
|
-
saveInSessionStorage(topic, "state", state);
|
|
736
|
-
saveInSessionStorage(topic, "verifier", verifier);
|
|
737
|
-
saveInSessionStorage(topic, "href", globalThis.location.href);
|
|
738
|
-
saveInSessionStorage("", "client-in-progress", topic);
|
|
739
|
-
const queryParams = {
|
|
740
|
-
response_type: "code",
|
|
741
|
-
client_id: clientId,
|
|
742
|
-
redirect_uri: redirectUri,
|
|
743
|
-
scope: hostConfig.scope || "user_default",
|
|
744
|
-
state,
|
|
745
|
-
code_challenge: codeChallenge,
|
|
746
|
-
code_challenge_method: "S256"
|
|
747
|
-
};
|
|
748
|
-
const url = `${locationUrl}/oauth/authorize?${toQueryString(queryParams)}`;
|
|
749
|
-
globalThis.location.replace(url);
|
|
788
|
+
function createTrackingCode() {
|
|
789
|
+
const timeStamp = Math.floor(Date.now() / 1e3).toString(16);
|
|
790
|
+
const randomString = generateRandomHexString(40 - timeStamp.length);
|
|
791
|
+
return `${timeStamp}${randomString}`;
|
|
750
792
|
}
|
|
751
|
-
async function
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
headers: { "content-type": "application/json" },
|
|
758
|
-
redirect: "follow",
|
|
759
|
-
body: JSON.stringify({
|
|
760
|
-
grant_type: "authorization_code",
|
|
761
|
-
scope: hostConfig.scope || "user_default",
|
|
762
|
-
...code ? { code } : {},
|
|
763
|
-
...{ redirect_uri: redirectUri || globalThis.location.href },
|
|
764
|
-
...verifier ? { code_verifier: verifier } : {},
|
|
765
|
-
client_id: hostConfig.clientId
|
|
766
|
-
})
|
|
767
|
-
});
|
|
768
|
-
const data = await result2.json();
|
|
769
|
-
handlePossibleErrors(data);
|
|
770
|
-
return {
|
|
771
|
-
accessToken: data.access_token,
|
|
772
|
-
refreshToken: data.refresh_token,
|
|
773
|
-
errors: data.errors
|
|
774
|
-
};
|
|
775
|
-
} catch (err) {
|
|
776
|
-
console.error(err);
|
|
777
|
-
return new Promise(() => {
|
|
778
|
-
});
|
|
793
|
+
async function getAnonymousAccessToken(hostConfig) {
|
|
794
|
+
const { accessCode, clientId } = hostConfig;
|
|
795
|
+
if (!accessCode || !clientId) {
|
|
796
|
+
throw new InvalidHostConfigError(
|
|
797
|
+
'A host config with authType set to "anonymous" has to provide both an accessCode and clientId'
|
|
798
|
+
);
|
|
779
799
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
grant_type: "urn:qlik:oauth:user-impersonation",
|
|
791
|
-
user_lookup: {
|
|
792
|
-
field: "subject",
|
|
793
|
-
value: subject
|
|
794
|
-
}
|
|
795
|
-
};
|
|
800
|
+
const tokens = await loadOrAcquireAccessTokenAnon(hostConfig, async () => {
|
|
801
|
+
const baseUrl = toValidLocationUrl(hostConfig);
|
|
802
|
+
const trackingCode = await getOrCreateTrackingCode(hostConfig);
|
|
803
|
+
return getAnonymousOauthAccessToken(baseUrl, accessCode, clientId, trackingCode);
|
|
804
|
+
});
|
|
805
|
+
if (!tokens) {
|
|
806
|
+
return "";
|
|
807
|
+
}
|
|
808
|
+
if (tokens.errors) {
|
|
809
|
+
throw new AuthorizationError(tokens.errors);
|
|
796
810
|
}
|
|
797
|
-
if (
|
|
798
|
-
return
|
|
799
|
-
...commonProps,
|
|
800
|
-
grant_type: "urn:qlik:oauth:user-impersonation",
|
|
801
|
-
user_lookup: {
|
|
802
|
-
field: "userId",
|
|
803
|
-
value: userId
|
|
804
|
-
}
|
|
805
|
-
};
|
|
811
|
+
if (tokens.accessToken) {
|
|
812
|
+
return tokens.accessToken;
|
|
806
813
|
}
|
|
814
|
+
return "";
|
|
815
|
+
}
|
|
816
|
+
async function getRestCallAuthParams({
|
|
817
|
+
hostConfig
|
|
818
|
+
}) {
|
|
807
819
|
return {
|
|
808
|
-
|
|
809
|
-
|
|
820
|
+
headers: {
|
|
821
|
+
Authorization: `Bearer ${await getAnonymousAccessToken(hostConfig)}`
|
|
822
|
+
},
|
|
823
|
+
queryParams: {},
|
|
824
|
+
credentials: "omit"
|
|
810
825
|
};
|
|
811
826
|
}
|
|
812
|
-
async function
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
827
|
+
async function getWebSocketAuthParams({
|
|
828
|
+
hostConfig
|
|
829
|
+
}) {
|
|
830
|
+
const websocketAccessToken = await handlePotentialAuthenticationErrorAndRetry(hostConfig, async () => {
|
|
831
|
+
const accessToken = await getAnonymousAccessToken(hostConfig);
|
|
832
|
+
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "websocket");
|
|
818
833
|
});
|
|
819
|
-
const data = await result2.json();
|
|
820
834
|
return {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
835
|
+
queryParams: {
|
|
836
|
+
accessToken: websocketAccessToken
|
|
837
|
+
}
|
|
824
838
|
};
|
|
825
839
|
}
|
|
826
|
-
async function
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
grant_type: "refresh_token",
|
|
833
|
-
refresh_token: refreshToken,
|
|
834
|
-
client_secret: clientSecret
|
|
835
|
-
})
|
|
840
|
+
async function getWebResourceAuthParams({
|
|
841
|
+
hostConfig
|
|
842
|
+
}) {
|
|
843
|
+
const websocketResourceAccessToken = await handlePotentialAuthenticationErrorAndRetry(hostConfig, async () => {
|
|
844
|
+
const accessToken = await getAnonymousAccessToken(hostConfig);
|
|
845
|
+
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "websocket");
|
|
836
846
|
});
|
|
837
|
-
const data = await result2.json();
|
|
838
847
|
return {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
848
|
+
queryParams: {
|
|
849
|
+
accessToken: websocketResourceAccessToken
|
|
850
|
+
}
|
|
842
851
|
};
|
|
843
852
|
}
|
|
844
|
-
async function
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
headers: { "content-type": "application/json" },
|
|
849
|
-
body: JSON.stringify({
|
|
850
|
-
eac: accessCode,
|
|
851
|
-
client_id: clientId,
|
|
852
|
-
grant_type: "urn:qlik:oauth:anonymous-embed",
|
|
853
|
-
tracking_code: trackingCode
|
|
854
|
-
})
|
|
855
|
-
});
|
|
856
|
-
const data = await result2.json();
|
|
853
|
+
async function handleAuthenticationError({
|
|
854
|
+
hostConfig
|
|
855
|
+
}) {
|
|
856
|
+
clearStoredAnonymousTokens(hostConfig);
|
|
857
857
|
return {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
errors: data.errors
|
|
858
|
+
preventDefault: false,
|
|
859
|
+
retry: true
|
|
861
860
|
};
|
|
862
861
|
}
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
hostConfig.scope,
|
|
881
|
-
hostConfig.subject,
|
|
882
|
-
hostConfig.userId
|
|
883
|
-
);
|
|
862
|
+
var anonymous_default = {
|
|
863
|
+
requiredProps: ["clientId", "accessCode"],
|
|
864
|
+
optionalProps: [],
|
|
865
|
+
getRestCallAuthParams,
|
|
866
|
+
getWebSocketAuthParams,
|
|
867
|
+
getWebResourceAuthParams,
|
|
868
|
+
handleAuthenticationError
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
// src/auth/internal/default-auth-modules/apikey.ts
|
|
872
|
+
function getRestCallAuthParams2({ hostConfig }) {
|
|
873
|
+
return Promise.resolve({
|
|
874
|
+
headers: {
|
|
875
|
+
Authorization: `Bearer ${hostConfig?.apiKey}`
|
|
876
|
+
},
|
|
877
|
+
queryParams: {},
|
|
878
|
+
credentials: "omit"
|
|
884
879
|
});
|
|
885
|
-
return oauthTokens;
|
|
886
880
|
}
|
|
887
|
-
async function
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
}
|
|
892
|
-
const oauthTokens = await loadOrAcquireAccessTokenOauth(hostConfig, async () => {
|
|
893
|
-
if (hostConfig.getAccessToken) {
|
|
894
|
-
try {
|
|
895
|
-
const tokenFetchedFromRemote = typeof hostConfig.getAccessToken === "string" ? await lookupGetAccessFn(hostConfig.getAccessToken)() : await hostConfig.getAccessToken();
|
|
896
|
-
return {
|
|
897
|
-
accessToken: tokenFetchedFromRemote,
|
|
898
|
-
refreshToken: void 0,
|
|
899
|
-
errors: void 0
|
|
900
|
-
};
|
|
901
|
-
} catch {
|
|
902
|
-
return errorMessageToAuthData("Could not fetch access token using custom function");
|
|
903
|
-
}
|
|
881
|
+
async function getWebSocketAuthParams2() {
|
|
882
|
+
return {
|
|
883
|
+
queryParams: {
|
|
884
|
+
// accessToken: hostConfig.apiKey,
|
|
904
885
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
function handleAuthenticationError2() {
|
|
889
|
+
return Promise.resolve({});
|
|
890
|
+
}
|
|
891
|
+
var apikey_default = {
|
|
892
|
+
requiredProps: ["apiKey"],
|
|
893
|
+
optionalProps: [],
|
|
894
|
+
getRestCallAuthParams: getRestCallAuthParams2,
|
|
895
|
+
getWebSocketAuthParams: getWebSocketAuthParams2,
|
|
896
|
+
handleAuthenticationError: handleAuthenticationError2
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
// src/http/http-constants.ts
|
|
900
|
+
var QLIK_CSRF_TOKEN = "qlik-csrf-token";
|
|
901
|
+
|
|
902
|
+
// src/http/http-functions.ts
|
|
903
|
+
function clearCsrfToken(hostConfig) {
|
|
904
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
905
|
+
delete csrfTokens[locationUrl];
|
|
906
|
+
}
|
|
907
|
+
async function getCsrfToken(hostConfig, noCache) {
|
|
908
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
909
|
+
let pathTemplate;
|
|
910
|
+
if (await isWindows(hostConfig)) {
|
|
911
|
+
pathTemplate = "/qps/csrftoken";
|
|
912
|
+
} else {
|
|
913
|
+
pathTemplate = "/api/v1/csrf-token";
|
|
914
|
+
}
|
|
915
|
+
const fetchCsrfToken = async () => {
|
|
916
|
+
try {
|
|
917
|
+
const res = await invokeFetch("csrf-token", {
|
|
918
|
+
method: "get",
|
|
919
|
+
pathTemplate,
|
|
920
|
+
options: {
|
|
928
921
|
hostConfig,
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
return {
|
|
936
|
-
accessToken: void 0,
|
|
937
|
-
refreshToken: void 0,
|
|
938
|
-
errors: [
|
|
939
|
-
{
|
|
940
|
-
code: "",
|
|
941
|
-
status: 401,
|
|
942
|
-
title: "Could not perform custom interactive login",
|
|
943
|
-
detail: `${error}`
|
|
944
|
-
}
|
|
945
|
-
]
|
|
946
|
-
};
|
|
922
|
+
noCache: true
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
const csrfToken = res.headers.get(QLIK_CSRF_TOKEN);
|
|
926
|
+
if (!csrfToken) {
|
|
927
|
+
return "";
|
|
947
928
|
}
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
const tokenResponse = await exchangeCodeAndVerifierForAccessTokenData(
|
|
954
|
-
hostConfig,
|
|
955
|
-
code,
|
|
956
|
-
verifier,
|
|
957
|
-
hostConfig.redirectUri
|
|
958
|
-
);
|
|
959
|
-
if (tokenResponse) {
|
|
960
|
-
return tokenResponse;
|
|
929
|
+
return csrfToken;
|
|
930
|
+
} catch (e) {
|
|
931
|
+
const error = e;
|
|
932
|
+
if (error.status === 404) {
|
|
933
|
+
return "";
|
|
961
934
|
}
|
|
935
|
+
throw e;
|
|
962
936
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
return
|
|
937
|
+
};
|
|
938
|
+
if (noCache) {
|
|
939
|
+
csrfTokens[locationUrl] = fetchCsrfToken();
|
|
940
|
+
return csrfTokens[locationUrl];
|
|
967
941
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
942
|
+
csrfTokens[locationUrl] = csrfTokens[locationUrl] || fetchCsrfToken();
|
|
943
|
+
return csrfTokens[locationUrl];
|
|
944
|
+
}
|
|
945
|
+
var csrfTokens = {};
|
|
946
|
+
|
|
947
|
+
// src/auth/internal/internal-auth-functions.ts
|
|
948
|
+
function internalGetCredentialsForCookieAuth(hostConfig) {
|
|
949
|
+
if (hostConfig.crossSiteCookies === false) {
|
|
950
|
+
return "same-origin";
|
|
971
951
|
}
|
|
972
|
-
if (hostConfig
|
|
973
|
-
|
|
952
|
+
if (isHostCrossOrigin(hostConfig)) {
|
|
953
|
+
return "include";
|
|
974
954
|
}
|
|
975
|
-
|
|
976
|
-
return new Promise(() => {
|
|
977
|
-
});
|
|
955
|
+
return "same-origin";
|
|
978
956
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
957
|
+
|
|
958
|
+
// src/auth/internal/default-auth-modules/cookie.ts
|
|
959
|
+
function isModifyingVerb(verb) {
|
|
960
|
+
return !(verb === "get" || verb === "GET");
|
|
961
|
+
}
|
|
962
|
+
async function getRestCallAuthParams3({
|
|
963
|
+
hostConfig,
|
|
964
|
+
method
|
|
965
|
+
}) {
|
|
966
|
+
const headers = {};
|
|
967
|
+
if (isModifyingVerb(method)) {
|
|
968
|
+
headers["qlik-csrf-token"] = await getCsrfToken(hostConfig);
|
|
988
969
|
}
|
|
989
|
-
if (
|
|
990
|
-
|
|
991
|
-
const tokens = await getOAuthTokensForBrowser(hostConfig);
|
|
992
|
-
if (tokens) {
|
|
993
|
-
handlePossibleErrors(tokens);
|
|
994
|
-
return tokens.accessToken || "";
|
|
995
|
-
}
|
|
996
|
-
return "";
|
|
997
|
-
});
|
|
970
|
+
if (hostConfig.webIntegrationId) {
|
|
971
|
+
headers["qlik-web-integration-id"] = hostConfig.webIntegrationId;
|
|
998
972
|
}
|
|
999
|
-
return
|
|
973
|
+
return { headers, queryParams: {}, credentials: internalGetCredentialsForCookieAuth(hostConfig) };
|
|
1000
974
|
}
|
|
1001
|
-
async function
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
toValidLocationUrl(hostConfig),
|
|
1011
|
-
tokens.refreshToken,
|
|
1012
|
-
hostConfig.clientSecret
|
|
1013
|
-
);
|
|
1014
|
-
});
|
|
1015
|
-
if (refreshedTokens) {
|
|
1016
|
-
handlePossibleErrors(refreshedTokens);
|
|
1017
|
-
}
|
|
975
|
+
async function getWebSocketAuthParams3({
|
|
976
|
+
hostConfig
|
|
977
|
+
}) {
|
|
978
|
+
const params = {
|
|
979
|
+
// Bypass the cache to get one rest call out the door that can catch a 401 since the websocket only returns a general error
|
|
980
|
+
"qlik-csrf-token": await getCsrfToken(hostConfig, true)
|
|
981
|
+
};
|
|
982
|
+
if (hostConfig.webIntegrationId) {
|
|
983
|
+
params["qlik-web-integration-id"] = hostConfig.webIntegrationId;
|
|
1018
984
|
}
|
|
985
|
+
return { queryParams: params };
|
|
1019
986
|
}
|
|
1020
|
-
function
|
|
1021
|
-
|
|
1022
|
-
|
|
987
|
+
async function handleAuthenticationError3({
|
|
988
|
+
hostConfig,
|
|
989
|
+
status
|
|
990
|
+
}) {
|
|
991
|
+
clearCsrfToken(hostConfig);
|
|
992
|
+
if (status === 403) {
|
|
1023
993
|
return {
|
|
1024
|
-
|
|
1025
|
-
|
|
994
|
+
preventDefault: false,
|
|
995
|
+
retry: true
|
|
1026
996
|
};
|
|
1027
997
|
}
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
998
|
+
const webIntegrationParam = hostConfig.webIntegrationId ? `qlik-web-integration-id=${hostConfig?.webIntegrationId}&` : "";
|
|
999
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
1000
|
+
if (hostConfig.authRedirectUserConfirmation) {
|
|
1001
|
+
await hostConfig.authRedirectUserConfirmation();
|
|
1002
|
+
}
|
|
1003
|
+
globalThis.location.replace(
|
|
1004
|
+
`${locationUrl}/login?${webIntegrationParam}returnto=${encodeURIComponent(globalThis.location.href)}`
|
|
1005
|
+
);
|
|
1031
1006
|
return {
|
|
1032
|
-
|
|
1033
|
-
refreshToken: void 0,
|
|
1034
|
-
errors: [
|
|
1035
|
-
{
|
|
1036
|
-
code: "",
|
|
1037
|
-
status: 401,
|
|
1038
|
-
title: message,
|
|
1039
|
-
detail: ""
|
|
1040
|
-
}
|
|
1041
|
-
]
|
|
1007
|
+
preventDefault: true
|
|
1042
1008
|
};
|
|
1043
1009
|
}
|
|
1010
|
+
var cookie_default = {
|
|
1011
|
+
requiredProps: [],
|
|
1012
|
+
optionalProps: ["webIntegrationId", "crossSiteCookies", "anonymousMode"],
|
|
1013
|
+
getRestCallAuthParams: getRestCallAuthParams3,
|
|
1014
|
+
getWebSocketAuthParams: getWebSocketAuthParams3,
|
|
1015
|
+
handleAuthenticationError: handleAuthenticationError3
|
|
1016
|
+
};
|
|
1044
1017
|
|
|
1045
|
-
// src/auth/internal/default-auth-modules/
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
method: "POST",
|
|
1049
|
-
credentials: "include",
|
|
1050
|
-
mode: "cors",
|
|
1051
|
-
headers: { "content-type": "application/json" },
|
|
1052
|
-
redirect: "follow",
|
|
1053
|
-
body: JSON.stringify({
|
|
1054
|
-
subject_token: accessToken,
|
|
1055
|
-
subject_token_type: "urn:ietf:params:oauth:token-type:access_token",
|
|
1056
|
-
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
1057
|
-
purpose,
|
|
1058
|
-
redirect_uri: globalThis.location?.href,
|
|
1059
|
-
client_id: hostConfig.clientId
|
|
1060
|
-
})
|
|
1061
|
-
});
|
|
1062
|
-
if (response.status !== 200) {
|
|
1063
|
-
throw await toError(response);
|
|
1064
|
-
}
|
|
1065
|
-
const data = await response.json();
|
|
1066
|
-
return data.access_token;
|
|
1018
|
+
// src/auth/internal/default-auth-modules/none.ts
|
|
1019
|
+
function getRestCallAuthParams4() {
|
|
1020
|
+
return Promise.resolve({ headers: {}, queryParams: {}, credentials: "same-origin" });
|
|
1067
1021
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1022
|
+
function getWebSocketAuthParams4() {
|
|
1023
|
+
return Promise.resolve({ queryParams: {} });
|
|
1024
|
+
}
|
|
1025
|
+
function handleAuthenticationError4() {
|
|
1026
|
+
return Promise.resolve({});
|
|
1027
|
+
}
|
|
1028
|
+
var none_default = {
|
|
1029
|
+
requiredProps: [],
|
|
1030
|
+
optionalProps: [],
|
|
1031
|
+
getRestCallAuthParams: getRestCallAuthParams4,
|
|
1032
|
+
getWebSocketAuthParams: getWebSocketAuthParams4,
|
|
1033
|
+
handleAuthenticationError: handleAuthenticationError4
|
|
1034
|
+
};
|
|
1035
|
+
|
|
1036
|
+
// src/auth/internal/default-auth-modules/oauth/callback.ts
|
|
1037
|
+
function handleOAuthCallback() {
|
|
1038
|
+
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
1039
|
+
const callbackCode = urlParams.get("code") || void 0;
|
|
1040
|
+
const callbackState = urlParams.get("state") || void 0;
|
|
1041
|
+
if (urlParams.get("error")) {
|
|
1042
|
+
const element = document.createElement("pre");
|
|
1043
|
+
element.innerText = `<code>${JSON.stringify({
|
|
1044
|
+
error: urlParams.get("error"),
|
|
1045
|
+
error_code: urlParams.get("error_code"),
|
|
1046
|
+
error_description: urlParams.get("error_description"),
|
|
1047
|
+
error_detail: urlParams.get("error_detail"),
|
|
1048
|
+
error_uri: urlParams.get("error_uri")
|
|
1049
|
+
})}</code>`;
|
|
1050
|
+
document.body.prepend(element);
|
|
1051
|
+
}
|
|
1052
|
+
const topic = loadAndDeleteFromSessionStorage("", "client-in-progress");
|
|
1053
|
+
if (topic && callbackCode && callbackState) {
|
|
1054
|
+
const stateFromLocalStorage = loadAndDeleteFromSessionStorage(topic, "state");
|
|
1055
|
+
const finalRedirectUri = loadAndDeleteFromSessionStorage(topic, "href");
|
|
1056
|
+
if (stateFromLocalStorage && stateFromLocalStorage === callbackState && finalRedirectUri) {
|
|
1057
|
+
saveInSessionStorage(topic, "code", callbackCode);
|
|
1058
|
+
if (finalRedirectUri !== globalThis.location.href) {
|
|
1059
|
+
globalThis.location.replace(finalRedirectUri);
|
|
1080
1060
|
}
|
|
1081
|
-
|
|
1061
|
+
}
|
|
1082
1062
|
}
|
|
1083
1063
|
}
|
|
1084
1064
|
|
|
1085
|
-
// src/auth/internal/default-auth-modules/
|
|
1086
|
-
|
|
1065
|
+
// src/auth/internal/default-auth-modules/oauth.ts
|
|
1066
|
+
if (isBrowser()) {
|
|
1067
|
+
handleOAuthCallback();
|
|
1068
|
+
}
|
|
1069
|
+
async function handlePotentialAuthenticationErrorAndRetry2(hostConfig, fn) {
|
|
1087
1070
|
try {
|
|
1088
1071
|
return await fn();
|
|
1089
1072
|
} catch (err) {
|
|
1090
|
-
const { retry } = await
|
|
1073
|
+
const { retry } = await handleAuthenticationError5({
|
|
1091
1074
|
hostConfig,
|
|
1092
1075
|
canRetry: true
|
|
1093
1076
|
});
|
|
@@ -1097,518 +1080,586 @@ async function handlePotentialAuthenticationErrorAndRetry(hostConfig, fn) {
|
|
|
1097
1080
|
throw err;
|
|
1098
1081
|
}
|
|
1099
1082
|
}
|
|
1100
|
-
async function
|
|
1101
|
-
|
|
1083
|
+
async function getRestCallAuthParams5({
|
|
1084
|
+
hostConfig
|
|
1085
|
+
}) {
|
|
1086
|
+
return {
|
|
1087
|
+
headers: {
|
|
1088
|
+
Authorization: `Bearer ${await getOAuthAccessToken(hostConfig)}`
|
|
1089
|
+
},
|
|
1090
|
+
queryParams: {},
|
|
1091
|
+
credentials: "omit"
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
async function getWebSocketAuthParams5({
|
|
1095
|
+
hostConfig
|
|
1096
|
+
}) {
|
|
1097
|
+
const websocketAccessToken = await handlePotentialAuthenticationErrorAndRetry2(hostConfig, async () => {
|
|
1098
|
+
const accessToken = await getOAuthAccessToken(hostConfig);
|
|
1099
|
+
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "websocket");
|
|
1100
|
+
});
|
|
1101
|
+
return {
|
|
1102
|
+
queryParams: {
|
|
1103
|
+
accessToken: websocketAccessToken
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1107
|
+
async function getWebResourceAuthParams2({
|
|
1108
|
+
hostConfig
|
|
1109
|
+
}) {
|
|
1110
|
+
const webResourceAccessToken = await handlePotentialAuthenticationErrorAndRetry2(hostConfig, async () => {
|
|
1111
|
+
const accessToken = await getOAuthAccessToken(hostConfig);
|
|
1112
|
+
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "webresource");
|
|
1113
|
+
});
|
|
1114
|
+
return {
|
|
1115
|
+
queryParams: {
|
|
1116
|
+
accessToken: webResourceAccessToken
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
async function handleAuthenticationError5({
|
|
1121
|
+
hostConfig
|
|
1122
|
+
}) {
|
|
1123
|
+
if (hostConfig.getAccessToken) {
|
|
1124
|
+
clearStoredOauthTokens(hostConfig);
|
|
1125
|
+
return {
|
|
1126
|
+
preventDefault: false,
|
|
1127
|
+
retry: true
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1102
1130
|
if (isBrowser()) {
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1131
|
+
if (hostConfig.performInteractiveLogin) {
|
|
1132
|
+
clearStoredOauthTokens(hostConfig);
|
|
1133
|
+
return {
|
|
1134
|
+
retry: true
|
|
1135
|
+
};
|
|
1107
1136
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1137
|
+
if (hostConfig.authRedirectUserConfirmation) {
|
|
1138
|
+
await hostConfig.authRedirectUserConfirmation();
|
|
1139
|
+
}
|
|
1140
|
+
startFullPageLoginFlow(hostConfig);
|
|
1141
|
+
return {
|
|
1142
|
+
preventDefault: true
|
|
1143
|
+
};
|
|
1111
1144
|
}
|
|
1112
|
-
|
|
1145
|
+
await refreshAccessToken(hostConfig);
|
|
1146
|
+
return {
|
|
1147
|
+
preventDefault: false,
|
|
1148
|
+
retry: true
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
var oauth_default = {
|
|
1152
|
+
requiredProps: ["clientId"],
|
|
1153
|
+
optionalProps: [
|
|
1154
|
+
"clientSecret",
|
|
1155
|
+
"redirectUri",
|
|
1156
|
+
"accessTokenStorage",
|
|
1157
|
+
"scope",
|
|
1158
|
+
"subject",
|
|
1159
|
+
"userId",
|
|
1160
|
+
"noCache",
|
|
1161
|
+
"getAccessToken",
|
|
1162
|
+
"performInteractiveLogin"
|
|
1163
|
+
],
|
|
1164
|
+
getRestCallAuthParams: getRestCallAuthParams5,
|
|
1165
|
+
getWebSocketAuthParams: getWebSocketAuthParams5,
|
|
1166
|
+
getWebResourceAuthParams: getWebResourceAuthParams2,
|
|
1167
|
+
handleAuthenticationError: handleAuthenticationError5
|
|
1168
|
+
};
|
|
1169
|
+
|
|
1170
|
+
// src/auth/internal/default-auth-modules/reference.ts
|
|
1171
|
+
function getRestCallAuthParams6() {
|
|
1172
|
+
throw new Error("getRestCallAuthParams should never be called for reference auth module");
|
|
1113
1173
|
}
|
|
1114
|
-
function
|
|
1115
|
-
|
|
1116
|
-
const randomString = generateRandomHexString(40 - timeStamp.length);
|
|
1117
|
-
return `${timeStamp}${randomString}`;
|
|
1174
|
+
function getWebSocketAuthParams6() {
|
|
1175
|
+
throw new Error("getWebSocketAuthParams should never be called for reference auth module");
|
|
1118
1176
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1177
|
+
function handleAuthenticationError6() {
|
|
1178
|
+
throw new Error("handleAuthenticationError should never be called for reference auth module");
|
|
1179
|
+
}
|
|
1180
|
+
var reference_default = {
|
|
1181
|
+
requiredProps: ["reference"],
|
|
1182
|
+
optionalProps: [],
|
|
1183
|
+
getRestCallAuthParams: getRestCallAuthParams6,
|
|
1184
|
+
getWebSocketAuthParams: getWebSocketAuthParams6,
|
|
1185
|
+
handleAuthenticationError: handleAuthenticationError6
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
// src/auth/internal/default-auth-modules/windows-cookie/xrf-keys.ts
|
|
1189
|
+
var xrfKeys = {};
|
|
1190
|
+
function createXrfKey() {
|
|
1191
|
+
let result2 = "";
|
|
1192
|
+
for (let i = 0; i < 16; i += 1) {
|
|
1193
|
+
const j = Math.floor(Math.random() * 62);
|
|
1194
|
+
if (j < 10) {
|
|
1195
|
+
result2 += j;
|
|
1196
|
+
} else if (j > 9 && j < 36) {
|
|
1197
|
+
result2 += String.fromCharCode(j + 55);
|
|
1198
|
+
} else {
|
|
1199
|
+
result2 += String.fromCharCode(j + 61);
|
|
1200
|
+
}
|
|
1139
1201
|
}
|
|
1140
|
-
return
|
|
1202
|
+
return result2;
|
|
1203
|
+
}
|
|
1204
|
+
function getXrfKey(hostConfig) {
|
|
1205
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
1206
|
+
xrfKeys[locationUrl] = xrfKeys[locationUrl] || createXrfKey();
|
|
1207
|
+
return xrfKeys[locationUrl];
|
|
1141
1208
|
}
|
|
1142
|
-
|
|
1209
|
+
|
|
1210
|
+
// src/auth/internal/default-auth-modules/windows-cookie.ts
|
|
1211
|
+
async function getRestCallAuthParams7({
|
|
1143
1212
|
hostConfig
|
|
1144
1213
|
}) {
|
|
1145
1214
|
return {
|
|
1146
1215
|
headers: {
|
|
1147
|
-
|
|
1216
|
+
"X-Qlik-XrfKey": getXrfKey(hostConfig)
|
|
1148
1217
|
},
|
|
1149
|
-
queryParams: {},
|
|
1150
|
-
credentials: "omit"
|
|
1151
|
-
};
|
|
1152
|
-
}
|
|
1153
|
-
async function getWebSocketAuthParams2({
|
|
1154
|
-
hostConfig
|
|
1155
|
-
}) {
|
|
1156
|
-
const websocketAccessToken = await handlePotentialAuthenticationErrorAndRetry(hostConfig, async () => {
|
|
1157
|
-
const accessToken = await getAnonymousAccessToken(hostConfig);
|
|
1158
|
-
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "websocket");
|
|
1159
|
-
});
|
|
1160
|
-
return {
|
|
1161
1218
|
queryParams: {
|
|
1162
|
-
|
|
1163
|
-
}
|
|
1219
|
+
xrfkey: getXrfKey(hostConfig)
|
|
1220
|
+
},
|
|
1221
|
+
credentials: internalGetCredentialsForCookieAuth(hostConfig)
|
|
1164
1222
|
};
|
|
1165
1223
|
}
|
|
1166
|
-
async function
|
|
1224
|
+
async function getWebSocketAuthParams7({
|
|
1167
1225
|
hostConfig
|
|
1168
1226
|
}) {
|
|
1169
|
-
const websocketResourceAccessToken = await handlePotentialAuthenticationErrorAndRetry(hostConfig, async () => {
|
|
1170
|
-
const accessToken = await getAnonymousAccessToken(hostConfig);
|
|
1171
|
-
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "websocket");
|
|
1172
|
-
});
|
|
1173
1227
|
return {
|
|
1174
1228
|
queryParams: {
|
|
1175
|
-
|
|
1229
|
+
xrfkey: getXrfKey(hostConfig),
|
|
1230
|
+
"qlik-csrf-token": await getCsrfToken(hostConfig, true)
|
|
1176
1231
|
}
|
|
1177
1232
|
};
|
|
1178
1233
|
}
|
|
1179
|
-
async function
|
|
1234
|
+
async function handleAuthenticationError7({
|
|
1180
1235
|
hostConfig
|
|
1181
1236
|
}) {
|
|
1182
|
-
|
|
1237
|
+
if (hostConfig.loginUri) {
|
|
1238
|
+
if (hostConfig.authRedirectUserConfirmation) {
|
|
1239
|
+
await hostConfig.authRedirectUserConfirmation();
|
|
1240
|
+
}
|
|
1241
|
+
globalThis.location.replace(
|
|
1242
|
+
hostConfig.loginUri.replace("{location}", encodeURIComponent(globalThis.location.href))
|
|
1243
|
+
);
|
|
1244
|
+
return {
|
|
1245
|
+
preventDefault: true
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1183
1248
|
return {
|
|
1184
|
-
|
|
1185
|
-
retry: true
|
|
1249
|
+
// Do nothing, just let the error be thrown to calling code
|
|
1186
1250
|
};
|
|
1187
1251
|
}
|
|
1188
|
-
var
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
requiredProps: ["clientId", "accessCode"],
|
|
1195
|
-
optionalProps: []
|
|
1196
|
-
})
|
|
1252
|
+
var windows_cookie_default = {
|
|
1253
|
+
requiredProps: [],
|
|
1254
|
+
optionalProps: ["loginUri", "crossSiteCookies"],
|
|
1255
|
+
getRestCallAuthParams: getRestCallAuthParams7,
|
|
1256
|
+
getWebSocketAuthParams: getWebSocketAuthParams7,
|
|
1257
|
+
handleAuthenticationError: handleAuthenticationError7
|
|
1197
1258
|
};
|
|
1198
1259
|
|
|
1199
|
-
// src/auth/internal/
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1260
|
+
// src/auth/internal/auth-module-registry.ts
|
|
1261
|
+
var authModules = {};
|
|
1262
|
+
var ongoingAuthModuleLoading = Promise.resolve();
|
|
1263
|
+
var authModulesRegistered = false;
|
|
1264
|
+
(function registerDefaultAuthModules() {
|
|
1265
|
+
if (!authModulesRegistered) {
|
|
1266
|
+
registerAuthModule("apikey", apikey_default);
|
|
1267
|
+
registerAuthModule("cookie", cookie_default);
|
|
1268
|
+
registerAuthModule("none", none_default);
|
|
1269
|
+
registerAuthModule("oauth2", oauth_default);
|
|
1270
|
+
registerAuthModule("anonymous", anonymous_default);
|
|
1271
|
+
registerAuthModule("windowscookie", windows_cookie_default);
|
|
1272
|
+
registerAuthModule("reference", reference_default);
|
|
1273
|
+
authModulesRegistered = true;
|
|
1274
|
+
}
|
|
1275
|
+
})();
|
|
1276
|
+
function registerAuthModule(name, authModule) {
|
|
1277
|
+
authModules[name.toLowerCase()] = authModule;
|
|
1278
|
+
}
|
|
1279
|
+
function getRegisteredAuthModules() {
|
|
1280
|
+
return Object.keys(authModules);
|
|
1281
|
+
}
|
|
1282
|
+
function getRegisteredAuthModule(authType) {
|
|
1283
|
+
return authModules[authType.toLowerCase()];
|
|
1284
|
+
}
|
|
1285
|
+
async function getAuthModule(hostConfig) {
|
|
1286
|
+
const hostConfigToUse = withResolvedHostConfig(hostConfig);
|
|
1287
|
+
const authType = await determineAuthType(hostConfigToUse);
|
|
1288
|
+
if (ongoingAuthModuleLoading) {
|
|
1289
|
+
await ongoingAuthModuleLoading;
|
|
1290
|
+
}
|
|
1291
|
+
let authModule = getRegisteredAuthModule(authType);
|
|
1292
|
+
if (!authModule) {
|
|
1293
|
+
ongoingAuthModuleLoading = (async () => {
|
|
1294
|
+
authModule = await resolveGloballyDefinedAuthModule(authType);
|
|
1295
|
+
if (authModule) {
|
|
1296
|
+
registerAuthModule(authType, authModule);
|
|
1297
|
+
}
|
|
1298
|
+
})();
|
|
1299
|
+
await ongoingAuthModuleLoading;
|
|
1300
|
+
}
|
|
1301
|
+
if (!authModule) {
|
|
1302
|
+
throw new InvalidAuthTypeError(authType);
|
|
1303
|
+
}
|
|
1304
|
+
if (authModule.validateHostConfig) {
|
|
1305
|
+
authModule.validateHostConfig({ authType, ...hostConfigToUse });
|
|
1306
|
+
} else {
|
|
1307
|
+
internalValidateHostConfig(
|
|
1308
|
+
{ authType, ...hostConfigToUse },
|
|
1309
|
+
{ requiredProps: authModule.requiredProps || [], optionalProps: authModule.optionalProps || [] }
|
|
1310
|
+
);
|
|
1311
|
+
}
|
|
1312
|
+
return authModule;
|
|
1313
|
+
}
|
|
1314
|
+
async function resolveGloballyDefinedAuthModule(authType) {
|
|
1315
|
+
const globalWindow = globalThis;
|
|
1316
|
+
const globalVariable = globalWindow[authType];
|
|
1317
|
+
if (globalVariable) {
|
|
1318
|
+
let potentialAuthModule;
|
|
1319
|
+
if (typeof globalVariable === "function") {
|
|
1320
|
+
potentialAuthModule = await globalVariable();
|
|
1321
|
+
} else {
|
|
1322
|
+
potentialAuthModule = globalVariable;
|
|
1323
|
+
}
|
|
1324
|
+
if (potentialAuthModule && potentialAuthModule.getRestCallAuthParams && potentialAuthModule.getWebSocketAuthParams && potentialAuthModule.handleAuthenticationError) {
|
|
1325
|
+
return potentialAuthModule;
|
|
1326
|
+
}
|
|
1327
|
+
console.error("Not a valid auth module", potentialAuthModule);
|
|
1328
|
+
throw new InvalidAuthTypeError(authType);
|
|
1329
|
+
}
|
|
1330
|
+
return Promise.resolve(void 0);
|
|
1331
|
+
}
|
|
1332
|
+
function internalValidateHostConfig(hostConfig, { requiredProps, optionalProps }) {
|
|
1333
|
+
const missingRequiredProps = [];
|
|
1334
|
+
for (const requiredProp of requiredProps) {
|
|
1335
|
+
if (!hostConfig[requiredProp]) {
|
|
1336
|
+
missingRequiredProps.push(requiredProp);
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
if (missingRequiredProps.length > 0) {
|
|
1340
|
+
throw new InvalidHostConfigError(
|
|
1341
|
+
`missing required properties in host config; '${missingRequiredProps.join("', '")}'`
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
const validProps = [...hostConfigCommonProperties, ...requiredProps, ...optionalProps];
|
|
1345
|
+
const invalidKeys = [];
|
|
1346
|
+
Object.keys(hostConfig).forEach((key) => {
|
|
1347
|
+
if (!validProps.includes(key)) {
|
|
1348
|
+
invalidKeys.push(key);
|
|
1349
|
+
}
|
|
1207
1350
|
});
|
|
1351
|
+
if (invalidKeys.length > 0) {
|
|
1352
|
+
console.warn(`WARNING: unknown properties in host config; '${invalidKeys.join("', '")}'`);
|
|
1353
|
+
}
|
|
1354
|
+
return true;
|
|
1208
1355
|
}
|
|
1209
|
-
async function
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1356
|
+
async function determineAuthType(hostConfig) {
|
|
1357
|
+
if (hostConfig.authType) {
|
|
1358
|
+
return hostConfig.authType;
|
|
1359
|
+
}
|
|
1360
|
+
if (hostConfig.apiKey) {
|
|
1361
|
+
return "apikey";
|
|
1362
|
+
}
|
|
1363
|
+
if (hostConfig.accessCode) {
|
|
1364
|
+
return "anonymous";
|
|
1365
|
+
}
|
|
1366
|
+
if (hostConfig.clientId) {
|
|
1367
|
+
return "oauth2";
|
|
1368
|
+
}
|
|
1369
|
+
if (hostConfig.webIntegrationId) {
|
|
1370
|
+
return "cookie";
|
|
1371
|
+
}
|
|
1372
|
+
if (hostConfig.reference) {
|
|
1373
|
+
return "reference";
|
|
1374
|
+
}
|
|
1375
|
+
if (await isWindows(hostConfig)) {
|
|
1376
|
+
return "windowscookie";
|
|
1377
|
+
}
|
|
1378
|
+
return "cookie";
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
// src/auth/auth-errors.ts
|
|
1382
|
+
var InvalidHostConfigError = class extends Error {
|
|
1383
|
+
constructor(message) {
|
|
1384
|
+
super(`Invalid host config: ${message}`);
|
|
1385
|
+
this.name = "InvalidHostConfigError";
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
var UnexpectedAuthTypeError = class extends Error {
|
|
1389
|
+
constructor(...expectedAuthTypes) {
|
|
1390
|
+
const ors = expectedAuthTypes.map((item, index) => index === 0 ? `"${item}"` : `or "${item}"`).join(" ");
|
|
1391
|
+
super(`HostConfig is not properly configured. authType is expected to be ${ors}`);
|
|
1392
|
+
this.name = "UnexpectedAuthTypeError";
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
var InvalidAuthTypeError = class extends Error {
|
|
1396
|
+
constructor(authType) {
|
|
1397
|
+
const validAuthModules = getRegisteredAuthModules();
|
|
1398
|
+
super(
|
|
1399
|
+
`Not a valid auth type: ${authType}, valid auth types are; '${validAuthModules.filter((name) => name.toLowerCase() !== "qmfeembedframerauthmodule").join("', '")}'`
|
|
1400
|
+
);
|
|
1401
|
+
this.name = "InvalidAuthTypeError";
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
function errorToString({ title, detail, code, status }) {
|
|
1405
|
+
if (detail) {
|
|
1406
|
+
return `${title} - ${detail} (Status: ${status}, Code: ${code})`;
|
|
1407
|
+
}
|
|
1408
|
+
return `${title} (Status: ${status}, Code: ${code})`;
|
|
1409
|
+
}
|
|
1410
|
+
var AuthorizationError = class extends Error {
|
|
1411
|
+
errors;
|
|
1412
|
+
constructor(errors) {
|
|
1413
|
+
if (typeof errors !== "object") {
|
|
1414
|
+
super("Unknown error");
|
|
1415
|
+
return;
|
|
1213
1416
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
}
|
|
1219
|
-
var apikey_default = {
|
|
1220
|
-
getRestCallAuthParams: getRestCallAuthParams3,
|
|
1221
|
-
getWebSocketAuthParams: getWebSocketAuthParams3,
|
|
1222
|
-
handleAuthenticationError: handleAuthenticationError3,
|
|
1223
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: ["apiKey"], optionalProps: [] })
|
|
1417
|
+
const errorArray = Array.isArray(errors) ? errors : [errors];
|
|
1418
|
+
super(errorArray.map(errorToString).join(", "));
|
|
1419
|
+
this.errors = errorArray;
|
|
1420
|
+
}
|
|
1224
1421
|
};
|
|
1225
1422
|
|
|
1226
|
-
// src/
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
}
|
|
1232
|
-
async function getCsrfToken(hostConfig, noCache) {
|
|
1233
|
-
const locationUrl = toValidLocationUrl(hostConfig);
|
|
1234
|
-
let pathTemplate;
|
|
1235
|
-
if (await isWindows(hostConfig)) {
|
|
1236
|
-
pathTemplate = "/qps/csrftoken";
|
|
1237
|
-
} else {
|
|
1238
|
-
pathTemplate = "/api/v1/csrf-token";
|
|
1423
|
+
// src/auth/internal/host-config-functions.ts
|
|
1424
|
+
function removeDefaults(hostConfig) {
|
|
1425
|
+
const cleanedHostConfig = cleanFalsyValues(hostConfig) || {};
|
|
1426
|
+
if (cleanedHostConfig.host) {
|
|
1427
|
+
cleanedHostConfig.host = toValidLocationUrl(cleanedHostConfig);
|
|
1239
1428
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
method: "get",
|
|
1244
|
-
pathTemplate,
|
|
1245
|
-
options: {
|
|
1246
|
-
hostConfig,
|
|
1247
|
-
noCache: true
|
|
1248
|
-
}
|
|
1249
|
-
});
|
|
1250
|
-
const csrfToken = res.headers.get(QLIK_CSRF_TOKEN);
|
|
1251
|
-
if (!csrfToken) {
|
|
1252
|
-
return "";
|
|
1253
|
-
}
|
|
1254
|
-
return csrfToken;
|
|
1255
|
-
} catch (e) {
|
|
1256
|
-
const error = e;
|
|
1257
|
-
if (error.status === 404) {
|
|
1258
|
-
return "";
|
|
1259
|
-
}
|
|
1260
|
-
throw e;
|
|
1429
|
+
if (isBrowser()) {
|
|
1430
|
+
if (toValidLocationUrl(cleanedHostConfig) === window.location.origin) {
|
|
1431
|
+
delete cleanedHostConfig.host;
|
|
1261
1432
|
}
|
|
1262
|
-
};
|
|
1263
|
-
if (noCache) {
|
|
1264
|
-
csrfTokens[locationUrl] = fetchCsrfToken();
|
|
1265
|
-
return csrfTokens[locationUrl];
|
|
1266
1433
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1434
|
+
if (cleanedHostConfig.authType && authTypesThatCanBeOmitted.includes(cleanedHostConfig.authType)) {
|
|
1435
|
+
delete cleanedHostConfig.authType;
|
|
1436
|
+
}
|
|
1437
|
+
return cleanedHostConfig;
|
|
1269
1438
|
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
return
|
|
1439
|
+
function globalReplacer(key, value) {
|
|
1440
|
+
if (typeof value === "function") {
|
|
1441
|
+
return void 0;
|
|
1442
|
+
}
|
|
1443
|
+
return value;
|
|
1275
1444
|
}
|
|
1276
|
-
|
|
1277
|
-
hostConfig
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1445
|
+
function serializeHostConfig(hostConfig) {
|
|
1446
|
+
const hostConfigToUse = removeDefaults(withResolvedHostConfig(hostConfig));
|
|
1447
|
+
const sorted = sortKeys(hostConfigToUse);
|
|
1448
|
+
return JSON.stringify(sorted, globalReplacer);
|
|
1449
|
+
}
|
|
1450
|
+
var registeredHostConfigs = /* @__PURE__ */ new Map();
|
|
1451
|
+
function registerHostConfig(name, hostConfig) {
|
|
1452
|
+
if (hostConfig?.reference) {
|
|
1453
|
+
throw new InvalidHostConfigError("Cannot register a host config with a reference");
|
|
1283
1454
|
}
|
|
1284
|
-
if (
|
|
1285
|
-
|
|
1455
|
+
if (registeredHostConfigs.has(name)) {
|
|
1456
|
+
console.warn(`registerHostConfig: Host config with name "${name}" is already registered. Overwriting.`);
|
|
1286
1457
|
}
|
|
1287
|
-
|
|
1458
|
+
registeredHostConfigs.set(name, hostConfig);
|
|
1288
1459
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
"qlik-csrf-token": await getCsrfToken(hostConfig, true)
|
|
1295
|
-
};
|
|
1296
|
-
if (hostConfig.webIntegrationId) {
|
|
1297
|
-
params["qlik-web-integration-id"] = hostConfig.webIntegrationId;
|
|
1460
|
+
function unregisterHostConfig(name) {
|
|
1461
|
+
if (registeredHostConfigs.has(name)) {
|
|
1462
|
+
registeredHostConfigs.delete(name);
|
|
1463
|
+
} else {
|
|
1464
|
+
console.warn(`unregisterHostConfig: Host config with name "${name}" not found.`);
|
|
1298
1465
|
}
|
|
1299
|
-
return { queryParams: params };
|
|
1300
1466
|
}
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
retry: true
|
|
1310
|
-
};
|
|
1311
|
-
}
|
|
1312
|
-
const webIntegrationParam = hostConfig.webIntegrationId ? `qlik-web-integration-id=${hostConfig?.webIntegrationId}&` : "";
|
|
1313
|
-
const locationUrl = toValidLocationUrl(hostConfig);
|
|
1314
|
-
if (hostConfig.authRedirectUserConfirmation) {
|
|
1315
|
-
await hostConfig.authRedirectUserConfirmation();
|
|
1316
|
-
}
|
|
1317
|
-
globalThis.location.replace(
|
|
1318
|
-
`${locationUrl}/login?${webIntegrationParam}returnto=${encodeURIComponent(globalThis.location.href)}`
|
|
1319
|
-
);
|
|
1320
|
-
return {
|
|
1321
|
-
preventDefault: true
|
|
1322
|
-
};
|
|
1467
|
+
function getRegisteredHostConfig(name) {
|
|
1468
|
+
return registeredHostConfigs.get(name);
|
|
1469
|
+
}
|
|
1470
|
+
function setDefaultHostConfig(hostConfig) {
|
|
1471
|
+
registerHostConfig("default", hostConfig || {});
|
|
1472
|
+
}
|
|
1473
|
+
function getDefaultHostConfig() {
|
|
1474
|
+
return getRegisteredHostConfig("default") || {};
|
|
1323
1475
|
}
|
|
1324
|
-
var cookie_default = {
|
|
1325
|
-
getRestCallAuthParams: getRestCallAuthParams4,
|
|
1326
|
-
getWebSocketAuthParams: getWebSocketAuthParams4,
|
|
1327
|
-
handleAuthenticationError: handleAuthenticationError4,
|
|
1328
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
1329
|
-
requiredProps: [],
|
|
1330
|
-
optionalProps: ["webIntegrationId", "crossSiteCookies", "anonymousMode"]
|
|
1331
|
-
})
|
|
1332
|
-
};
|
|
1333
1476
|
|
|
1334
|
-
// src/auth/
|
|
1335
|
-
|
|
1336
|
-
|
|
1477
|
+
// src/auth/auth-functions.ts
|
|
1478
|
+
globalThis.loggingOut = false;
|
|
1479
|
+
var lastErrorMessage = "";
|
|
1480
|
+
function logToConsole({ message }) {
|
|
1481
|
+
if (message !== lastErrorMessage) {
|
|
1482
|
+
lastErrorMessage = message;
|
|
1483
|
+
console.error(message);
|
|
1484
|
+
}
|
|
1337
1485
|
}
|
|
1338
|
-
function
|
|
1339
|
-
return
|
|
1486
|
+
function determineAuthType2(hostConfig) {
|
|
1487
|
+
return determineAuthType(hostConfig);
|
|
1340
1488
|
}
|
|
1341
|
-
function
|
|
1342
|
-
|
|
1489
|
+
function isHostCrossOrigin(hostConfig) {
|
|
1490
|
+
if (!globalThis.location?.origin) {
|
|
1491
|
+
return true;
|
|
1492
|
+
}
|
|
1493
|
+
const hostConfigToUse = withResolvedHostConfig(hostConfig);
|
|
1494
|
+
if (Object.keys(hostConfigToUse).length === 0) {
|
|
1495
|
+
return false;
|
|
1496
|
+
}
|
|
1497
|
+
try {
|
|
1498
|
+
const locationUrl = new URL(toValidLocationUrl(hostConfigToUse));
|
|
1499
|
+
return locationUrl.origin !== globalThis.location.origin;
|
|
1500
|
+
} catch {
|
|
1501
|
+
}
|
|
1502
|
+
return false;
|
|
1343
1503
|
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: [], optionalProps: [] })
|
|
1349
|
-
};
|
|
1350
|
-
|
|
1351
|
-
// src/auth/internal/default-auth-modules/oauth/callback.ts
|
|
1352
|
-
function handleOAuthCallback() {
|
|
1353
|
-
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
1354
|
-
const callbackCode = urlParams.get("code") || void 0;
|
|
1355
|
-
const callbackState = urlParams.get("state") || void 0;
|
|
1356
|
-
if (urlParams.get("error")) {
|
|
1357
|
-
const element = document.createElement("pre");
|
|
1358
|
-
element.innerText = `<code>${JSON.stringify({
|
|
1359
|
-
error: urlParams.get("error"),
|
|
1360
|
-
error_code: urlParams.get("error_code"),
|
|
1361
|
-
error_description: urlParams.get("error_description"),
|
|
1362
|
-
error_detail: urlParams.get("error_detail"),
|
|
1363
|
-
error_uri: urlParams.get("error_uri")
|
|
1364
|
-
})}</code>`;
|
|
1365
|
-
document.body.prepend(element);
|
|
1504
|
+
async function isWindows(hostConfig) {
|
|
1505
|
+
const hostConfigToUse = withResolvedHostConfig(hostConfig);
|
|
1506
|
+
if (typeof hostConfigToUse.forceIsWindows === "boolean") {
|
|
1507
|
+
return hostConfigToUse.forceIsWindows;
|
|
1366
1508
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
saveInSessionStorage(topic, "code", callbackCode);
|
|
1373
|
-
if (finalRedirectUri !== globalThis.location.href) {
|
|
1374
|
-
globalThis.location.replace(finalRedirectUri);
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1509
|
+
if (hostConfigToUse.authType === "cookie") {
|
|
1510
|
+
return false;
|
|
1511
|
+
}
|
|
1512
|
+
if (hostConfigToUse.authType === "windowscookie") {
|
|
1513
|
+
return true;
|
|
1377
1514
|
}
|
|
1515
|
+
return (await getPlatform({ hostConfig })).isWindows;
|
|
1378
1516
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1517
|
+
function toValidLocationUrl(hostConfig) {
|
|
1518
|
+
const url = withResolvedHostConfig(hostConfig)?.host?.trim();
|
|
1519
|
+
let locationUrl;
|
|
1520
|
+
if (!url) {
|
|
1521
|
+
locationUrl = "";
|
|
1522
|
+
} else if (url.toLowerCase().startsWith("https://") || url.toLowerCase().startsWith("http://")) {
|
|
1523
|
+
locationUrl = url;
|
|
1524
|
+
} else {
|
|
1525
|
+
locationUrl = `https://${url}`;
|
|
1526
|
+
}
|
|
1527
|
+
while (locationUrl[locationUrl.length - 1] === "/") {
|
|
1528
|
+
locationUrl = locationUrl.substring(0, locationUrl.length - 1);
|
|
1529
|
+
}
|
|
1530
|
+
return locationUrl;
|
|
1383
1531
|
}
|
|
1384
|
-
|
|
1532
|
+
function toValidWebsocketLocationUrl(hostConfig) {
|
|
1533
|
+
const url = withResolvedHostConfig(hostConfig)?.host;
|
|
1534
|
+
let locationUrl;
|
|
1535
|
+
if (!url) {
|
|
1536
|
+
locationUrl = globalThis.location.origin;
|
|
1537
|
+
} else if (url.toLowerCase().startsWith("https://") || url.toLowerCase().startsWith("http://")) {
|
|
1538
|
+
locationUrl = url;
|
|
1539
|
+
} else {
|
|
1540
|
+
locationUrl = `https://${url}`;
|
|
1541
|
+
}
|
|
1542
|
+
while (locationUrl[locationUrl.length - 1] === "/") {
|
|
1543
|
+
locationUrl = locationUrl.substring(0, locationUrl.length - 1);
|
|
1544
|
+
}
|
|
1545
|
+
return locationUrl.replace(leadingHttp, "ws");
|
|
1546
|
+
}
|
|
1547
|
+
async function getWebSocketAuthParams8(props) {
|
|
1548
|
+
const hostConfigToUse = withResolvedHostConfig(props.hostConfig);
|
|
1385
1549
|
try {
|
|
1386
|
-
|
|
1550
|
+
const authModule = await getAuthModule(hostConfigToUse);
|
|
1551
|
+
return await authModule.getWebSocketAuthParams({
|
|
1552
|
+
...props,
|
|
1553
|
+
hostConfig: hostConfigToUse
|
|
1554
|
+
});
|
|
1387
1555
|
} catch (err) {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1556
|
+
(hostConfigToUse.onAuthFailed || logToConsole)(normalizeAuthModuleError(err));
|
|
1557
|
+
throw err;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
async function getWebResourceAuthParams3(props) {
|
|
1561
|
+
const hostConfigToUse = withResolvedHostConfig(props.hostConfig);
|
|
1562
|
+
try {
|
|
1563
|
+
const authModule = await getAuthModule(hostConfigToUse);
|
|
1564
|
+
return await authModule.getWebResourceAuthParams?.({
|
|
1565
|
+
...props,
|
|
1566
|
+
hostConfig: hostConfigToUse
|
|
1567
|
+
}) || { queryParams: {} };
|
|
1568
|
+
} catch (err) {
|
|
1569
|
+
(hostConfigToUse.onAuthFailed || logToConsole)(normalizeAuthModuleError(err));
|
|
1570
|
+
throw err;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
async function handleAuthenticationError8(props) {
|
|
1574
|
+
const hostConfigToUse = withResolvedHostConfig(props.hostConfig);
|
|
1575
|
+
const authModule = await getAuthModule(hostConfigToUse);
|
|
1576
|
+
const result2 = await authModule.handleAuthenticationError({
|
|
1577
|
+
...props,
|
|
1578
|
+
hostConfig: hostConfigToUse
|
|
1579
|
+
});
|
|
1580
|
+
const willRetry = props.canRetry && result2.retry;
|
|
1581
|
+
const willHangUntilANewPageIsLoaded = result2.preventDefault;
|
|
1582
|
+
if (!willRetry && !willHangUntilANewPageIsLoaded) {
|
|
1583
|
+
const { status, errorBody } = props;
|
|
1584
|
+
(hostConfigToUse.onAuthFailed || logToConsole)(normalizeInbandAuthError({ status, errorBody }));
|
|
1585
|
+
}
|
|
1586
|
+
return result2;
|
|
1587
|
+
}
|
|
1588
|
+
async function getRestCallAuthParams8(props) {
|
|
1589
|
+
const hostConfigToUse = withResolvedHostConfig(props.hostConfig);
|
|
1590
|
+
try {
|
|
1591
|
+
const authModule = await getAuthModule(hostConfigToUse);
|
|
1592
|
+
return await authModule.getRestCallAuthParams({
|
|
1593
|
+
...props,
|
|
1594
|
+
hostConfig: hostConfigToUse
|
|
1391
1595
|
});
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
}
|
|
1596
|
+
} catch (err) {
|
|
1597
|
+
(hostConfigToUse.onAuthFailed || logToConsole)(normalizeAuthModuleError(err));
|
|
1395
1598
|
throw err;
|
|
1396
1599
|
}
|
|
1397
1600
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
}) {
|
|
1401
|
-
return {
|
|
1402
|
-
headers: {
|
|
1403
|
-
Authorization: `Bearer ${await getOAuthAccessToken(hostConfig)}`
|
|
1404
|
-
},
|
|
1405
|
-
queryParams: {},
|
|
1406
|
-
credentials: "omit"
|
|
1407
|
-
};
|
|
1601
|
+
function registerAuthModule2(name, authModule) {
|
|
1602
|
+
registerAuthModule(name, authModule);
|
|
1408
1603
|
}
|
|
1409
|
-
|
|
1410
|
-
hostConfig
|
|
1411
|
-
}) {
|
|
1412
|
-
const websocketAccessToken = await handlePotentialAuthenticationErrorAndRetry2(hostConfig, async () => {
|
|
1413
|
-
const accessToken = await getOAuthAccessToken(hostConfig);
|
|
1414
|
-
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "websocket");
|
|
1415
|
-
});
|
|
1416
|
-
return {
|
|
1417
|
-
queryParams: {
|
|
1418
|
-
accessToken: websocketAccessToken
|
|
1419
|
-
}
|
|
1420
|
-
};
|
|
1604
|
+
function setDefaultHostConfig2(hostConfig) {
|
|
1605
|
+
setDefaultHostConfig(hostConfig);
|
|
1421
1606
|
}
|
|
1422
|
-
|
|
1423
|
-
hostConfig
|
|
1424
|
-
}) {
|
|
1425
|
-
const webResourceAccessToken = await handlePotentialAuthenticationErrorAndRetry2(hostConfig, async () => {
|
|
1426
|
-
const accessToken = await getOAuthAccessToken(hostConfig);
|
|
1427
|
-
return exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, "webresource");
|
|
1428
|
-
});
|
|
1429
|
-
return {
|
|
1430
|
-
queryParams: {
|
|
1431
|
-
accessToken: webResourceAccessToken
|
|
1432
|
-
}
|
|
1433
|
-
};
|
|
1607
|
+
function registerHostConfig2(name, hostConfig) {
|
|
1608
|
+
registerHostConfig(name, hostConfig);
|
|
1434
1609
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
if (hostConfig.performInteractiveLogin) {
|
|
1447
|
-
clearStoredOauthTokens(hostConfig);
|
|
1448
|
-
return {
|
|
1449
|
-
retry: true
|
|
1450
|
-
};
|
|
1610
|
+
function unregisterHostConfig2(name) {
|
|
1611
|
+
unregisterHostConfig(name);
|
|
1612
|
+
}
|
|
1613
|
+
function serializeHostConfig2(hostConfig) {
|
|
1614
|
+
return serializeHostConfig(hostConfig);
|
|
1615
|
+
}
|
|
1616
|
+
function checkForCrossDomainRequest(hostConfig) {
|
|
1617
|
+
const hostConfigToUse = withResolvedHostConfig(hostConfig);
|
|
1618
|
+
if (isHostCrossOrigin(hostConfigToUse)) {
|
|
1619
|
+
if (Object.keys(hostConfigToUse).length === 0) {
|
|
1620
|
+
throw new InvalidHostConfigError("a host config must be provided when making a cross domain request");
|
|
1451
1621
|
}
|
|
1452
|
-
if (
|
|
1453
|
-
|
|
1622
|
+
if (!hostConfigToUse.host) {
|
|
1623
|
+
throw new InvalidHostConfigError(
|
|
1624
|
+
"A 'host' property must be set in host config when making a cross domain request"
|
|
1625
|
+
);
|
|
1454
1626
|
}
|
|
1455
|
-
startFullPageLoginFlow(hostConfig);
|
|
1456
|
-
return {
|
|
1457
|
-
preventDefault: true
|
|
1458
|
-
};
|
|
1459
1627
|
}
|
|
1460
|
-
await refreshAccessToken(hostConfig);
|
|
1461
|
-
return {
|
|
1462
|
-
preventDefault: false,
|
|
1463
|
-
retry: true
|
|
1464
|
-
};
|
|
1465
|
-
}
|
|
1466
|
-
var oauth_default = {
|
|
1467
|
-
getRestCallAuthParams: getRestCallAuthParams6,
|
|
1468
|
-
getWebSocketAuthParams: getWebSocketAuthParams6,
|
|
1469
|
-
getWebResourceAuthParams: getWebResourceAuthParams3,
|
|
1470
|
-
handleAuthenticationError: handleAuthenticationError6,
|
|
1471
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
1472
|
-
requiredProps: ["clientId"],
|
|
1473
|
-
optionalProps: [
|
|
1474
|
-
"clientSecret",
|
|
1475
|
-
"redirectUri",
|
|
1476
|
-
"accessTokenStorage",
|
|
1477
|
-
"scope",
|
|
1478
|
-
"subject",
|
|
1479
|
-
"userId",
|
|
1480
|
-
"noCache",
|
|
1481
|
-
"getAccessToken",
|
|
1482
|
-
"performInteractiveLogin"
|
|
1483
|
-
]
|
|
1484
|
-
})
|
|
1485
|
-
};
|
|
1486
|
-
|
|
1487
|
-
// src/auth/internal/default-auth-modules/reference.ts
|
|
1488
|
-
function getRestCallAuthParams7() {
|
|
1489
|
-
throw new Error("getRestCallAuthParams should never be called for reference auth module");
|
|
1490
|
-
}
|
|
1491
|
-
function getWebSocketAuthParams7() {
|
|
1492
|
-
throw new Error("getWebSocketAuthParams should never be called for reference auth module");
|
|
1493
|
-
}
|
|
1494
|
-
function handleAuthenticationError7() {
|
|
1495
|
-
throw new Error("handleAuthenticationError should never be called for reference auth module");
|
|
1496
1628
|
}
|
|
1497
|
-
var
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
handleAuthenticationError: handleAuthenticationError7,
|
|
1501
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: ["reference"], optionalProps: [] })
|
|
1629
|
+
var logout = () => {
|
|
1630
|
+
globalThis.loggingOut = true;
|
|
1631
|
+
globalThis.location.href = "/logout";
|
|
1502
1632
|
};
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
const j = Math.floor(Math.random() * 62);
|
|
1510
|
-
if (j < 10) {
|
|
1511
|
-
result2 += j;
|
|
1512
|
-
} else if (j > 9 && j < 36) {
|
|
1513
|
-
result2 += String.fromCharCode(j + 55);
|
|
1514
|
-
} else {
|
|
1515
|
-
result2 += String.fromCharCode(j + 61);
|
|
1516
|
-
}
|
|
1633
|
+
var leadingHttp = /^http/;
|
|
1634
|
+
function normalizeInbandAuthError({ errorBody, status }) {
|
|
1635
|
+
const authError = errorBody;
|
|
1636
|
+
if (typeof authError?.errors === "object") {
|
|
1637
|
+
const err = new AuthorizationError(authError?.errors);
|
|
1638
|
+
return { message: err.message };
|
|
1517
1639
|
}
|
|
1518
|
-
return
|
|
1519
|
-
}
|
|
1520
|
-
function getXrfKey(hostConfig) {
|
|
1521
|
-
const locationUrl = toValidLocationUrl(hostConfig);
|
|
1522
|
-
xrfKeys[locationUrl] = xrfKeys[locationUrl] || createXrfKey();
|
|
1523
|
-
return xrfKeys[locationUrl];
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1526
|
-
// src/auth/internal/default-auth-modules/windows-cookie.ts
|
|
1527
|
-
async function getRestCallAuthParams8({
|
|
1528
|
-
hostConfig
|
|
1529
|
-
}) {
|
|
1530
|
-
return {
|
|
1531
|
-
headers: {
|
|
1532
|
-
"X-Qlik-XrfKey": getXrfKey(hostConfig)
|
|
1533
|
-
},
|
|
1534
|
-
queryParams: {
|
|
1535
|
-
xrfkey: getXrfKey(hostConfig)
|
|
1536
|
-
},
|
|
1537
|
-
credentials: getCredentialsForCookieAuth(hostConfig)
|
|
1538
|
-
};
|
|
1640
|
+
return { message: `HTTP ${status}` };
|
|
1539
1641
|
}
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
}) {
|
|
1543
|
-
return {
|
|
1544
|
-
queryParams: {
|
|
1545
|
-
xrfkey: getXrfKey(hostConfig),
|
|
1546
|
-
"qlik-csrf-token": await getCsrfToken(hostConfig, true)
|
|
1547
|
-
}
|
|
1548
|
-
};
|
|
1642
|
+
function normalizeAuthModuleError(err) {
|
|
1643
|
+
return { message: err.message || "Unknown error" };
|
|
1549
1644
|
}
|
|
1550
|
-
|
|
1551
|
-
hostConfig
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1645
|
+
function withResolvedHostConfig(hostConfig) {
|
|
1646
|
+
if (hostConfig?.reference) {
|
|
1647
|
+
const refConfig = getRegisteredHostConfig(hostConfig.reference);
|
|
1648
|
+
if (!refConfig) {
|
|
1649
|
+
throw new InvalidHostConfigError(
|
|
1650
|
+
`Host config with name "${hostConfig.reference}" not found.`
|
|
1651
|
+
);
|
|
1556
1652
|
}
|
|
1557
|
-
|
|
1558
|
-
hostConfig.loginUri.replace("{location}", encodeURIComponent(globalThis.location.href))
|
|
1559
|
-
);
|
|
1560
|
-
return {
|
|
1561
|
-
preventDefault: true
|
|
1562
|
-
};
|
|
1653
|
+
return refConfig;
|
|
1563
1654
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
};
|
|
1567
|
-
}
|
|
1568
|
-
var windows_cookie_default = {
|
|
1569
|
-
getRestCallAuthParams: getRestCallAuthParams8,
|
|
1570
|
-
getWebSocketAuthParams: getWebSocketAuthParams8,
|
|
1571
|
-
handleAuthenticationError: handleAuthenticationError8,
|
|
1572
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
1573
|
-
requiredProps: [],
|
|
1574
|
-
optionalProps: ["loginUri", "crossSiteCookies"]
|
|
1575
|
-
})
|
|
1576
|
-
};
|
|
1577
|
-
|
|
1578
|
-
// src/auth/auth.ts
|
|
1579
|
-
globalThis.loggingOut = false;
|
|
1580
|
-
var authModulesRegistered = false;
|
|
1581
|
-
function registerDefaultAuthModules() {
|
|
1582
|
-
if (!authModulesRegistered) {
|
|
1583
|
-
registerAuthModule("apikey", apikey_default);
|
|
1584
|
-
registerAuthModule("cookie", cookie_default);
|
|
1585
|
-
registerAuthModule("none", none_default);
|
|
1586
|
-
registerAuthModule("oauth2", oauth_default);
|
|
1587
|
-
registerAuthModule("anonymous", anonymous_default);
|
|
1588
|
-
registerAuthModule("windowscookie", windows_cookie_default);
|
|
1589
|
-
registerAuthModule("reference", reference_default);
|
|
1590
|
-
authModulesRegistered = true;
|
|
1655
|
+
if (hostConfig && Object.keys(hostConfig).length > 0) {
|
|
1656
|
+
return hostConfig;
|
|
1591
1657
|
}
|
|
1658
|
+
return getDefaultHostConfig();
|
|
1659
|
+
}
|
|
1660
|
+
function getDefaultHostConfig2() {
|
|
1661
|
+
return getDefaultHostConfig();
|
|
1592
1662
|
}
|
|
1593
|
-
registerDefaultAuthModules();
|
|
1594
|
-
var auth = {
|
|
1595
|
-
logout,
|
|
1596
|
-
registerAuthModule,
|
|
1597
|
-
setDefaultHostConfig,
|
|
1598
|
-
registerHostConfig,
|
|
1599
|
-
unregisterHostConfig,
|
|
1600
|
-
getRestCallAuthParams,
|
|
1601
|
-
getWebSocketAuthParams,
|
|
1602
|
-
getWebResourceAuthParams,
|
|
1603
|
-
handleAuthenticationError,
|
|
1604
|
-
toValidLocationUrl,
|
|
1605
|
-
toValidWebsocketLocationUrl,
|
|
1606
|
-
isWindows,
|
|
1607
|
-
isHostCrossOrigin,
|
|
1608
|
-
determineAuthType,
|
|
1609
|
-
serializeHostConfig
|
|
1610
|
-
};
|
|
1611
|
-
var auth_default = auth;
|
|
1612
1663
|
|
|
1613
1664
|
// src/invoke-fetch/internal/invoke-fetch-helpers.ts
|
|
1614
1665
|
function encodeQueryParams(query) {
|
|
@@ -1981,14 +2032,14 @@ async function getInvokeFetchUrlParams({
|
|
|
1981
2032
|
headers: authHeaders,
|
|
1982
2033
|
queryParams: authQueryParams,
|
|
1983
2034
|
credentials
|
|
1984
|
-
} = await
|
|
2035
|
+
} = await getRestCallAuthParams8({
|
|
1985
2036
|
hostConfig: options?.hostConfig,
|
|
1986
2037
|
method
|
|
1987
2038
|
});
|
|
1988
2039
|
const url = locationUrl + applyPathVariables(pathTemplate, pathVariables);
|
|
1989
2040
|
const queryString = encodeQueryParams({ ...query, ...authQueryParams });
|
|
1990
2041
|
const completeUrl = toCompleteUrl(url, queryString);
|
|
1991
|
-
const cacheKey = toCacheKey(url, queryString,
|
|
2042
|
+
const cacheKey = toCacheKey(url, queryString, serializeHostConfig2(options?.hostConfig), options?.headers);
|
|
1992
2043
|
return { completeUrl, cacheKey, authHeaders, credentials };
|
|
1993
2044
|
}
|
|
1994
2045
|
function invokeFetchWithUrl(api, props) {
|
|
@@ -2067,7 +2118,7 @@ function invokeFetchWithUrlAndRetry(api, {
|
|
|
2067
2118
|
return cloneResultPromise(resultPromiseAfterCacheClearing);
|
|
2068
2119
|
}
|
|
2069
2120
|
function addPagingFunctions(api, value, method, body, options, authHeaders, credentials) {
|
|
2070
|
-
const serializedHostConfig =
|
|
2121
|
+
const serializedHostConfig = serializeHostConfig2(options?.hostConfig);
|
|
2071
2122
|
return value.then((resp) => {
|
|
2072
2123
|
const dataWithPotentialLinks = resp.data;
|
|
2073
2124
|
if (!dataWithPotentialLinks) {
|
|
@@ -2114,7 +2165,7 @@ async function interceptAuthenticationErrors(hostConfig, resultPromise, performR
|
|
|
2114
2165
|
if (globalThis.loggingOut) {
|
|
2115
2166
|
return neverResolvingPromise();
|
|
2116
2167
|
}
|
|
2117
|
-
const { retry, preventDefault } = await
|
|
2168
|
+
const { retry, preventDefault } = await handleAuthenticationError8({
|
|
2118
2169
|
hostConfig,
|
|
2119
2170
|
status: err.status,
|
|
2120
2171
|
headers: err.headers,
|
|
@@ -2166,50 +2217,6 @@ async function download(blob, filename) {
|
|
|
2166
2217
|
}
|
|
2167
2218
|
}
|
|
2168
2219
|
|
|
2169
|
-
// src/invoke-fetch/invoke-fetch-error.ts
|
|
2170
|
-
var InvokeFetchError = class extends Error {
|
|
2171
|
-
status;
|
|
2172
|
-
headers;
|
|
2173
|
-
data;
|
|
2174
|
-
constructor(errorMessage, status, headers, data) {
|
|
2175
|
-
super(errorMessage);
|
|
2176
|
-
this.status = status;
|
|
2177
|
-
this.headers = headers;
|
|
2178
|
-
this.data = data;
|
|
2179
|
-
this.stack = cleanStack(this.stack);
|
|
2180
|
-
}
|
|
2181
|
-
};
|
|
2182
|
-
var EncodingError = class extends Error {
|
|
2183
|
-
contentType;
|
|
2184
|
-
data;
|
|
2185
|
-
constructor(errorMessage, contentType, data) {
|
|
2186
|
-
super(errorMessage);
|
|
2187
|
-
this.contentType = contentType;
|
|
2188
|
-
this.data = data;
|
|
2189
|
-
this.stack = cleanStack(this.stack);
|
|
2190
|
-
}
|
|
2191
|
-
};
|
|
2192
|
-
var regex = /^.+\/qmfe-api(?:\.js)?:(\d+)(?::\d+)?$/gim;
|
|
2193
|
-
var isFromQmfeApi = (line) => {
|
|
2194
|
-
const matches = line.match(regex);
|
|
2195
|
-
return Boolean(matches && matches.length > 0);
|
|
2196
|
-
};
|
|
2197
|
-
function cleanStack(stack) {
|
|
2198
|
-
if (!stack) {
|
|
2199
|
-
return stack;
|
|
2200
|
-
}
|
|
2201
|
-
const newStack = [];
|
|
2202
|
-
const lines = stack.split("\n");
|
|
2203
|
-
lines.reverse();
|
|
2204
|
-
for (const line of lines) {
|
|
2205
|
-
if (isFromQmfeApi(line)) {
|
|
2206
|
-
break;
|
|
2207
|
-
}
|
|
2208
|
-
newStack.unshift(line);
|
|
2209
|
-
}
|
|
2210
|
-
return newStack.join("\n");
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
2220
|
// src/invoke-fetch/invoke-fetch-functions.ts
|
|
2214
2221
|
var defaultUserAgent = "qmfe-api/latest";
|
|
2215
2222
|
async function invokeFetch(api, props, interceptors) {
|
|
@@ -2301,44 +2308,33 @@ async function parseFetchResponse(fetchResponse, url) {
|
|
|
2301
2308
|
return invokeFetchResponse;
|
|
2302
2309
|
}
|
|
2303
2310
|
|
|
2304
|
-
// src/invoke-fetch/invoke-fetch.ts
|
|
2305
|
-
var invokeFetchExp = {
|
|
2306
|
-
invokeFetch,
|
|
2307
|
-
clearApiCache,
|
|
2308
|
-
parseFetchResponse
|
|
2309
|
-
};
|
|
2310
|
-
var invoke_fetch_default = invokeFetchExp;
|
|
2311
|
-
|
|
2312
2311
|
export {
|
|
2313
2312
|
getPlatform,
|
|
2313
|
+
generateRandomString,
|
|
2314
|
+
exposeInternalApiOnWindow,
|
|
2315
|
+
InvokeFetchError,
|
|
2316
|
+
EncodingError,
|
|
2317
|
+
invokeFetch,
|
|
2318
|
+
clearApiCache,
|
|
2319
|
+
parseFetchResponse,
|
|
2314
2320
|
InvalidHostConfigError,
|
|
2315
2321
|
UnexpectedAuthTypeError,
|
|
2316
2322
|
InvalidAuthTypeError,
|
|
2317
2323
|
AuthorizationError,
|
|
2324
|
+
determineAuthType2 as determineAuthType,
|
|
2318
2325
|
isHostCrossOrigin,
|
|
2319
2326
|
isWindows,
|
|
2320
2327
|
toValidLocationUrl,
|
|
2321
2328
|
toValidWebsocketLocationUrl,
|
|
2322
|
-
getWebSocketAuthParams,
|
|
2323
|
-
getWebResourceAuthParams,
|
|
2324
|
-
handleAuthenticationError,
|
|
2325
|
-
getRestCallAuthParams,
|
|
2326
|
-
getAccessToken,
|
|
2329
|
+
getWebSocketAuthParams8 as getWebSocketAuthParams,
|
|
2330
|
+
getWebResourceAuthParams3 as getWebResourceAuthParams,
|
|
2331
|
+
handleAuthenticationError8 as handleAuthenticationError,
|
|
2332
|
+
getRestCallAuthParams8 as getRestCallAuthParams,
|
|
2327
2333
|
registerAuthModule2 as registerAuthModule,
|
|
2328
|
-
setDefaultHostConfig,
|
|
2329
|
-
registerHostConfig,
|
|
2330
|
-
unregisterHostConfig,
|
|
2331
|
-
serializeHostConfig,
|
|
2332
|
-
determineAuthType,
|
|
2333
|
-
checkForCrossDomainRequest,
|
|
2334
|
+
setDefaultHostConfig2 as setDefaultHostConfig,
|
|
2335
|
+
registerHostConfig2 as registerHostConfig,
|
|
2336
|
+
unregisterHostConfig2 as unregisterHostConfig,
|
|
2337
|
+
serializeHostConfig2 as serializeHostConfig,
|
|
2334
2338
|
logout,
|
|
2335
|
-
|
|
2336
|
-
exposeInternalApiOnWindow,
|
|
2337
|
-
InvokeFetchError,
|
|
2338
|
-
EncodingError,
|
|
2339
|
-
invokeFetch,
|
|
2340
|
-
clearApiCache,
|
|
2341
|
-
parseFetchResponse,
|
|
2342
|
-
invoke_fetch_default,
|
|
2343
|
-
auth_default
|
|
2339
|
+
getDefaultHostConfig2 as getDefaultHostConfig
|
|
2344
2340
|
};
|