@qlik/api 0.0.1 → 0.0.3
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/.github/CODEOWNERS +2 -0
- package/.github/workflows/release.yaml +35 -0
- package/README.md +1 -3
- package/api-keys.d.mts +27 -13
- package/api-keys.d.ts +27 -13
- package/api-keys.js +17 -13
- package/api-keys.mjs +12 -8
- package/apps.d.mts +580 -165
- package/apps.d.ts +580 -165
- package/apps.js +111 -44
- package/apps.mjs +78 -11
- package/audits.d.mts +20 -8
- package/audits.d.ts +20 -8
- package/audits.js +12 -11
- package/audits.mjs +7 -6
- package/auth-AWZV4DPP.js +41 -0
- package/{auth-TE272Q34.mjs → auth-CPBNNC7S.mjs} +8 -3
- package/auth.js +4 -3
- package/auth.mjs +3 -2
- package/automations.d.mts +56 -20
- package/automations.d.ts +56 -20
- package/automations.js +32 -25
- package/automations.mjs +18 -11
- package/brands.d.mts +45 -4
- package/brands.d.ts +45 -4
- package/brands.js +20 -15
- package/brands.mjs +7 -2
- package/{chunk-ZT4C7KCQ.js → chunk-2STFUQKQ.js} +3 -3
- package/{chunk-WM7FQU2U.mjs → chunk-3SVRHJII.mjs} +3 -3
- package/{chunk-CKPJE4IA.mjs → chunk-67GJTTPV.mjs} +1 -1
- package/{chunk-4ES65KO3.js → chunk-7RY3NO6N.js} +2 -2
- package/{chunk-4OMEH5SW.mjs → chunk-CYRLVHU3.mjs} +321 -53
- package/{chunk-XASXL2NC.js → chunk-D52VW5UN.js} +323 -55
- package/{chunk-GUQBHY3H.mjs → chunk-GNWU6SP2.mjs} +1 -1
- package/{chunk-4FLMND6T.js → chunk-GV5SRHY2.js} +4 -4
- package/{chunk-OULT3V2U.js → chunk-JNGURO23.js} +3 -3
- package/chunk-P57PW2II.js +11 -0
- package/{chunk-3YE7EI7I.mjs → chunk-TE7XMBT5.mjs} +1 -1
- package/chunk-ZFXKCRJC.mjs +11 -0
- package/collections.d.mts +52 -18
- package/collections.d.ts +52 -18
- package/collections.js +28 -14
- package/collections.mjs +16 -2
- package/csp-origins.d.mts +12 -0
- package/csp-origins.d.ts +12 -0
- package/csp-origins.js +12 -9
- package/csp-origins.mjs +5 -2
- package/data-assets.d.mts +10 -0
- package/data-assets.d.ts +10 -0
- package/data-assets.js +13 -8
- package/data-assets.mjs +7 -2
- package/data-connections.d.mts +20 -0
- package/data-connections.d.ts +20 -0
- package/data-connections.js +19 -12
- package/data-connections.mjs +9 -2
- package/data-credentials.d.mts +10 -0
- package/data-credentials.d.ts +10 -0
- package/data-credentials.js +10 -7
- package/data-credentials.mjs +5 -2
- package/data-files.d.mts +114 -29
- package/data-files.d.ts +114 -29
- package/data-files.js +25 -18
- package/data-files.mjs +15 -8
- package/{enigma-session-TEB53FAF.js → enigma-session-XPXDQAIV.js} +12 -7
- package/{enigma-session-4L373ALV.mjs → enigma-session-ZH6MYA54.mjs} +10 -5
- package/{esm-4X3DKK5D.js → esm-3VXX2GKL.js} +13 -9
- package/{esm-SOWVJKOQ.mjs → esm-OY4XVIJB.mjs} +13 -9
- package/extensions.d.mts +26 -2
- package/extensions.d.ts +26 -2
- package/extensions.js +13 -10
- package/extensions.mjs +5 -2
- package/glossaries.d.mts +55 -20
- package/glossaries.d.ts +55 -20
- package/glossaries.js +39 -27
- package/glossaries.mjs +14 -2
- package/groups.d.mts +29 -13
- package/groups.d.ts +29 -13
- package/groups.js +19 -14
- package/groups.mjs +13 -8
- package/identity-providers.d.mts +23 -7
- package/identity-providers.d.ts +23 -7
- package/identity-providers.js +16 -13
- package/identity-providers.mjs +8 -5
- package/index.js +150 -112
- package/index.mjs +146 -108
- package/{invoke-fetch-MSSJAZ7K.mjs → invoke-fetch-3WZWAAZH.mjs} +4 -1
- package/invoke-fetch-UNTAUR7O.js +17 -0
- package/items.d.mts +25 -22
- package/items.d.ts +25 -22
- package/items.js +17 -14
- package/items.mjs +11 -8
- package/licenses.d.mts +20 -0
- package/licenses.d.ts +20 -0
- package/licenses.js +17 -12
- package/licenses.mjs +7 -2
- package/package.json +7 -18
- package/{qix-RLTISYTB.js → qix-UNWXPGMA.js} +9 -8
- package/{qix-EU7PXRZ6.mjs → qix-ZSJ4PIK3.mjs} +5 -4
- package/qix.d.mts +1066 -1017
- package/qix.d.ts +1066 -1017
- package/qix.js +4 -3
- package/qix.mjs +3 -2
- package/quotas.d.mts +4 -0
- package/quotas.d.ts +4 -0
- package/quotas.js +6 -5
- package/quotas.mjs +3 -2
- package/reload-tasks.d.mts +2 -0
- package/reload-tasks.d.ts +2 -0
- package/reload-tasks.js +11 -8
- package/reload-tasks.mjs +5 -2
- package/reloads.d.mts +20 -11
- package/reloads.d.ts +20 -11
- package/reloads.js +9 -7
- package/reloads.mjs +4 -2
- package/roles.d.mts +4 -0
- package/roles.d.ts +4 -0
- package/roles.js +6 -5
- package/roles.mjs +3 -2
- package/spaces.d.mts +36 -30
- package/spaces.d.ts +36 -30
- package/spaces.js +21 -15
- package/spaces.mjs +8 -2
- package/temp-contents.d.mts +9 -70
- package/temp-contents.d.ts +9 -70
- package/temp-contents.js +10 -29
- package/temp-contents.mjs +5 -24
- package/tenants.d.mts +12 -0
- package/tenants.d.ts +12 -0
- package/tenants.js +14 -9
- package/tenants.mjs +7 -2
- package/themes.d.mts +26 -2
- package/themes.d.ts +26 -2
- package/themes.js +13 -10
- package/themes.mjs +5 -2
- package/transports.d.mts +12 -0
- package/transports.d.ts +12 -0
- package/transports.js +12 -9
- package/transports.mjs +5 -2
- package/users.d.mts +48 -29
- package/users.d.ts +48 -29
- package/users.js +18 -13
- package/users.mjs +7 -2
- package/web-integrations.d.mts +10 -0
- package/web-integrations.d.ts +10 -0
- package/web-integrations.js +11 -8
- package/web-integrations.mjs +5 -2
- package/web-notifications.d.mts +12 -0
- package/web-notifications.d.ts +12 -0
- package/web-notifications.js +12 -9
- package/web-notifications.mjs +5 -2
- package/webhooks.d.mts +27 -7
- package/webhooks.d.ts +27 -7
- package/webhooks.js +17 -13
- package/webhooks.mjs +6 -2
- package/auth-CSVTXOZX.js +0 -36
- package/invoke-fetch-PEI54KZO.js +0 -14
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__require
|
|
3
|
+
} from "./chunk-ZFXKCRJC.mjs";
|
|
4
|
+
|
|
1
5
|
// src/platform/platform-functions.ts
|
|
2
6
|
var getPlatform = async (options = {}) => {
|
|
3
7
|
const isNodeEnvironment = typeof window === "undefined";
|
|
@@ -175,6 +179,21 @@ var InvalidAuthTypeError = class extends Error {
|
|
|
175
179
|
this.name = "InvalidAuthTypeError";
|
|
176
180
|
}
|
|
177
181
|
};
|
|
182
|
+
var AuthorizationError = class extends Error {
|
|
183
|
+
constructor(errors) {
|
|
184
|
+
const errorArray = Array.isArray(errors) ? errors : [errors];
|
|
185
|
+
super(
|
|
186
|
+
errorArray.map(
|
|
187
|
+
(error) => `
|
|
188
|
+
Code: ${error.code}
|
|
189
|
+
Status: ${error.status}
|
|
190
|
+
${error.title}:
|
|
191
|
+
${error.detail}
|
|
192
|
+
`
|
|
193
|
+
).join(",\n")
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
178
197
|
|
|
179
198
|
// src/auth/auth-functions.ts
|
|
180
199
|
function isHostCrossOrigin(hostConfig) {
|
|
@@ -214,6 +233,9 @@ function toValidLocationUrl(hostConfig) {
|
|
|
214
233
|
return locationUrl;
|
|
215
234
|
}
|
|
216
235
|
function toValidEnigmaLocationUrl(hostConfig) {
|
|
236
|
+
return toValidWebsocketLocationUrl(hostConfig);
|
|
237
|
+
}
|
|
238
|
+
function toValidWebsocketLocationUrl(hostConfig) {
|
|
217
239
|
const url = withDefaultHostConfig(hostConfig)?.host;
|
|
218
240
|
let locationUrl;
|
|
219
241
|
if (!url) {
|
|
@@ -462,9 +484,17 @@ var none_default = {
|
|
|
462
484
|
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, { requiredProps: [], optionalProps: [] })
|
|
463
485
|
};
|
|
464
486
|
|
|
487
|
+
// src/utils/utils.ts
|
|
488
|
+
function isBrowser() {
|
|
489
|
+
return typeof window === "object" && typeof window.document === "object";
|
|
490
|
+
}
|
|
491
|
+
function isNode() {
|
|
492
|
+
return typeof process === "object" && typeof __require === "function";
|
|
493
|
+
}
|
|
494
|
+
|
|
465
495
|
// src/auth/internal/default-auth-modules/oauth/storage-helpers.ts
|
|
466
496
|
var storagePrefix = "qlik-qmfe-api";
|
|
467
|
-
var
|
|
497
|
+
var cachedTokens = {};
|
|
468
498
|
function saveInLocalStorage(scope, name, value) {
|
|
469
499
|
localStorage.setItem(`${storagePrefix}-${scope}-${name}`, value);
|
|
470
500
|
}
|
|
@@ -477,11 +507,11 @@ function loadFromLocalStorage(scope, name) {
|
|
|
477
507
|
function loadFromSessionStorage(scope, name) {
|
|
478
508
|
return sessionStorage.getItem(`${storagePrefix}-${scope}-${name}`) || void 0;
|
|
479
509
|
}
|
|
480
|
-
function deleteFromLocalStorage(scope,
|
|
481
|
-
localStorage.removeItem(`${storagePrefix}-${scope}-${name}`);
|
|
510
|
+
function deleteFromLocalStorage(scope, names) {
|
|
511
|
+
names.forEach((name) => localStorage.removeItem(`${storagePrefix}-${scope}-${name}`));
|
|
482
512
|
}
|
|
483
|
-
function deleteFromSessionStorage(scope,
|
|
484
|
-
sessionStorage.removeItem(`${storagePrefix}-${scope}-${name}`);
|
|
513
|
+
function deleteFromSessionStorage(scope, names) {
|
|
514
|
+
names.forEach((name) => sessionStorage.removeItem(`${storagePrefix}-${scope}-${name}`));
|
|
485
515
|
}
|
|
486
516
|
function loadAndDeleteFromSessionStorage(scope, name) {
|
|
487
517
|
const id = `${storagePrefix}-${scope}-${name}`;
|
|
@@ -489,43 +519,70 @@ function loadAndDeleteFromSessionStorage(scope, name) {
|
|
|
489
519
|
sessionStorage.removeItem(id);
|
|
490
520
|
return result2;
|
|
491
521
|
}
|
|
492
|
-
function
|
|
522
|
+
function loadOauthTokensFromStorage(hostConfig) {
|
|
493
523
|
if (!hostConfig.clientId) {
|
|
494
524
|
return void 0;
|
|
495
525
|
}
|
|
526
|
+
let accessToken;
|
|
527
|
+
let refreshToken;
|
|
496
528
|
if (hostConfig.accessTokenStorage === "local") {
|
|
497
|
-
|
|
529
|
+
accessToken = loadFromLocalStorage(hostConfig.clientId, "access-token");
|
|
530
|
+
refreshToken = loadFromLocalStorage(hostConfig.clientId, "refresh-token");
|
|
531
|
+
} else if (hostConfig.accessTokenStorage === "session") {
|
|
532
|
+
accessToken = loadFromSessionStorage(hostConfig.clientId, "access-token");
|
|
533
|
+
refreshToken = loadFromSessionStorage(hostConfig.clientId, "refresh-token");
|
|
498
534
|
}
|
|
499
|
-
if (
|
|
500
|
-
return
|
|
535
|
+
if (accessToken) {
|
|
536
|
+
return {
|
|
537
|
+
accessToken,
|
|
538
|
+
refreshToken
|
|
539
|
+
};
|
|
501
540
|
}
|
|
502
541
|
return void 0;
|
|
503
542
|
}
|
|
504
|
-
async function
|
|
543
|
+
async function loadCachedOauthTokens(hostConfig) {
|
|
544
|
+
return cachedTokens[hostConfig.clientId];
|
|
545
|
+
}
|
|
546
|
+
async function loadOrAcquireAccessToken(hostConfig, acquireTokens) {
|
|
505
547
|
if (!hostConfig.clientId) {
|
|
506
548
|
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
507
549
|
}
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
if (
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
550
|
+
const mayUseStorage = isBrowser();
|
|
551
|
+
const storedOauthTokens = cachedTokens[hostConfig.clientId] || (mayUseStorage ? loadOauthTokensFromStorage(hostConfig) : void 0);
|
|
552
|
+
if (storedOauthTokens) {
|
|
553
|
+
return Promise.resolve(storedOauthTokens);
|
|
554
|
+
}
|
|
555
|
+
const tokensPromise = acquireTokens();
|
|
556
|
+
cachedTokens[hostConfig.clientId] = tokensPromise;
|
|
557
|
+
if (mayUseStorage) {
|
|
558
|
+
const tokens = await tokensPromise;
|
|
559
|
+
if (hostConfig.accessTokenStorage === "local" && tokens) {
|
|
560
|
+
if (tokens.accessToken) {
|
|
561
|
+
saveInLocalStorage(hostConfig.clientId, "access-token", tokens.accessToken);
|
|
562
|
+
}
|
|
563
|
+
if (tokens.refreshToken) {
|
|
564
|
+
saveInLocalStorage(hostConfig.clientId, "refresh-token", tokens.refreshToken);
|
|
565
|
+
}
|
|
566
|
+
} else if (hostConfig.accessTokenStorage === "session" && tokens) {
|
|
567
|
+
if (tokens.accessToken) {
|
|
568
|
+
saveInSessionStorage(hostConfig.clientId, "access-token", tokens.accessToken);
|
|
569
|
+
}
|
|
570
|
+
if (tokens.refreshToken) {
|
|
571
|
+
saveInSessionStorage(hostConfig.clientId, "refresh-token", tokens.refreshToken);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
519
574
|
}
|
|
520
|
-
return
|
|
575
|
+
return tokensPromise;
|
|
521
576
|
}
|
|
522
|
-
function
|
|
577
|
+
function clearStoredOauthTokens(hostConfig) {
|
|
523
578
|
if (!hostConfig.clientId) {
|
|
524
579
|
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
525
580
|
}
|
|
526
|
-
delete
|
|
527
|
-
|
|
528
|
-
|
|
581
|
+
delete cachedTokens[hostConfig.clientId];
|
|
582
|
+
if (isBrowser()) {
|
|
583
|
+
deleteFromLocalStorage(hostConfig.clientId, ["access-token", "refresh-token"]);
|
|
584
|
+
deleteFromSessionStorage(hostConfig.clientId, ["access-token", "refresh-token"]);
|
|
585
|
+
}
|
|
529
586
|
}
|
|
530
587
|
|
|
531
588
|
// src/auth/internal/default-auth-modules/oauth/callback.ts
|
|
@@ -572,16 +629,21 @@ function toBase64Url(uint8Array) {
|
|
|
572
629
|
}
|
|
573
630
|
function byteArrayToBase64(hashArray) {
|
|
574
631
|
let result2 = "";
|
|
575
|
-
if (
|
|
576
|
-
result2 = Buffer.from(hashArray).toString("base64");
|
|
577
|
-
} else if (typeof window !== "undefined" && typeof window.btoa === "function") {
|
|
632
|
+
if (isBrowser()) {
|
|
578
633
|
const byteArrayToString = String.fromCharCode.apply(null, hashArray);
|
|
579
|
-
result2 =
|
|
634
|
+
result2 = btoa(byteArrayToString);
|
|
635
|
+
} else if (isNode()) {
|
|
636
|
+
result2 = Buffer.from(hashArray).toString("base64");
|
|
580
637
|
} else {
|
|
581
|
-
throw new Error("Environment not supported");
|
|
638
|
+
throw new Error("Environment not supported for oauth2 authentication");
|
|
582
639
|
}
|
|
583
640
|
return result2;
|
|
584
641
|
}
|
|
642
|
+
function handlePossibleErrors(data) {
|
|
643
|
+
if (data.errors) {
|
|
644
|
+
throw new AuthorizationError(data.errors);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
585
647
|
async function sha256(message) {
|
|
586
648
|
const msgBuffer = new TextEncoder().encode(message);
|
|
587
649
|
const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", msgBuffer);
|
|
@@ -603,7 +665,7 @@ async function startFullPageLoginFlow(hostConfig) {
|
|
|
603
665
|
const codeChallenge = await sha256(verifier);
|
|
604
666
|
const redirectUri = hostConfig.redirectUri || globalThis.location.href;
|
|
605
667
|
const scopes = ["user_default"];
|
|
606
|
-
|
|
668
|
+
clearStoredOauthTokens(hostConfig);
|
|
607
669
|
saveInSessionStorage(clientId, "state", state);
|
|
608
670
|
saveInSessionStorage(clientId, "verifier", verifier);
|
|
609
671
|
saveInSessionStorage(clientId, "href", globalThis.location.href);
|
|
@@ -638,9 +700,11 @@ async function exchangeCodeAndVerifierForAccessTokenData(hostConfig, code, verif
|
|
|
638
700
|
})
|
|
639
701
|
});
|
|
640
702
|
const data = await result2.json();
|
|
703
|
+
handlePossibleErrors(data);
|
|
641
704
|
return {
|
|
642
705
|
accessToken: data.access_token,
|
|
643
|
-
refreshToken: data.refresh_token
|
|
706
|
+
refreshToken: data.refresh_token,
|
|
707
|
+
errors: data.errors
|
|
644
708
|
};
|
|
645
709
|
} catch (err) {
|
|
646
710
|
console.error(err);
|
|
@@ -648,29 +712,85 @@ async function exchangeCodeAndVerifierForAccessTokenData(hostConfig, code, verif
|
|
|
648
712
|
});
|
|
649
713
|
}
|
|
650
714
|
}
|
|
651
|
-
async function
|
|
715
|
+
async function getOauthTokensWithCredentials(baseUrl, clientId, clientSecret, scope = "user_default") {
|
|
716
|
+
const result2 = await fetch(`${baseUrl}/oauth/token`, {
|
|
717
|
+
method: "POST",
|
|
718
|
+
mode: "cors",
|
|
719
|
+
headers: { "content-type": "application/json" },
|
|
720
|
+
body: JSON.stringify({
|
|
721
|
+
grant_type: "client_credentials",
|
|
722
|
+
client_id: clientId,
|
|
723
|
+
client_secret: clientSecret,
|
|
724
|
+
scope
|
|
725
|
+
})
|
|
726
|
+
});
|
|
727
|
+
const data = await result2.json();
|
|
728
|
+
return {
|
|
729
|
+
accessToken: data.access_token,
|
|
730
|
+
refreshToken: data.refresh_token,
|
|
731
|
+
errors: data.errors
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
async function getOauthTokensWithRefreshToken(baseUrl, refreshToken, clientSecret) {
|
|
735
|
+
const result2 = await fetch(`${baseUrl}/oauth/token`, {
|
|
736
|
+
method: "POST",
|
|
737
|
+
mode: "cors",
|
|
738
|
+
headers: { "content-type": "application/json" },
|
|
739
|
+
body: JSON.stringify({
|
|
740
|
+
grant_type: "refresh_token",
|
|
741
|
+
refresh_token: refreshToken,
|
|
742
|
+
client_secret: clientSecret
|
|
743
|
+
})
|
|
744
|
+
});
|
|
745
|
+
const data = await result2.json();
|
|
746
|
+
return {
|
|
747
|
+
accessToken: data.access_token,
|
|
748
|
+
refreshToken: data.refresh_token,
|
|
749
|
+
errors: data.errors
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
async function getOAuthTokensForNode(hostConfig) {
|
|
753
|
+
const { clientId, clientSecret } = hostConfig;
|
|
754
|
+
if (!clientId || !clientSecret) {
|
|
755
|
+
throw new InvalidHostConfigError(
|
|
756
|
+
'A host config with authType set to "oauth2" has to provide a clientId and a clientSecret'
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
const oauthTokens = await loadOrAcquireAccessToken(
|
|
760
|
+
hostConfig,
|
|
761
|
+
async () => getOauthTokensWithCredentials(
|
|
762
|
+
toValidLocationUrl(hostConfig),
|
|
763
|
+
hostConfig.clientId,
|
|
764
|
+
// @ts-expect-error clientSecret is not yet in HostConfig type
|
|
765
|
+
hostConfig.clientSecret,
|
|
766
|
+
hostConfig.scope
|
|
767
|
+
)
|
|
768
|
+
);
|
|
769
|
+
return oauthTokens;
|
|
770
|
+
}
|
|
771
|
+
async function getOAuthTokensForBrowser(hostConfig) {
|
|
652
772
|
const { clientId } = hostConfig;
|
|
653
773
|
if (!clientId) {
|
|
654
774
|
throw new InvalidHostConfigError('A host config with authType set to "oauth2" has to also provide a clientId');
|
|
655
775
|
}
|
|
656
|
-
const
|
|
776
|
+
const oauthTokens = await loadOrAcquireAccessToken(hostConfig, async () => {
|
|
657
777
|
const code = loadAndDeleteFromSessionStorage(clientId, "code");
|
|
658
778
|
const verifier = loadAndDeleteFromSessionStorage(clientId, "verifier");
|
|
659
779
|
if (code && verifier) {
|
|
660
|
-
const
|
|
780
|
+
const tokenResponse = await exchangeCodeAndVerifierForAccessTokenData(
|
|
661
781
|
hostConfig,
|
|
662
782
|
code,
|
|
663
783
|
verifier,
|
|
664
784
|
hostConfig.redirectUri
|
|
665
785
|
);
|
|
666
|
-
if (
|
|
667
|
-
return
|
|
786
|
+
if (tokenResponse) {
|
|
787
|
+
return tokenResponse;
|
|
668
788
|
}
|
|
669
789
|
}
|
|
670
790
|
return void 0;
|
|
671
791
|
});
|
|
672
|
-
if (
|
|
673
|
-
return
|
|
792
|
+
if (oauthTokens) {
|
|
793
|
+
return oauthTokens;
|
|
674
794
|
}
|
|
675
795
|
if (hostConfig.authRedirectUserConfirmation) {
|
|
676
796
|
await hostConfig.authRedirectUserConfirmation();
|
|
@@ -679,10 +799,41 @@ async function getOAuthAccessTokenInternal(hostConfig) {
|
|
|
679
799
|
return new Promise(() => {
|
|
680
800
|
});
|
|
681
801
|
}
|
|
682
|
-
var
|
|
802
|
+
var lastOauthTokensCall = Promise.resolve("");
|
|
683
803
|
async function getOAuthAccessToken(hostConfig) {
|
|
684
|
-
|
|
685
|
-
|
|
804
|
+
let getOauthTokensCall;
|
|
805
|
+
if (isNode()) {
|
|
806
|
+
getOauthTokensCall = getOAuthTokensForNode;
|
|
807
|
+
} else {
|
|
808
|
+
getOauthTokensCall = getOAuthTokensForBrowser;
|
|
809
|
+
}
|
|
810
|
+
lastOauthTokensCall = lastOauthTokensCall.then(async () => {
|
|
811
|
+
const tokens = await getOauthTokensCall(hostConfig);
|
|
812
|
+
if (tokens) {
|
|
813
|
+
handlePossibleErrors(tokens);
|
|
814
|
+
return tokens.accessToken || "";
|
|
815
|
+
}
|
|
816
|
+
return "";
|
|
817
|
+
});
|
|
818
|
+
return lastOauthTokensCall;
|
|
819
|
+
}
|
|
820
|
+
async function refreshAccessToken(hostConfig) {
|
|
821
|
+
const tokens = await loadCachedOauthTokens(hostConfig);
|
|
822
|
+
clearStoredOauthTokens(hostConfig);
|
|
823
|
+
if (tokens && tokens.refreshToken) {
|
|
824
|
+
const refreshedTokens = await loadOrAcquireAccessToken(
|
|
825
|
+
hostConfig,
|
|
826
|
+
async () => getOauthTokensWithRefreshToken(
|
|
827
|
+
toValidLocationUrl(hostConfig),
|
|
828
|
+
tokens.refreshToken,
|
|
829
|
+
// @ts-expect-error clientSecret is not yet in HostConfig type
|
|
830
|
+
hostConfig.clientSecret
|
|
831
|
+
)
|
|
832
|
+
);
|
|
833
|
+
if (refreshedTokens) {
|
|
834
|
+
handlePossibleErrors(refreshedTokens);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
686
837
|
}
|
|
687
838
|
|
|
688
839
|
// src/auth/internal/default-auth-modules/oauth/temporary-token.ts
|
|
@@ -715,7 +866,7 @@ async function exchangeAccessTokenForTemporaryToken(hostConfig, accessToken, pur
|
|
|
715
866
|
}
|
|
716
867
|
|
|
717
868
|
// src/auth/internal/default-auth-modules/oauth.ts
|
|
718
|
-
if (
|
|
869
|
+
if (isBrowser()) {
|
|
719
870
|
handleOAuthCallback();
|
|
720
871
|
}
|
|
721
872
|
async function getRestCallAuthParams5({
|
|
@@ -754,12 +905,19 @@ async function getWebResourceAuthParams2({
|
|
|
754
905
|
async function handleAuthenticationError5({
|
|
755
906
|
hostConfig
|
|
756
907
|
}) {
|
|
757
|
-
if (
|
|
758
|
-
|
|
908
|
+
if (isBrowser()) {
|
|
909
|
+
if (hostConfig.authRedirectUserConfirmation) {
|
|
910
|
+
await hostConfig.authRedirectUserConfirmation();
|
|
911
|
+
}
|
|
912
|
+
startFullPageLoginFlow(hostConfig);
|
|
913
|
+
return {
|
|
914
|
+
preventDefault: true
|
|
915
|
+
};
|
|
759
916
|
}
|
|
760
|
-
|
|
917
|
+
await refreshAccessToken(hostConfig);
|
|
761
918
|
return {
|
|
762
|
-
preventDefault:
|
|
919
|
+
preventDefault: false,
|
|
920
|
+
retry: true
|
|
763
921
|
};
|
|
764
922
|
}
|
|
765
923
|
var oauth_default = {
|
|
@@ -769,7 +927,7 @@ var oauth_default = {
|
|
|
769
927
|
handleAuthenticationError: handleAuthenticationError5,
|
|
770
928
|
validateHostConfig: (hostConfig) => internalValidateHostConfig(hostConfig, {
|
|
771
929
|
requiredProps: ["clientId"],
|
|
772
|
-
optionalProps: ["redirectUri", "accessTokenStorage"]
|
|
930
|
+
optionalProps: ["clientSecret", "redirectUri", "accessTokenStorage"]
|
|
773
931
|
})
|
|
774
932
|
};
|
|
775
933
|
|
|
@@ -870,6 +1028,7 @@ var auth = {
|
|
|
870
1028
|
handleAuthenticationError,
|
|
871
1029
|
toValidLocationUrl,
|
|
872
1030
|
toValidEnigmaLocationUrl,
|
|
1031
|
+
toValidWebsocketLocationUrl,
|
|
873
1032
|
isWindows,
|
|
874
1033
|
isHostCrossOrigin
|
|
875
1034
|
};
|
|
@@ -1013,9 +1172,10 @@ async function fetchAndTransformExceptions(input, init) {
|
|
|
1013
1172
|
return Promise.reject(new InvokeFetchError(getErrorMessage(e), 0, new Headers(), {}));
|
|
1014
1173
|
}
|
|
1015
1174
|
}
|
|
1016
|
-
async function performActualHttpFetch(method, completeUrl,
|
|
1175
|
+
async function performActualHttpFetch(method, completeUrl, unencodedBody, contentType, options, interceptors, authHeaders, credentials) {
|
|
1176
|
+
const { body, contentTypeHeader, requestOptions } = encodeBody(unencodedBody, contentType ?? "");
|
|
1017
1177
|
const headers = {
|
|
1018
|
-
|
|
1178
|
+
...contentTypeHeader,
|
|
1019
1179
|
...authHeaders,
|
|
1020
1180
|
...options?.headers
|
|
1021
1181
|
};
|
|
@@ -1026,8 +1186,10 @@ async function performActualHttpFetch(method, completeUrl, body, options, interc
|
|
|
1026
1186
|
mode: isCrossOrigin ? "cors" : "same-origin",
|
|
1027
1187
|
headers,
|
|
1028
1188
|
redirect: await isWindows(options?.hostConfig) ? "manual" : "follow",
|
|
1029
|
-
body
|
|
1189
|
+
body,
|
|
1030
1190
|
// body data type must match "Content-Type" header
|
|
1191
|
+
...requestOptions
|
|
1192
|
+
// This adds 'duplex: "half"' if we're sending application/octet-stream, needed in node only.
|
|
1031
1193
|
};
|
|
1032
1194
|
let fetchTimeoutId;
|
|
1033
1195
|
if (options?.timeoutMs && options.timeoutMs > 0) {
|
|
@@ -1050,6 +1212,98 @@ async function performActualHttpFetch(method, completeUrl, body, options, interc
|
|
|
1050
1212
|
}
|
|
1051
1213
|
return invokeFetchResponse;
|
|
1052
1214
|
}
|
|
1215
|
+
function encodeBody(unencodedBody, contentType) {
|
|
1216
|
+
if (!unencodedBody) {
|
|
1217
|
+
return { body: null, contentTypeHeader: {}, requestOptions: {} };
|
|
1218
|
+
}
|
|
1219
|
+
const contentTypeHeader = {};
|
|
1220
|
+
const requestOptions = {};
|
|
1221
|
+
let body = null;
|
|
1222
|
+
switch (contentType) {
|
|
1223
|
+
case "":
|
|
1224
|
+
case "application/json":
|
|
1225
|
+
contentTypeHeader["Content-Type"] = "application/json";
|
|
1226
|
+
body = JSON.stringify(unencodedBody);
|
|
1227
|
+
break;
|
|
1228
|
+
case "multipart/form-data":
|
|
1229
|
+
body = encodeMultipartBody(unencodedBody);
|
|
1230
|
+
break;
|
|
1231
|
+
case "application/octet-stream":
|
|
1232
|
+
contentTypeHeader["Content-Type"] = contentType;
|
|
1233
|
+
requestOptions["duplex"] = "half";
|
|
1234
|
+
body = unencodedBody;
|
|
1235
|
+
break;
|
|
1236
|
+
case "text/plain":
|
|
1237
|
+
if (typeof unencodedBody === "string") {
|
|
1238
|
+
contentTypeHeader["Content-Type"] = contentType;
|
|
1239
|
+
body = unencodedBody;
|
|
1240
|
+
} else {
|
|
1241
|
+
throw new EncodingError(
|
|
1242
|
+
`Cannot send ${typeof unencodedBody} as ${contentType}, body should be a string.`,
|
|
1243
|
+
contentType,
|
|
1244
|
+
unencodedBody
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
break;
|
|
1248
|
+
default:
|
|
1249
|
+
throw new EncodingError(
|
|
1250
|
+
`Unsupported content-type "${contentType}", supported are: application/json, multipart/form-data, application/octet-stream and text/plain`,
|
|
1251
|
+
contentType,
|
|
1252
|
+
unencodedBody
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
return { body, contentTypeHeader, requestOptions };
|
|
1256
|
+
}
|
|
1257
|
+
function encodeMultipartBody(unencodedBody) {
|
|
1258
|
+
const contentType = "multipart/form-data";
|
|
1259
|
+
if (typeof unencodedBody !== "object") {
|
|
1260
|
+
throw new EncodingError(
|
|
1261
|
+
`Cannot encode ${typeof unencodedBody} as ${contentType}, body should be an object.`,
|
|
1262
|
+
contentType,
|
|
1263
|
+
unencodedBody
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
1266
|
+
if (Array.isArray(unencodedBody)) {
|
|
1267
|
+
throw new EncodingError(
|
|
1268
|
+
`Cannot encode ${typeof unencodedBody} as ${contentType}, body should be an object.`,
|
|
1269
|
+
contentType,
|
|
1270
|
+
unencodedBody
|
|
1271
|
+
);
|
|
1272
|
+
}
|
|
1273
|
+
if (unencodedBody instanceof FormData) {
|
|
1274
|
+
return unencodedBody;
|
|
1275
|
+
}
|
|
1276
|
+
const form = new FormData();
|
|
1277
|
+
Object.entries(unencodedBody).forEach((entry) => {
|
|
1278
|
+
const [key, value] = entry;
|
|
1279
|
+
switch (typeof value) {
|
|
1280
|
+
case "boolean":
|
|
1281
|
+
case "number":
|
|
1282
|
+
case "string":
|
|
1283
|
+
form.set(key, `${value}`);
|
|
1284
|
+
break;
|
|
1285
|
+
case "object":
|
|
1286
|
+
if (value instanceof Blob) {
|
|
1287
|
+
form.set(key, value);
|
|
1288
|
+
} else if (value instanceof Uint8Array) {
|
|
1289
|
+
const data = new Blob([value], { type: "application/octet-stream" });
|
|
1290
|
+
form.set(key, data);
|
|
1291
|
+
} else {
|
|
1292
|
+
const json = JSON.stringify(value);
|
|
1293
|
+
const data = new Blob([json], { type: "application/json" });
|
|
1294
|
+
form.set(key, data, "");
|
|
1295
|
+
}
|
|
1296
|
+
break;
|
|
1297
|
+
default:
|
|
1298
|
+
throw new EncodingError(
|
|
1299
|
+
`Cannot encode multipart-field "${key}" with value of type ${typeof value}, values must be objects, strings, numbers or boolean.`,
|
|
1300
|
+
contentType,
|
|
1301
|
+
unencodedBody
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
});
|
|
1305
|
+
return form;
|
|
1306
|
+
}
|
|
1053
1307
|
async function getInvokeFetchUrlParams({
|
|
1054
1308
|
method,
|
|
1055
1309
|
pathTemplate,
|
|
@@ -1089,7 +1343,7 @@ function invokeFetchWithUrl(api, props, interceptors) {
|
|
|
1089
1343
|
interceptors
|
|
1090
1344
|
);
|
|
1091
1345
|
}
|
|
1092
|
-
function invokeFetchWithUrlAndRetry(api, { method, completeUrl, cacheKey, body, options, authHeaders, credentials }, performRetry, interceptors) {
|
|
1346
|
+
function invokeFetchWithUrlAndRetry(api, { method, completeUrl, cacheKey, body, options, authHeaders, credentials, contentType }, performRetry, interceptors) {
|
|
1093
1347
|
if (!cache[api]) {
|
|
1094
1348
|
cache[api] = {};
|
|
1095
1349
|
}
|
|
@@ -1107,6 +1361,7 @@ function invokeFetchWithUrlAndRetry(api, { method, completeUrl, cacheKey, body,
|
|
|
1107
1361
|
method,
|
|
1108
1362
|
completeUrl,
|
|
1109
1363
|
body,
|
|
1364
|
+
contentType,
|
|
1110
1365
|
options,
|
|
1111
1366
|
interceptors,
|
|
1112
1367
|
authHeaders,
|
|
@@ -1246,6 +1501,16 @@ var InvokeFetchError = class extends Error {
|
|
|
1246
1501
|
this.stack = cleanStack(this.stack);
|
|
1247
1502
|
}
|
|
1248
1503
|
};
|
|
1504
|
+
var EncodingError = class extends Error {
|
|
1505
|
+
contentType;
|
|
1506
|
+
data;
|
|
1507
|
+
constructor(errorMessage, contentType, data) {
|
|
1508
|
+
super(errorMessage);
|
|
1509
|
+
this.contentType = contentType;
|
|
1510
|
+
this.data = data;
|
|
1511
|
+
this.stack = cleanStack(this.stack);
|
|
1512
|
+
}
|
|
1513
|
+
};
|
|
1249
1514
|
var regex = /^.+\/qmfe-api(?:\.js)?:(\d+)(?::\d+)?$/gim;
|
|
1250
1515
|
var isFromQmfeApi = (line) => {
|
|
1251
1516
|
const matches = line.match(regex);
|
|
@@ -1316,10 +1581,12 @@ export {
|
|
|
1316
1581
|
InvalidHostConfigError,
|
|
1317
1582
|
UnexpectedAuthTypeError,
|
|
1318
1583
|
InvalidAuthTypeError,
|
|
1584
|
+
AuthorizationError,
|
|
1319
1585
|
isHostCrossOrigin,
|
|
1320
1586
|
isWindows,
|
|
1321
1587
|
toValidLocationUrl,
|
|
1322
1588
|
toValidEnigmaLocationUrl,
|
|
1589
|
+
toValidWebsocketLocationUrl,
|
|
1323
1590
|
getWebSocketAuthParams,
|
|
1324
1591
|
getWebResourceAuthParams,
|
|
1325
1592
|
handleAuthenticationError,
|
|
@@ -1329,6 +1596,7 @@ export {
|
|
|
1329
1596
|
checkForCrossDomainRequest,
|
|
1330
1597
|
logout,
|
|
1331
1598
|
InvokeFetchError,
|
|
1599
|
+
EncodingError,
|
|
1332
1600
|
invokeFetch,
|
|
1333
1601
|
clearApiCache,
|
|
1334
1602
|
parseFetchResponse,
|