@qlik/api 1.13.0 → 1.15.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 +2 -2
- package/api-keys.js +2 -2
- package/apps.d.ts +2 -2
- package/apps.js +2 -2
- package/audits.d.ts +2 -2
- package/audits.js +2 -2
- package/{auth-types-Bqw3vbLs.d.ts → auth-types-BU5EGt_9.d.ts} +1 -0
- package/auth.d.ts +2 -2
- package/auth.js +2 -2
- package/automations.d.ts +2 -2
- package/automations.js +2 -2
- package/brands.d.ts +2 -2
- package/brands.js +2 -2
- package/chunks/{5T2SBCJG.js → BOSBVTSJ.js} +9 -3
- package/chunks/{HACHQCYI.js → DVK2JJ2J.js} +2 -2
- package/chunks/{IOUD76RB.js → J76NVE2J.js} +1 -1
- package/chunks/{JIAZ5W7Y.js → LEILCZC6.js} +1 -1
- package/chunks/{RN5AUIPP.js → N6IB3ZM5.js} +415 -257
- package/chunks/{LIPAU4N5.js → OQWVV26L.js} +1 -3
- package/chunks/{ADP23C4M.js → TBHMVTOT.js} +1 -1
- package/chunks/{5V4BMSM2.js → V2I3BC7K.js} +2 -2
- package/chunks/{NWOESCMR.js → W5IUOFYL.js} +1 -1
- package/chunks/{CNQQPV5L.js → ZWPUDPMY.js} +1 -1
- package/collections.d.ts +2 -2
- package/collections.js +2 -2
- package/csp-origins.d.ts +2 -2
- package/csp-origins.js +2 -2
- package/data-assets.d.ts +4 -2
- package/data-assets.js +2 -2
- package/data-connections.d.ts +9 -9
- package/data-connections.js +2 -2
- package/data-credentials.d.ts +7 -7
- package/data-credentials.js +2 -2
- package/data-files.d.ts +2 -2
- package/data-files.js +2 -2
- package/extensions.d.ts +2 -2
- package/extensions.js +2 -2
- package/{global.types-Xt6XzwlN.d.ts → global.types-z1p6A9D-.d.ts} +12 -1
- package/glossaries.d.ts +4 -2
- package/glossaries.js +2 -2
- package/groups.d.ts +2 -2
- package/groups.js +2 -2
- package/identity-providers.d.ts +2 -2
- package/identity-providers.js +2 -2
- package/index.d.ts +2 -2
- package/index.js +4 -4
- package/items.d.ts +2 -2
- package/items.js +2 -2
- package/licenses.d.ts +2 -2
- package/licenses.js +2 -2
- package/package.json +2 -2
- package/qix.d.ts +94 -65
- package/qix.js +2 -2
- package/quotas.d.ts +2 -2
- package/quotas.js +2 -2
- package/reload-tasks.d.ts +2 -2
- package/reload-tasks.js +2 -2
- package/reloads.d.ts +2 -2
- package/reloads.js +2 -2
- package/reports.d.ts +32 -8
- package/reports.js +2 -2
- package/roles.d.ts +2 -2
- package/roles.js +2 -2
- package/spaces.d.ts +2 -2
- package/spaces.js +2 -2
- package/temp-contents.d.ts +2 -2
- package/temp-contents.js +2 -2
- package/tenants.d.ts +2 -2
- package/tenants.js +2 -2
- package/themes.d.ts +2 -2
- package/themes.js +2 -2
- package/transports.d.ts +2 -2
- package/transports.js +2 -2
- package/users.d.ts +2 -2
- package/users.js +2 -2
- package/web-integrations.d.ts +2 -2
- package/web-integrations.js +2 -2
- package/web-notifications.d.ts +4 -2
- package/web-notifications.js +2 -2
- package/webhooks.d.ts +6 -4
- package/webhooks.js +2 -2
|
@@ -132,6 +132,9 @@ async function guessAuthTypeIfMissing(hostConfig) {
|
|
|
132
132
|
if (hostConfig.apiKey) {
|
|
133
133
|
return "apikey";
|
|
134
134
|
}
|
|
135
|
+
if (hostConfig.accessCode) {
|
|
136
|
+
return "anonymous";
|
|
137
|
+
}
|
|
135
138
|
if (hostConfig.clientId) {
|
|
136
139
|
return "oauth2";
|
|
137
140
|
}
|
|
@@ -319,6 +322,15 @@ var logout = () => {
|
|
|
319
322
|
};
|
|
320
323
|
var leadingHttp = /^http/;
|
|
321
324
|
|
|
325
|
+
// src/random/random.ts
|
|
326
|
+
import { customAlphabet, nanoid } from "nanoid";
|
|
327
|
+
function generateRandomString(targetLength) {
|
|
328
|
+
return nanoid(targetLength);
|
|
329
|
+
}
|
|
330
|
+
function generateRandomHexString(targetLength) {
|
|
331
|
+
return customAlphabet("1234567890abcdef", targetLength)();
|
|
332
|
+
}
|
|
333
|
+
|
|
322
334
|
// src/auth/internal/auth-functions.ts
|
|
323
335
|
function getCredentialsForCookieAuth(hostConfig) {
|
|
324
336
|
if (hostConfig.crossSiteCookies === false) {
|
|
@@ -362,155 +374,9 @@ function internalValidateHostConfig(hostConfig, options) {
|
|
|
362
374
|
return true;
|
|
363
375
|
}
|
|
364
376
|
|
|
365
|
-
// src/auth/internal/default-auth-modules/apikey.ts
|
|
366
|
-
function getRestCallAuthParams2({ hostConfig }) {
|
|
367
|
-
return Promise.resolve({
|
|
368
|
-
headers: {
|
|
369
|
-
Authorization: `Bearer ${hostConfig?.apiKey}`
|
|
370
|
-
},
|
|
371
|
-
queryParams: {},
|
|
372
|
-
credentials: "omit"
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
async function getWebSocketAuthParams2() {
|
|
376
|
-
return {
|
|
377
|
-
queryParams: {
|
|
378
|
-
// accessToken: hostConfig.apiKey,
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
function handleAuthenticationError2() {
|
|
383
|
-
return Promise.resolve({});
|
|
384
|
-
}
|
|
385
|
-
var apikey_default = {
|
|
386
|
-
getRestCallAuthParams: getRestCallAuthParams2,
|
|
387
|
-
getWebSocketAuthParams: getWebSocketAuthParams2,
|
|
388
|
-
handleAuthenticationError: handleAuthenticationError2,
|
|
389
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: ["apiKey"], optionalProps: [] })
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
// src/http/http-functions.ts
|
|
393
|
-
var QLIK_CSRF_TOKEN = "qlik-csrf-token";
|
|
394
|
-
function clearCsrfToken(hostConfig) {
|
|
395
|
-
const locationUrl = toValidLocationUrl(hostConfig);
|
|
396
|
-
delete csrfTokens[locationUrl];
|
|
397
|
-
}
|
|
398
|
-
async function getCsrfToken(hostConfig, noCache) {
|
|
399
|
-
const locationUrl = toValidLocationUrl(hostConfig);
|
|
400
|
-
let pathTemplate;
|
|
401
|
-
if (await isWindows(hostConfig)) {
|
|
402
|
-
pathTemplate = "/qps/csrftoken";
|
|
403
|
-
} else {
|
|
404
|
-
pathTemplate = "/api/v1/csrf-token";
|
|
405
|
-
}
|
|
406
|
-
const fetchCsrfToken = async () => {
|
|
407
|
-
const res = await invokeFetch("csrf-token", {
|
|
408
|
-
method: "get",
|
|
409
|
-
pathTemplate,
|
|
410
|
-
options: {
|
|
411
|
-
hostConfig,
|
|
412
|
-
noCache: true
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
const csrfToken = res.headers.get(QLIK_CSRF_TOKEN);
|
|
416
|
-
if (!csrfToken) {
|
|
417
|
-
return "";
|
|
418
|
-
}
|
|
419
|
-
return csrfToken;
|
|
420
|
-
};
|
|
421
|
-
if (noCache) {
|
|
422
|
-
csrfTokens[locationUrl] = fetchCsrfToken();
|
|
423
|
-
return csrfTokens[locationUrl];
|
|
424
|
-
}
|
|
425
|
-
csrfTokens[locationUrl] = csrfTokens[locationUrl] || fetchCsrfToken();
|
|
426
|
-
return csrfTokens[locationUrl];
|
|
427
|
-
}
|
|
428
|
-
var csrfTokens = {};
|
|
429
|
-
|
|
430
|
-
// src/auth/internal/default-auth-modules/cookie.ts
|
|
431
|
-
function isModifyingVerb(verb) {
|
|
432
|
-
return !(verb === "get" || verb === "GET");
|
|
433
|
-
}
|
|
434
|
-
async function getRestCallAuthParams3({
|
|
435
|
-
hostConfig,
|
|
436
|
-
method
|
|
437
|
-
}) {
|
|
438
|
-
const headers = {};
|
|
439
|
-
if (isModifyingVerb(method)) {
|
|
440
|
-
headers["qlik-csrf-token"] = await getCsrfToken(hostConfig);
|
|
441
|
-
}
|
|
442
|
-
if (hostConfig.webIntegrationId) {
|
|
443
|
-
headers["qlik-web-integration-id"] = hostConfig.webIntegrationId;
|
|
444
|
-
}
|
|
445
|
-
return { headers, queryParams: {}, credentials: getCredentialsForCookieAuth(hostConfig) };
|
|
446
|
-
}
|
|
447
|
-
async function getWebSocketAuthParams3({
|
|
448
|
-
hostConfig
|
|
449
|
-
}) {
|
|
450
|
-
const params = {
|
|
451
|
-
// Bypass the cache to get one rest call out the door that can catch a 401 since the websocket only returns a general error
|
|
452
|
-
"qlik-csrf-token": await getCsrfToken(hostConfig, true)
|
|
453
|
-
};
|
|
454
|
-
if (hostConfig.webIntegrationId) {
|
|
455
|
-
params["qlik-web-integration-id"] = hostConfig.webIntegrationId;
|
|
456
|
-
}
|
|
457
|
-
return { queryParams: params };
|
|
458
|
-
}
|
|
459
|
-
async function handleAuthenticationError3({
|
|
460
|
-
hostConfig,
|
|
461
|
-
status,
|
|
462
|
-
errorBody = {}
|
|
463
|
-
}) {
|
|
464
|
-
clearCsrfToken(hostConfig);
|
|
465
|
-
if (status === 403) {
|
|
466
|
-
return {
|
|
467
|
-
preventDefault: false,
|
|
468
|
-
// Only retry if the csrf token has expired
|
|
469
|
-
retry: errorBody?.code === "CSRF-TOKEN-2"
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
const webIntegrationParam = hostConfig.webIntegrationId ? `qlik-web-integration-id=${hostConfig?.webIntegrationId}&` : "";
|
|
473
|
-
const locationUrl = toValidLocationUrl(hostConfig);
|
|
474
|
-
if (hostConfig.authRedirectUserConfirmation) {
|
|
475
|
-
await hostConfig.authRedirectUserConfirmation();
|
|
476
|
-
}
|
|
477
|
-
globalThis.location.replace(
|
|
478
|
-
`${locationUrl}/login?${webIntegrationParam}returnto=${encodeURIComponent(globalThis.location.href)}`
|
|
479
|
-
);
|
|
480
|
-
return {
|
|
481
|
-
preventDefault: true
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
var cookie_default = {
|
|
485
|
-
getRestCallAuthParams: getRestCallAuthParams3,
|
|
486
|
-
getWebSocketAuthParams: getWebSocketAuthParams3,
|
|
487
|
-
handleAuthenticationError: handleAuthenticationError3,
|
|
488
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
489
|
-
requiredProps: [],
|
|
490
|
-
optionalProps: ["webIntegrationId", "crossSiteCookies"]
|
|
491
|
-
})
|
|
492
|
-
};
|
|
493
|
-
|
|
494
|
-
// src/auth/internal/default-auth-modules/none.ts
|
|
495
|
-
function getRestCallAuthParams4() {
|
|
496
|
-
return Promise.resolve({ headers: {}, queryParams: {}, credentials: "same-origin" });
|
|
497
|
-
}
|
|
498
|
-
function getWebSocketAuthParams4() {
|
|
499
|
-
return Promise.resolve({ queryParams: {} });
|
|
500
|
-
}
|
|
501
|
-
function handleAuthenticationError4() {
|
|
502
|
-
return Promise.resolve({});
|
|
503
|
-
}
|
|
504
|
-
var none_default = {
|
|
505
|
-
getRestCallAuthParams: getRestCallAuthParams4,
|
|
506
|
-
getWebSocketAuthParams: getWebSocketAuthParams4,
|
|
507
|
-
handleAuthenticationError: handleAuthenticationError4,
|
|
508
|
-
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: [], optionalProps: [] })
|
|
509
|
-
};
|
|
510
|
-
|
|
511
377
|
// src/auth/internal/default-auth-modules/oauth/storage-helpers.ts
|
|
512
378
|
var storagePrefix = "qlik-qmfe-api";
|
|
513
|
-
function
|
|
379
|
+
function getTopicFromOauthHostConfig(hostConfig) {
|
|
514
380
|
let topic = `${hostConfig.clientId + (hostConfig.scope ? `_${hostConfig.scope}` : "_user_default")}`;
|
|
515
381
|
if (hostConfig.subject) {
|
|
516
382
|
topic += `_${hostConfig.subject}`;
|
|
@@ -520,6 +386,9 @@ function getTopicFromHostConfig(hostConfig) {
|
|
|
520
386
|
}
|
|
521
387
|
return topic;
|
|
522
388
|
}
|
|
389
|
+
function getTopicFromAnonHostConfig(hostConfig) {
|
|
390
|
+
return `${hostConfig.accessCode}_${hostConfig.clientId}`;
|
|
391
|
+
}
|
|
523
392
|
var cachedTokens = {};
|
|
524
393
|
function saveInLocalStorage(topic, name, value) {
|
|
525
394
|
localStorage.setItem(`${storagePrefix}-${topic}-${name}`, value);
|
|
@@ -545,18 +414,15 @@ function loadAndDeleteFromSessionStorage(topic, name) {
|
|
|
545
414
|
sessionStorage.removeItem(id);
|
|
546
415
|
return result2;
|
|
547
416
|
}
|
|
548
|
-
function loadOauthTokensFromStorage(
|
|
549
|
-
if (!hostConfig.clientId) {
|
|
550
|
-
return void 0;
|
|
551
|
-
}
|
|
417
|
+
function loadOauthTokensFromStorage(topic, accessTokenStorage) {
|
|
552
418
|
let accessToken;
|
|
553
419
|
let refreshToken;
|
|
554
|
-
if (
|
|
555
|
-
accessToken = loadFromLocalStorage(
|
|
556
|
-
refreshToken = loadFromLocalStorage(
|
|
557
|
-
} else if (
|
|
558
|
-
accessToken = loadFromSessionStorage(
|
|
559
|
-
refreshToken = loadFromSessionStorage(
|
|
420
|
+
if (accessTokenStorage === "local") {
|
|
421
|
+
accessToken = loadFromLocalStorage(topic, "access-token");
|
|
422
|
+
refreshToken = loadFromLocalStorage(topic, "refresh-token");
|
|
423
|
+
} else if (accessTokenStorage === "session") {
|
|
424
|
+
accessToken = loadFromSessionStorage(topic, "access-token");
|
|
425
|
+
refreshToken = loadFromSessionStorage(topic, "refresh-token");
|
|
560
426
|
}
|
|
561
427
|
if (accessToken) {
|
|
562
428
|
return {
|
|
@@ -567,88 +433,72 @@ function loadOauthTokensFromStorage(hostConfig) {
|
|
|
567
433
|
return void 0;
|
|
568
434
|
}
|
|
569
435
|
async function loadCachedOauthTokens(hostConfig) {
|
|
570
|
-
return cachedTokens[
|
|
436
|
+
return cachedTokens[getTopicFromOauthHostConfig(hostConfig)];
|
|
571
437
|
}
|
|
572
|
-
async function
|
|
438
|
+
async function loadOrAcquireAccessTokenOauth(hostConfig, acquireTokens) {
|
|
573
439
|
if (!hostConfig.clientId) {
|
|
574
440
|
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
575
441
|
}
|
|
576
|
-
|
|
442
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
443
|
+
return loadOrAcquireAccessToken(topic, acquireTokens, hostConfig.noCache, hostConfig.accessTokenStorage);
|
|
444
|
+
}
|
|
445
|
+
async function loadOrAcquireAccessTokenAnon(hostConfig, acquireTokens) {
|
|
446
|
+
if (!hostConfig.accessCode) {
|
|
447
|
+
throw new InvalidHostConfigError(
|
|
448
|
+
'A host config with authType set to "anonymous" has to also provide an accessCode'
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
const topic = getTopicFromAnonHostConfig(hostConfig);
|
|
452
|
+
return loadOrAcquireAccessToken(topic, acquireTokens, false, void 0);
|
|
453
|
+
}
|
|
454
|
+
async function loadOrAcquireAccessToken(topic, acquireTokens, noCache, accessTokenStorage) {
|
|
455
|
+
if (noCache) {
|
|
577
456
|
return acquireTokens();
|
|
578
457
|
}
|
|
579
458
|
const mayUseStorage = isBrowser();
|
|
580
|
-
const storedOauthTokens = cachedTokens[
|
|
459
|
+
const storedOauthTokens = cachedTokens[topic] || (mayUseStorage ? loadOauthTokensFromStorage(topic, accessTokenStorage) : void 0);
|
|
581
460
|
if (storedOauthTokens) {
|
|
582
461
|
return Promise.resolve(storedOauthTokens);
|
|
583
462
|
}
|
|
584
463
|
const tokensPromise = acquireTokens();
|
|
585
|
-
cachedTokens[
|
|
464
|
+
cachedTokens[topic] = tokensPromise;
|
|
586
465
|
if (mayUseStorage) {
|
|
587
466
|
const tokens = await tokensPromise;
|
|
588
|
-
if (
|
|
467
|
+
if (accessTokenStorage === "local" && tokens) {
|
|
589
468
|
if (tokens.accessToken) {
|
|
590
|
-
saveInLocalStorage(
|
|
469
|
+
saveInLocalStorage(topic, "access-token", tokens.accessToken);
|
|
591
470
|
}
|
|
592
471
|
if (tokens.refreshToken) {
|
|
593
|
-
saveInLocalStorage(
|
|
472
|
+
saveInLocalStorage(topic, "refresh-token", tokens.refreshToken);
|
|
594
473
|
}
|
|
595
|
-
} else if (
|
|
474
|
+
} else if (accessTokenStorage === "session" && tokens) {
|
|
596
475
|
if (tokens.accessToken) {
|
|
597
|
-
saveInSessionStorage(
|
|
476
|
+
saveInSessionStorage(topic, "access-token", tokens.accessToken);
|
|
598
477
|
}
|
|
599
478
|
if (tokens.refreshToken) {
|
|
600
|
-
saveInSessionStorage(
|
|
479
|
+
saveInSessionStorage(topic, "refresh-token", tokens.refreshToken);
|
|
601
480
|
}
|
|
602
481
|
}
|
|
603
482
|
}
|
|
604
483
|
return tokensPromise;
|
|
605
484
|
}
|
|
606
485
|
function clearStoredOauthTokens(hostConfig) {
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
}
|
|
610
|
-
delete cachedTokens[getTopicFromHostConfig(hostConfig)];
|
|
486
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
487
|
+
delete cachedTokens[topic];
|
|
611
488
|
if (isBrowser()) {
|
|
612
|
-
deleteFromLocalStorage(
|
|
613
|
-
deleteFromSessionStorage(
|
|
489
|
+
deleteFromLocalStorage(topic, ["access-token", "refresh-token"]);
|
|
490
|
+
deleteFromSessionStorage(topic, ["access-token", "refresh-token"]);
|
|
614
491
|
}
|
|
615
492
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
if (urlParams.get("error")) {
|
|
623
|
-
const element = document.createElement("pre");
|
|
624
|
-
element.innerText = `<code>${JSON.stringify({
|
|
625
|
-
error: urlParams.get("error"),
|
|
626
|
-
error_code: urlParams.get("error_code"),
|
|
627
|
-
error_description: urlParams.get("error_description"),
|
|
628
|
-
error_detail: urlParams.get("error_detail"),
|
|
629
|
-
error_uri: urlParams.get("error_uri")
|
|
630
|
-
})}</code>`;
|
|
631
|
-
document.body.prepend(element);
|
|
632
|
-
}
|
|
633
|
-
const topic = loadAndDeleteFromSessionStorage("", "client-in-progress");
|
|
634
|
-
if (topic && callbackCode && callbackState) {
|
|
635
|
-
const stateFromLocalStorage = loadAndDeleteFromSessionStorage(topic, "state");
|
|
636
|
-
const finalRedirectUri = loadAndDeleteFromSessionStorage(topic, "href");
|
|
637
|
-
if (stateFromLocalStorage && stateFromLocalStorage === callbackState && finalRedirectUri) {
|
|
638
|
-
saveInSessionStorage(topic, "code", callbackCode);
|
|
639
|
-
if (finalRedirectUri !== globalThis.location.href) {
|
|
640
|
-
globalThis.location.replace(finalRedirectUri);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
493
|
+
function clearStoredAnonymousTokens(hostConfig) {
|
|
494
|
+
const topic = getTopicFromAnonHostConfig(hostConfig);
|
|
495
|
+
delete cachedTokens[topic];
|
|
496
|
+
if (isBrowser()) {
|
|
497
|
+
deleteFromLocalStorage(topic, ["access-token", "refresh-token"]);
|
|
498
|
+
deleteFromSessionStorage(topic, ["access-token", "refresh-token"]);
|
|
643
499
|
}
|
|
644
500
|
}
|
|
645
501
|
|
|
646
|
-
// src/random/random.ts
|
|
647
|
-
import { nanoid } from "nanoid";
|
|
648
|
-
function generateRandomString(targetLength) {
|
|
649
|
-
return nanoid(targetLength);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
502
|
// src/auth/internal/default-auth-modules/oauth/oauth-utils.ts
|
|
653
503
|
function lookupGetAccessFn(getAccessToken2) {
|
|
654
504
|
return globalThis[getAccessToken2];
|
|
@@ -690,11 +540,12 @@ async function startFullPageLoginFlow(hostConfig) {
|
|
|
690
540
|
const state = generateRandomString(43);
|
|
691
541
|
const codeChallenge = await sha256(verifier);
|
|
692
542
|
const redirectUri = hostConfig.redirectUri || globalThis.location.href;
|
|
543
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
693
544
|
clearStoredOauthTokens(hostConfig);
|
|
694
|
-
saveInSessionStorage(
|
|
695
|
-
saveInSessionStorage(
|
|
696
|
-
saveInSessionStorage(
|
|
697
|
-
saveInSessionStorage("", "client-in-progress",
|
|
545
|
+
saveInSessionStorage(topic, "state", state);
|
|
546
|
+
saveInSessionStorage(topic, "verifier", verifier);
|
|
547
|
+
saveInSessionStorage(topic, "href", globalThis.location.href);
|
|
548
|
+
saveInSessionStorage("", "client-in-progress", topic);
|
|
698
549
|
const queryParams = {
|
|
699
550
|
response_type: "code",
|
|
700
551
|
client_id: clientId,
|
|
@@ -800,6 +651,25 @@ async function getOauthTokensWithRefreshToken(baseUrl, refreshToken, clientSecre
|
|
|
800
651
|
errors: data.errors
|
|
801
652
|
};
|
|
802
653
|
}
|
|
654
|
+
async function getAnonymousOauthAccessToken(baseUrl, accessCode, clientId, trackingCode) {
|
|
655
|
+
const result2 = await fetch(`${baseUrl}/oauth/token`, {
|
|
656
|
+
method: "POST",
|
|
657
|
+
mode: "cors",
|
|
658
|
+
headers: { "content-type": "application/json" },
|
|
659
|
+
body: JSON.stringify({
|
|
660
|
+
eac: accessCode,
|
|
661
|
+
client_id: clientId,
|
|
662
|
+
grant_type: "urn:qlik:oauth:anonymous-embed",
|
|
663
|
+
tracking_code: trackingCode
|
|
664
|
+
})
|
|
665
|
+
});
|
|
666
|
+
const data = await result2.json();
|
|
667
|
+
return {
|
|
668
|
+
accessToken: data.access_token,
|
|
669
|
+
refreshToken: data.refresh_token,
|
|
670
|
+
errors: data.errors
|
|
671
|
+
};
|
|
672
|
+
}
|
|
803
673
|
async function getOAuthTokensForNode(hostConfig) {
|
|
804
674
|
const { clientId, clientSecret } = hostConfig;
|
|
805
675
|
if (!clientId || !clientSecret) {
|
|
@@ -807,7 +677,7 @@ async function getOAuthTokensForNode(hostConfig) {
|
|
|
807
677
|
'A host config with authType set to "oauth2" has to provide a clientId and a clientSecret'
|
|
808
678
|
);
|
|
809
679
|
}
|
|
810
|
-
const oauthTokens = await
|
|
680
|
+
const oauthTokens = await loadOrAcquireAccessTokenOauth(hostConfig, async () => {
|
|
811
681
|
if (!hostConfig.clientId || !hostConfig.clientSecret) {
|
|
812
682
|
throw new InvalidHostConfigError(
|
|
813
683
|
'A host config with authType set to "oauth2" has to provide a clientId and a clientSecret'
|
|
@@ -829,7 +699,7 @@ async function getOAuthTokensForBrowser(hostConfig) {
|
|
|
829
699
|
if (!clientId) {
|
|
830
700
|
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
831
701
|
}
|
|
832
|
-
const oauthTokens = await
|
|
702
|
+
const oauthTokens = await loadOrAcquireAccessTokenOauth(hostConfig, async () => {
|
|
833
703
|
if (hostConfig.getAccessToken) {
|
|
834
704
|
try {
|
|
835
705
|
const tokenFetchedFromRemote = typeof hostConfig.getAccessToken === "string" ? await lookupGetAccessFn(hostConfig.getAccessToken)() : await hostConfig.getAccessToken();
|
|
@@ -854,8 +724,9 @@ async function getOAuthTokensForBrowser(hostConfig) {
|
|
|
854
724
|
};
|
|
855
725
|
}
|
|
856
726
|
}
|
|
857
|
-
const
|
|
858
|
-
const
|
|
727
|
+
const topic = getTopicFromOauthHostConfig(hostConfig);
|
|
728
|
+
const code = loadAndDeleteFromSessionStorage(topic, "code");
|
|
729
|
+
const verifier = loadAndDeleteFromSessionStorage(topic, "verifier");
|
|
859
730
|
if (code && verifier) {
|
|
860
731
|
const tokenResponse = await exchangeCodeAndVerifierForAccessTokenData(
|
|
861
732
|
hostConfig,
|
|
@@ -905,7 +776,7 @@ async function refreshAccessToken(hostConfig) {
|
|
|
905
776
|
const tokens = await loadCachedOauthTokens(hostConfig);
|
|
906
777
|
clearStoredOauthTokens(hostConfig);
|
|
907
778
|
if (tokens && tokens.refreshToken && hostConfig.clientSecret) {
|
|
908
|
-
const refreshedTokens = await
|
|
779
|
+
const refreshedTokens = await loadOrAcquireAccessTokenOauth(hostConfig, async () => {
|
|
909
780
|
if (!tokens || !tokens.refreshToken || !hostConfig.clientSecret) {
|
|
910
781
|
throw new Error("Trying to refresh tokens without refreshToken or clientSecret");
|
|
911
782
|
}
|
|
@@ -921,6 +792,273 @@ async function refreshAccessToken(hostConfig) {
|
|
|
921
792
|
}
|
|
922
793
|
}
|
|
923
794
|
|
|
795
|
+
// src/auth/internal/default-auth-modules/anonymous.ts
|
|
796
|
+
async function getOrCreateTrackingCode(hostConfig) {
|
|
797
|
+
let trackingCode;
|
|
798
|
+
if (isBrowser()) {
|
|
799
|
+
const topic = getTopicFromAnonHostConfig(hostConfig);
|
|
800
|
+
trackingCode = loadFromLocalStorage(topic, "tracking-code");
|
|
801
|
+
if (!trackingCode) {
|
|
802
|
+
trackingCode = createTrackingCode();
|
|
803
|
+
}
|
|
804
|
+
saveInLocalStorage(topic, "tracking-code", trackingCode);
|
|
805
|
+
} else {
|
|
806
|
+
trackingCode = createTrackingCode();
|
|
807
|
+
}
|
|
808
|
+
return trackingCode;
|
|
809
|
+
}
|
|
810
|
+
function createTrackingCode() {
|
|
811
|
+
const timeStamp = Math.floor(Date.now() / 1e3).toString(16);
|
|
812
|
+
const randomString = generateRandomHexString(20);
|
|
813
|
+
return `${timeStamp}${randomString}`;
|
|
814
|
+
}
|
|
815
|
+
async function getAnonymousAccessToken(hostConfig) {
|
|
816
|
+
const { accessCode, clientId } = hostConfig;
|
|
817
|
+
if (!accessCode || !clientId) {
|
|
818
|
+
throw new InvalidHostConfigError(
|
|
819
|
+
'A host config with authType set to "anonymous" has to provide both an accessCode and clientId'
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
const tokens = await loadOrAcquireAccessTokenAnon(hostConfig, async () => {
|
|
823
|
+
const baseUrl = toValidLocationUrl(hostConfig);
|
|
824
|
+
const trackingCode = await getOrCreateTrackingCode(hostConfig);
|
|
825
|
+
return getAnonymousOauthAccessToken(baseUrl, accessCode, clientId, trackingCode);
|
|
826
|
+
});
|
|
827
|
+
if (!tokens) {
|
|
828
|
+
return "";
|
|
829
|
+
}
|
|
830
|
+
if (tokens.errors) {
|
|
831
|
+
throw new AuthorizationError(tokens.errors);
|
|
832
|
+
}
|
|
833
|
+
if (tokens.accessToken) {
|
|
834
|
+
return tokens.accessToken;
|
|
835
|
+
}
|
|
836
|
+
return "";
|
|
837
|
+
}
|
|
838
|
+
async function getRestCallAuthParams2({
|
|
839
|
+
hostConfig
|
|
840
|
+
}) {
|
|
841
|
+
return {
|
|
842
|
+
headers: {
|
|
843
|
+
Authorization: `Bearer ${await getAnonymousAccessToken(hostConfig)}`
|
|
844
|
+
},
|
|
845
|
+
queryParams: {},
|
|
846
|
+
credentials: "omit"
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
async function getWebSocketAuthParams2({
|
|
850
|
+
hostConfig
|
|
851
|
+
}) {
|
|
852
|
+
const accessToken = await getAnonymousAccessToken(hostConfig);
|
|
853
|
+
return {
|
|
854
|
+
queryParams: {
|
|
855
|
+
accessToken
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
async function getWebResourceAuthParams2({
|
|
860
|
+
hostConfig
|
|
861
|
+
}) {
|
|
862
|
+
const accessToken = await getAnonymousAccessToken(hostConfig);
|
|
863
|
+
return {
|
|
864
|
+
queryParams: {
|
|
865
|
+
accessToken
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
async function handleAuthenticationError2({
|
|
870
|
+
hostConfig
|
|
871
|
+
}) {
|
|
872
|
+
clearStoredAnonymousTokens(hostConfig);
|
|
873
|
+
return {
|
|
874
|
+
preventDefault: false,
|
|
875
|
+
retry: true
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
var anonymous_default = {
|
|
879
|
+
getRestCallAuthParams: getRestCallAuthParams2,
|
|
880
|
+
getWebSocketAuthParams: getWebSocketAuthParams2,
|
|
881
|
+
getWebResourceAuthParams: getWebResourceAuthParams2,
|
|
882
|
+
handleAuthenticationError: handleAuthenticationError2,
|
|
883
|
+
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
884
|
+
requiredProps: ["clientId", "accessCode"],
|
|
885
|
+
optionalProps: []
|
|
886
|
+
})
|
|
887
|
+
};
|
|
888
|
+
|
|
889
|
+
// src/auth/internal/default-auth-modules/apikey.ts
|
|
890
|
+
function getRestCallAuthParams3({ hostConfig }) {
|
|
891
|
+
return Promise.resolve({
|
|
892
|
+
headers: {
|
|
893
|
+
Authorization: `Bearer ${hostConfig?.apiKey}`
|
|
894
|
+
},
|
|
895
|
+
queryParams: {},
|
|
896
|
+
credentials: "omit"
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
async function getWebSocketAuthParams3() {
|
|
900
|
+
return {
|
|
901
|
+
queryParams: {
|
|
902
|
+
// accessToken: hostConfig.apiKey,
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
function handleAuthenticationError3() {
|
|
907
|
+
return Promise.resolve({});
|
|
908
|
+
}
|
|
909
|
+
var apikey_default = {
|
|
910
|
+
getRestCallAuthParams: getRestCallAuthParams3,
|
|
911
|
+
getWebSocketAuthParams: getWebSocketAuthParams3,
|
|
912
|
+
handleAuthenticationError: handleAuthenticationError3,
|
|
913
|
+
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: ["apiKey"], optionalProps: [] })
|
|
914
|
+
};
|
|
915
|
+
|
|
916
|
+
// src/http/http-functions.ts
|
|
917
|
+
var QLIK_CSRF_TOKEN = "qlik-csrf-token";
|
|
918
|
+
function clearCsrfToken(hostConfig) {
|
|
919
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
920
|
+
delete csrfTokens[locationUrl];
|
|
921
|
+
}
|
|
922
|
+
async function getCsrfToken(hostConfig, noCache) {
|
|
923
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
924
|
+
let pathTemplate;
|
|
925
|
+
if (await isWindows(hostConfig)) {
|
|
926
|
+
pathTemplate = "/qps/csrftoken";
|
|
927
|
+
} else {
|
|
928
|
+
pathTemplate = "/api/v1/csrf-token";
|
|
929
|
+
}
|
|
930
|
+
const fetchCsrfToken = async () => {
|
|
931
|
+
const res = await invokeFetch("csrf-token", {
|
|
932
|
+
method: "get",
|
|
933
|
+
pathTemplate,
|
|
934
|
+
options: {
|
|
935
|
+
hostConfig,
|
|
936
|
+
noCache: true
|
|
937
|
+
}
|
|
938
|
+
});
|
|
939
|
+
const csrfToken = res.headers.get(QLIK_CSRF_TOKEN);
|
|
940
|
+
if (!csrfToken) {
|
|
941
|
+
return "";
|
|
942
|
+
}
|
|
943
|
+
return csrfToken;
|
|
944
|
+
};
|
|
945
|
+
if (noCache) {
|
|
946
|
+
csrfTokens[locationUrl] = fetchCsrfToken();
|
|
947
|
+
return csrfTokens[locationUrl];
|
|
948
|
+
}
|
|
949
|
+
csrfTokens[locationUrl] = csrfTokens[locationUrl] || fetchCsrfToken();
|
|
950
|
+
return csrfTokens[locationUrl];
|
|
951
|
+
}
|
|
952
|
+
var csrfTokens = {};
|
|
953
|
+
|
|
954
|
+
// src/auth/internal/default-auth-modules/cookie.ts
|
|
955
|
+
function isModifyingVerb(verb) {
|
|
956
|
+
return !(verb === "get" || verb === "GET");
|
|
957
|
+
}
|
|
958
|
+
async function getRestCallAuthParams4({
|
|
959
|
+
hostConfig,
|
|
960
|
+
method
|
|
961
|
+
}) {
|
|
962
|
+
const headers = {};
|
|
963
|
+
if (isModifyingVerb(method)) {
|
|
964
|
+
headers["qlik-csrf-token"] = await getCsrfToken(hostConfig);
|
|
965
|
+
}
|
|
966
|
+
if (hostConfig.webIntegrationId) {
|
|
967
|
+
headers["qlik-web-integration-id"] = hostConfig.webIntegrationId;
|
|
968
|
+
}
|
|
969
|
+
return { headers, queryParams: {}, credentials: getCredentialsForCookieAuth(hostConfig) };
|
|
970
|
+
}
|
|
971
|
+
async function getWebSocketAuthParams4({
|
|
972
|
+
hostConfig
|
|
973
|
+
}) {
|
|
974
|
+
const params = {
|
|
975
|
+
// Bypass the cache to get one rest call out the door that can catch a 401 since the websocket only returns a general error
|
|
976
|
+
"qlik-csrf-token": await getCsrfToken(hostConfig, true)
|
|
977
|
+
};
|
|
978
|
+
if (hostConfig.webIntegrationId) {
|
|
979
|
+
params["qlik-web-integration-id"] = hostConfig.webIntegrationId;
|
|
980
|
+
}
|
|
981
|
+
return { queryParams: params };
|
|
982
|
+
}
|
|
983
|
+
async function handleAuthenticationError4({
|
|
984
|
+
hostConfig,
|
|
985
|
+
status
|
|
986
|
+
}) {
|
|
987
|
+
clearCsrfToken(hostConfig);
|
|
988
|
+
if (status === 403) {
|
|
989
|
+
return {
|
|
990
|
+
preventDefault: false,
|
|
991
|
+
retry: true
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
const webIntegrationParam = hostConfig.webIntegrationId ? `qlik-web-integration-id=${hostConfig?.webIntegrationId}&` : "";
|
|
995
|
+
const locationUrl = toValidLocationUrl(hostConfig);
|
|
996
|
+
if (hostConfig.authRedirectUserConfirmation) {
|
|
997
|
+
await hostConfig.authRedirectUserConfirmation();
|
|
998
|
+
}
|
|
999
|
+
globalThis.location.replace(
|
|
1000
|
+
`${locationUrl}/login?${webIntegrationParam}returnto=${encodeURIComponent(globalThis.location.href)}`
|
|
1001
|
+
);
|
|
1002
|
+
return {
|
|
1003
|
+
preventDefault: true
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
var cookie_default = {
|
|
1007
|
+
getRestCallAuthParams: getRestCallAuthParams4,
|
|
1008
|
+
getWebSocketAuthParams: getWebSocketAuthParams4,
|
|
1009
|
+
handleAuthenticationError: handleAuthenticationError4,
|
|
1010
|
+
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
1011
|
+
requiredProps: [],
|
|
1012
|
+
optionalProps: ["webIntegrationId", "crossSiteCookies"]
|
|
1013
|
+
})
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
// src/auth/internal/default-auth-modules/none.ts
|
|
1017
|
+
function getRestCallAuthParams5() {
|
|
1018
|
+
return Promise.resolve({ headers: {}, queryParams: {}, credentials: "same-origin" });
|
|
1019
|
+
}
|
|
1020
|
+
function getWebSocketAuthParams5() {
|
|
1021
|
+
return Promise.resolve({ queryParams: {} });
|
|
1022
|
+
}
|
|
1023
|
+
function handleAuthenticationError5() {
|
|
1024
|
+
return Promise.resolve({});
|
|
1025
|
+
}
|
|
1026
|
+
var none_default = {
|
|
1027
|
+
getRestCallAuthParams: getRestCallAuthParams5,
|
|
1028
|
+
getWebSocketAuthParams: getWebSocketAuthParams5,
|
|
1029
|
+
handleAuthenticationError: handleAuthenticationError5,
|
|
1030
|
+
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: [], optionalProps: [] })
|
|
1031
|
+
};
|
|
1032
|
+
|
|
1033
|
+
// src/auth/internal/default-auth-modules/oauth/callback.ts
|
|
1034
|
+
function handleOAuthCallback() {
|
|
1035
|
+
const urlParams = new URLSearchParams(globalThis.location.search);
|
|
1036
|
+
const callbackCode = urlParams.get("code") || void 0;
|
|
1037
|
+
const callbackState = urlParams.get("state") || void 0;
|
|
1038
|
+
if (urlParams.get("error")) {
|
|
1039
|
+
const element = document.createElement("pre");
|
|
1040
|
+
element.innerText = `<code>${JSON.stringify({
|
|
1041
|
+
error: urlParams.get("error"),
|
|
1042
|
+
error_code: urlParams.get("error_code"),
|
|
1043
|
+
error_description: urlParams.get("error_description"),
|
|
1044
|
+
error_detail: urlParams.get("error_detail"),
|
|
1045
|
+
error_uri: urlParams.get("error_uri")
|
|
1046
|
+
})}</code>`;
|
|
1047
|
+
document.body.prepend(element);
|
|
1048
|
+
}
|
|
1049
|
+
const topic = loadAndDeleteFromSessionStorage("", "client-in-progress");
|
|
1050
|
+
if (topic && callbackCode && callbackState) {
|
|
1051
|
+
const stateFromLocalStorage = loadAndDeleteFromSessionStorage(topic, "state");
|
|
1052
|
+
const finalRedirectUri = loadAndDeleteFromSessionStorage(topic, "href");
|
|
1053
|
+
if (stateFromLocalStorage && stateFromLocalStorage === callbackState && finalRedirectUri) {
|
|
1054
|
+
saveInSessionStorage(topic, "code", callbackCode);
|
|
1055
|
+
if (finalRedirectUri !== globalThis.location.href) {
|
|
1056
|
+
globalThis.location.replace(finalRedirectUri);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
924
1062
|
// src/auth/internal/default-auth-modules/oauth/temporary-token.ts
|
|
925
1063
|
async function exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, purpose) {
|
|
926
1064
|
const response = await fetch(`${toValidLocationUrl(hostConfig)}/oauth/token`, {
|
|
@@ -969,17 +1107,17 @@ async function handlePotentialAuthenticationErrorAndRetry(hostConfig, fn) {
|
|
|
969
1107
|
try {
|
|
970
1108
|
return await fn();
|
|
971
1109
|
} catch (err) {
|
|
972
|
-
const { retry } = await
|
|
1110
|
+
const { retry } = await handleAuthenticationError6({
|
|
973
1111
|
hostConfig,
|
|
974
1112
|
canRetry: true
|
|
975
1113
|
});
|
|
976
1114
|
if (retry) {
|
|
977
|
-
return
|
|
1115
|
+
return fn();
|
|
978
1116
|
}
|
|
979
1117
|
throw err;
|
|
980
1118
|
}
|
|
981
1119
|
}
|
|
982
|
-
async function
|
|
1120
|
+
async function getRestCallAuthParams6({
|
|
983
1121
|
hostConfig
|
|
984
1122
|
}) {
|
|
985
1123
|
return {
|
|
@@ -990,7 +1128,7 @@ async function getRestCallAuthParams5({
|
|
|
990
1128
|
credentials: "omit"
|
|
991
1129
|
};
|
|
992
1130
|
}
|
|
993
|
-
async function
|
|
1131
|
+
async function getWebSocketAuthParams6({
|
|
994
1132
|
hostConfig
|
|
995
1133
|
}) {
|
|
996
1134
|
const websocketAccessToken = await handlePotentialAuthenticationErrorAndRetry(hostConfig, async () => {
|
|
@@ -1003,7 +1141,7 @@ async function getWebSocketAuthParams5({
|
|
|
1003
1141
|
}
|
|
1004
1142
|
};
|
|
1005
1143
|
}
|
|
1006
|
-
async function
|
|
1144
|
+
async function getWebResourceAuthParams3({
|
|
1007
1145
|
hostConfig
|
|
1008
1146
|
}) {
|
|
1009
1147
|
const webResourceAccessToken = await handlePotentialAuthenticationErrorAndRetry(hostConfig, async () => {
|
|
@@ -1016,7 +1154,7 @@ async function getWebResourceAuthParams2({
|
|
|
1016
1154
|
}
|
|
1017
1155
|
};
|
|
1018
1156
|
}
|
|
1019
|
-
async function
|
|
1157
|
+
async function handleAuthenticationError6({
|
|
1020
1158
|
hostConfig
|
|
1021
1159
|
}) {
|
|
1022
1160
|
if (hostConfig.getAccessToken) {
|
|
@@ -1042,10 +1180,10 @@ async function handleAuthenticationError5({
|
|
|
1042
1180
|
};
|
|
1043
1181
|
}
|
|
1044
1182
|
var oauth_default = {
|
|
1045
|
-
getRestCallAuthParams:
|
|
1046
|
-
getWebSocketAuthParams:
|
|
1047
|
-
getWebResourceAuthParams:
|
|
1048
|
-
handleAuthenticationError:
|
|
1183
|
+
getRestCallAuthParams: getRestCallAuthParams6,
|
|
1184
|
+
getWebSocketAuthParams: getWebSocketAuthParams6,
|
|
1185
|
+
getWebResourceAuthParams: getWebResourceAuthParams3,
|
|
1186
|
+
handleAuthenticationError: handleAuthenticationError6,
|
|
1049
1187
|
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
1050
1188
|
requiredProps: ["clientId"],
|
|
1051
1189
|
optionalProps: [
|
|
@@ -1084,7 +1222,7 @@ function getXrfKey(hostConfig) {
|
|
|
1084
1222
|
}
|
|
1085
1223
|
|
|
1086
1224
|
// src/auth/internal/default-auth-modules/windows-cookie.ts
|
|
1087
|
-
function
|
|
1225
|
+
function getRestCallAuthParams7({
|
|
1088
1226
|
hostConfig
|
|
1089
1227
|
}) {
|
|
1090
1228
|
return Promise.resolve({
|
|
@@ -1097,7 +1235,7 @@ function getRestCallAuthParams6({
|
|
|
1097
1235
|
credentials: getCredentialsForCookieAuth(hostConfig)
|
|
1098
1236
|
});
|
|
1099
1237
|
}
|
|
1100
|
-
function
|
|
1238
|
+
function getWebSocketAuthParams7({
|
|
1101
1239
|
hostConfig
|
|
1102
1240
|
}) {
|
|
1103
1241
|
return Promise.resolve({
|
|
@@ -1106,7 +1244,7 @@ function getWebSocketAuthParams6({
|
|
|
1106
1244
|
}
|
|
1107
1245
|
});
|
|
1108
1246
|
}
|
|
1109
|
-
async function
|
|
1247
|
+
async function handleAuthenticationError7({
|
|
1110
1248
|
hostConfig
|
|
1111
1249
|
}) {
|
|
1112
1250
|
if (hostConfig.loginUri) {
|
|
@@ -1125,9 +1263,9 @@ async function handleAuthenticationError6({
|
|
|
1125
1263
|
};
|
|
1126
1264
|
}
|
|
1127
1265
|
var windows_cookie_default = {
|
|
1128
|
-
getRestCallAuthParams:
|
|
1129
|
-
getWebSocketAuthParams:
|
|
1130
|
-
handleAuthenticationError:
|
|
1266
|
+
getRestCallAuthParams: getRestCallAuthParams7,
|
|
1267
|
+
getWebSocketAuthParams: getWebSocketAuthParams7,
|
|
1268
|
+
handleAuthenticationError: handleAuthenticationError7,
|
|
1131
1269
|
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
1132
1270
|
requiredProps: [],
|
|
1133
1271
|
optionalProps: ["loginUri", "crossSiteCookies"]
|
|
@@ -1143,6 +1281,7 @@ function registerDefaultAuthModules() {
|
|
|
1143
1281
|
registerAuthModule("cookie", cookie_default);
|
|
1144
1282
|
registerAuthModule("none", none_default);
|
|
1145
1283
|
registerAuthModule("oauth2", oauth_default);
|
|
1284
|
+
registerAuthModule("anonymous", anonymous_default);
|
|
1146
1285
|
registerAuthModule("windowscookie", windows_cookie_default);
|
|
1147
1286
|
authModulesRegistered = true;
|
|
1148
1287
|
}
|
|
@@ -1603,19 +1742,20 @@ async function interceptAuthenticationErrors(hostConfig, resultPromise, performR
|
|
|
1603
1742
|
return await resultPromise;
|
|
1604
1743
|
} catch (error) {
|
|
1605
1744
|
const err = error;
|
|
1606
|
-
|
|
1745
|
+
const errorBody = err.data;
|
|
1746
|
+
if (err.status === 401 || err.status === 403 && errorBody?.code === "CSRF-TOKEN-2" || (err.status === 301 || err.status === 302) && await isWindows(hostConfig)) {
|
|
1607
1747
|
if (globalThis.loggingOut) {
|
|
1608
|
-
return
|
|
1748
|
+
return neverResolvingPromise();
|
|
1609
1749
|
}
|
|
1610
1750
|
const { retry, preventDefault } = await handleAuthenticationError({
|
|
1611
1751
|
hostConfig,
|
|
1612
1752
|
status: err.status,
|
|
1613
1753
|
headers: err.headers,
|
|
1614
|
-
errorBody
|
|
1754
|
+
errorBody,
|
|
1615
1755
|
canRetry: !!performRetry
|
|
1616
1756
|
});
|
|
1617
1757
|
if (retry && performRetry) {
|
|
1618
|
-
return
|
|
1758
|
+
return performRetry();
|
|
1619
1759
|
}
|
|
1620
1760
|
if (preventDefault) {
|
|
1621
1761
|
return neverResolvingPromise();
|
|
@@ -1634,9 +1774,13 @@ function getServiceOverrideHeaderFromLocalStorage() {
|
|
|
1634
1774
|
}
|
|
1635
1775
|
return { "X-Qlik-Overrides": header };
|
|
1636
1776
|
}
|
|
1637
|
-
function toDownloadableBlob(blob) {
|
|
1777
|
+
function toDownloadableBlob(blob, name) {
|
|
1638
1778
|
const result2 = blob;
|
|
1639
|
-
|
|
1779
|
+
if (name) {
|
|
1780
|
+
result2.download = (filename = name) => download(blob, filename);
|
|
1781
|
+
} else {
|
|
1782
|
+
result2.download = (filename) => download(blob, filename);
|
|
1783
|
+
}
|
|
1640
1784
|
return result2;
|
|
1641
1785
|
}
|
|
1642
1786
|
async function download(blob, filename) {
|
|
@@ -1722,25 +1866,39 @@ function clearApiCache(api) {
|
|
|
1722
1866
|
async function parseFetchResponse(fetchResponse, url) {
|
|
1723
1867
|
let resultData;
|
|
1724
1868
|
const contentType = fetchResponse.headers.get("content-type")?.split(";")[0];
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
case "text/event-stream":
|
|
1735
|
-
resultData = fetchResponse.body;
|
|
1736
|
-
break;
|
|
1737
|
-
default:
|
|
1738
|
-
try {
|
|
1739
|
-
resultData = await fetchResponse.text();
|
|
1740
|
-
resultData = JSON.parse(resultData);
|
|
1741
|
-
} catch {
|
|
1869
|
+
const contentDisposition = fetchResponse.headers.get("content-disposition")?.split(";");
|
|
1870
|
+
if (contentDisposition && contentDisposition[0] === "attachment") {
|
|
1871
|
+
let filename = "";
|
|
1872
|
+
for (let i = 1; i < contentDisposition.length; i++) {
|
|
1873
|
+
const attr = contentDisposition[i].trim();
|
|
1874
|
+
if (attr.indexOf("filename") === 0) {
|
|
1875
|
+
const start = attr.indexOf('"');
|
|
1876
|
+
const end = attr.lastIndexOf('"');
|
|
1877
|
+
filename = attr.slice(start + 1, end);
|
|
1742
1878
|
}
|
|
1743
|
-
|
|
1879
|
+
}
|
|
1880
|
+
resultData = toDownloadableBlob(await fetchResponse.blob(), filename);
|
|
1881
|
+
} else {
|
|
1882
|
+
switch (contentType) {
|
|
1883
|
+
case "image/png":
|
|
1884
|
+
case "image/jpeg":
|
|
1885
|
+
case "image/x-icon":
|
|
1886
|
+
case "application/offset+octet-stream":
|
|
1887
|
+
case "application/octet-stream":
|
|
1888
|
+
case "application/zip":
|
|
1889
|
+
resultData = toDownloadableBlob(await fetchResponse.blob());
|
|
1890
|
+
break;
|
|
1891
|
+
case "text/event-stream":
|
|
1892
|
+
resultData = fetchResponse.body;
|
|
1893
|
+
break;
|
|
1894
|
+
default:
|
|
1895
|
+
try {
|
|
1896
|
+
resultData = await fetchResponse.text();
|
|
1897
|
+
resultData = JSON.parse(resultData);
|
|
1898
|
+
} catch {
|
|
1899
|
+
}
|
|
1900
|
+
break;
|
|
1901
|
+
}
|
|
1744
1902
|
}
|
|
1745
1903
|
const { status, statusText, headers } = fetchResponse;
|
|
1746
1904
|
const errorMsg = `request to '${url}' failed with status ${status} ${statusText}.`;
|
|
@@ -1786,6 +1944,7 @@ export {
|
|
|
1786
1944
|
setDefaultHostConfig2 as setDefaultHostConfig,
|
|
1787
1945
|
checkForCrossDomainRequest,
|
|
1788
1946
|
logout,
|
|
1947
|
+
generateRandomString,
|
|
1789
1948
|
InvokeFetchError,
|
|
1790
1949
|
EncodingError,
|
|
1791
1950
|
invokeFetch,
|
|
@@ -1793,6 +1952,5 @@ export {
|
|
|
1793
1952
|
parseFetchResponse,
|
|
1794
1953
|
invoke_fetch_default,
|
|
1795
1954
|
getCsrfToken,
|
|
1796
|
-
generateRandomString,
|
|
1797
1955
|
auth_default
|
|
1798
1956
|
};
|