@replicated/portal-components 0.0.12 → 0.0.13
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/components/metadata/registry.json +2 -2
- package/components/metadata/registry.md +2 -2
- package/dist/actions/index.d.mts +26 -4
- package/dist/actions/index.d.ts +26 -4
- package/dist/actions/index.js +171 -124
- package/dist/actions/index.js.map +1 -1
- package/dist/airgap-instances.js.map +1 -1
- package/dist/esm/actions/index.js +170 -124
- package/dist/esm/actions/index.js.map +1 -1
- package/dist/esm/airgap-instances.js.map +1 -1
- package/dist/esm/helm-install-wizard.js +15 -9
- package/dist/esm/helm-install-wizard.js.map +1 -1
- package/dist/esm/index.js +127 -108
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-actions.js +42 -47
- package/dist/esm/install-actions.js.map +1 -1
- package/dist/esm/instance-card.js.map +1 -1
- package/dist/esm/license-details.js +20 -10
- package/dist/esm/license-details.js.map +1 -1
- package/dist/esm/linux-install-wizard.js +26 -47
- package/dist/esm/linux-install-wizard.js.map +1 -1
- package/dist/esm/online-instance-list.js.map +1 -1
- package/dist/esm/support-card.js +18 -49
- package/dist/esm/support-card.js.map +1 -1
- package/dist/esm/top-nav.js +13 -31
- package/dist/esm/top-nav.js.map +1 -1
- package/dist/esm/update-layout.js +13 -31
- package/dist/esm/update-layout.js.map +1 -1
- package/dist/esm/utils/index.js +14 -10
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/helm-install-wizard.js +15 -9
- package/dist/helm-install-wizard.js.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +126 -106
- package/dist/index.js.map +1 -1
- package/dist/install-actions.js +43 -48
- package/dist/install-actions.js.map +1 -1
- package/dist/instance-card.js.map +1 -1
- package/dist/license-details.js +20 -10
- package/dist/license-details.js.map +1 -1
- package/dist/linux-install-wizard.js +26 -47
- package/dist/linux-install-wizard.js.map +1 -1
- package/dist/online-instance-list.js.map +1 -1
- package/dist/support-card.js +18 -49
- package/dist/support-card.js.map +1 -1
- package/dist/top-nav.js +13 -31
- package/dist/top-nav.js.map +1 -1
- package/dist/update-layout.js +13 -31
- package/dist/update-layout.js.map +1 -1
- package/dist/utils/index.js +14 -10
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/actions/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var buffer = require('buffer');
|
|
3
4
|
var react = require('react');
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -73,10 +74,10 @@ var createServiceAccount = defineServerAction({
|
|
|
73
74
|
if (!name || typeof name !== "string" || !name.trim()) {
|
|
74
75
|
throw new Error("Service account name is required");
|
|
75
76
|
}
|
|
76
|
-
const endpoint = `${getApiOrigin()}/
|
|
77
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts`;
|
|
77
78
|
if (process.env.NODE_ENV !== "production") {
|
|
78
79
|
console.debug(
|
|
79
|
-
"[portal-components] creating service account via %s",
|
|
80
|
+
"[portal-components] creating service account via %s (Enterprise Portal API)",
|
|
80
81
|
endpoint
|
|
81
82
|
);
|
|
82
83
|
}
|
|
@@ -104,7 +105,7 @@ var initiateLogin = defineServerAction({
|
|
|
104
105
|
visibility: "customer",
|
|
105
106
|
tags: ["auth", "login", "session"],
|
|
106
107
|
async run(input) {
|
|
107
|
-
const endpoint = `${getApiOrigin()}/
|
|
108
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/auth/magic-link`;
|
|
108
109
|
const appSlug = process.env.PORTAL_APP_SLUG;
|
|
109
110
|
if (!appSlug) {
|
|
110
111
|
throw new Error("PORTAL_APP_SLUG is not configured");
|
|
@@ -154,7 +155,7 @@ var verifyMagicLink = defineServerAction({
|
|
|
154
155
|
visibility: "customer",
|
|
155
156
|
tags: ["auth", "login", "verify"],
|
|
156
157
|
async run({ nonce }) {
|
|
157
|
-
const endpoint = `${getApiOrigin()}/
|
|
158
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/auth/magic-link/verify`;
|
|
158
159
|
if (process.env.NODE_ENV !== "production") {
|
|
159
160
|
console.debug(
|
|
160
161
|
"[portal-components] verifying magic link via %s",
|
|
@@ -210,12 +211,12 @@ var fetchCustomBrandingImpl = async () => {
|
|
|
210
211
|
if (!appSlug) {
|
|
211
212
|
throw new Error("PORTAL_APP_SLUG is not configured");
|
|
212
213
|
}
|
|
213
|
-
const url = `${getApiOrigin()}/
|
|
214
|
+
const url = `${getApiOrigin()}/enterprise-portal/public/branding?app_slug=${encodeURIComponent(
|
|
214
215
|
appSlug
|
|
215
216
|
)}`;
|
|
216
217
|
if (process.env.NODE_ENV !== "production") {
|
|
217
218
|
console.debug(
|
|
218
|
-
"[portal-components] fetching custom branding via %s",
|
|
219
|
+
"[portal-components] fetching custom branding via %s (Enterprise Portal API)",
|
|
219
220
|
url
|
|
220
221
|
);
|
|
221
222
|
}
|
|
@@ -230,13 +231,18 @@ var fetchCustomBrandingImpl = async () => {
|
|
|
230
231
|
);
|
|
231
232
|
}
|
|
232
233
|
const payload = await response.json();
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
const brandingObject = {
|
|
235
|
+
logo: payload.logoUrl,
|
|
236
|
+
title: payload.appName,
|
|
237
|
+
customColor1: payload.primaryColor,
|
|
238
|
+
customColor2: payload.secondaryColor,
|
|
239
|
+
favicon: payload.faviconUrl
|
|
240
|
+
};
|
|
241
|
+
const brandingData = buffer.Buffer.from(JSON.stringify(brandingObject)).toString("base64");
|
|
237
242
|
return {
|
|
238
243
|
brandingData,
|
|
239
|
-
documentation:
|
|
244
|
+
documentation: null
|
|
245
|
+
// Documentation not included in new API's public endpoint
|
|
240
246
|
};
|
|
241
247
|
};
|
|
242
248
|
var fetchCustomBranding = react.cache(fetchCustomBrandingImpl);
|
|
@@ -253,7 +259,7 @@ var decodeJwtPayload = (token) => {
|
|
|
253
259
|
payloadSegment.length + (4 - payloadSegment.length % 4) % 4,
|
|
254
260
|
"="
|
|
255
261
|
);
|
|
256
|
-
const decoded = Buffer.from(padded, "base64").toString("utf-8");
|
|
262
|
+
const decoded = buffer.Buffer.from(padded, "base64").toString("utf-8");
|
|
257
263
|
return JSON.parse(decoded);
|
|
258
264
|
};
|
|
259
265
|
var getCustomerIdFromToken = (token) => {
|
|
@@ -264,22 +270,6 @@ var getCustomerIdFromToken = (token) => {
|
|
|
264
270
|
}
|
|
265
271
|
return customerId.trim();
|
|
266
272
|
};
|
|
267
|
-
var resolveSupportBundlesEndpoint = () => {
|
|
268
|
-
const fallback = `${getApiOrigin()}/v3/supportbundles`;
|
|
269
|
-
const explicit = process.env.SUPPORT_BUNDLES_ENDPOINT;
|
|
270
|
-
if (!explicit) {
|
|
271
|
-
return new URL(fallback);
|
|
272
|
-
}
|
|
273
|
-
try {
|
|
274
|
-
return new URL(explicit);
|
|
275
|
-
} catch (error) {
|
|
276
|
-
console.warn(
|
|
277
|
-
`[portal-components] invalid SUPPORT_BUNDLES_ENDPOINT, using fallback`,
|
|
278
|
-
error
|
|
279
|
-
);
|
|
280
|
-
return new URL(fallback);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
273
|
var listSupportBundles = defineServerAction({
|
|
284
274
|
id: "support/list-bundles",
|
|
285
275
|
description: "Fetches support bundles associated with the customer found in the portal session JWT.",
|
|
@@ -289,17 +279,11 @@ var listSupportBundles = defineServerAction({
|
|
|
289
279
|
if (!token || typeof token !== "string") {
|
|
290
280
|
throw new Error("Support bundle listing requires a session token");
|
|
291
281
|
}
|
|
292
|
-
const
|
|
293
|
-
const customerId = payload?.customer_id;
|
|
294
|
-
if (typeof customerId !== "string" || !customerId.trim()) {
|
|
295
|
-
throw new Error("Unable to determine customer_id from session token");
|
|
296
|
-
}
|
|
297
|
-
const url = resolveSupportBundlesEndpoint();
|
|
298
|
-
url.searchParams.set("customer_id", customerId.trim());
|
|
282
|
+
const url = `${getApiOrigin()}/enterprise-portal/support-bundles`;
|
|
299
283
|
if (process.env.NODE_ENV !== "production") {
|
|
300
|
-
console.debug("[portal-components] fetching support bundles via %s", url);
|
|
284
|
+
console.debug("[portal-components] fetching support bundles via %s (Enterprise Portal API)", url);
|
|
301
285
|
}
|
|
302
|
-
const response = await authenticatedFetch(url
|
|
286
|
+
const response = await authenticatedFetch(url, {
|
|
303
287
|
token,
|
|
304
288
|
headers: {
|
|
305
289
|
accept: "application/json"
|
|
@@ -314,7 +298,8 @@ var listSupportBundles = defineServerAction({
|
|
|
314
298
|
`Support bundles request failed (${response.status} ${response.statusText})`
|
|
315
299
|
);
|
|
316
300
|
}
|
|
317
|
-
const
|
|
301
|
+
const payload = await response.json();
|
|
302
|
+
const raw = payload.data;
|
|
318
303
|
const rawRecord = raw && typeof raw === "object" ? raw : void 0;
|
|
319
304
|
const parseInsights = (raw2) => {
|
|
320
305
|
if (!Array.isArray(raw2)) return void 0;
|
|
@@ -405,12 +390,8 @@ var downloadSupportBundle = defineServerAction({
|
|
|
405
390
|
if (!bundleId || typeof bundleId !== "string") {
|
|
406
391
|
throw new Error("Support bundle download requires a bundle ID");
|
|
407
392
|
}
|
|
408
|
-
const
|
|
409
|
-
const
|
|
410
|
-
if (typeof customerId !== "string" || !customerId.trim()) {
|
|
411
|
-
throw new Error("Unable to determine customer_id from session token");
|
|
412
|
-
}
|
|
413
|
-
const endpoint = `${getApiOrigin()}/v3/supportbundle/${encodeURIComponent(bundleId)}/download?customer_id=${encodeURIComponent(customerId.trim())}`;
|
|
393
|
+
const customerId = getCustomerIdFromToken(token);
|
|
394
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/${encodeURIComponent(bundleId)}/download?customer_id=${encodeURIComponent(customerId)}`;
|
|
414
395
|
if (process.env.NODE_ENV !== "production") {
|
|
415
396
|
console.debug("[portal-components] getting support bundle download URL via %s", endpoint);
|
|
416
397
|
}
|
|
@@ -448,12 +429,8 @@ var deleteSupportBundle = defineServerAction({
|
|
|
448
429
|
if (!bundleId || typeof bundleId !== "string") {
|
|
449
430
|
throw new Error("Support bundle deletion requires a bundle ID");
|
|
450
431
|
}
|
|
451
|
-
const
|
|
452
|
-
const
|
|
453
|
-
if (typeof customerId !== "string" || !customerId.trim()) {
|
|
454
|
-
throw new Error("Unable to determine customer_id from session token");
|
|
455
|
-
}
|
|
456
|
-
const endpoint = `${getApiOrigin()}/v3/supportbundle/${encodeURIComponent(bundleId)}?customer_id=${encodeURIComponent(customerId.trim())}`;
|
|
432
|
+
const customerId = getCustomerIdFromToken(token);
|
|
433
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/${encodeURIComponent(bundleId)}?customer_id=${encodeURIComponent(customerId)}`;
|
|
457
434
|
if (process.env.NODE_ENV !== "production") {
|
|
458
435
|
console.debug("[portal-components] deleting support bundle via %s", endpoint);
|
|
459
436
|
}
|
|
@@ -492,7 +469,7 @@ var uploadSupportBundle = defineServerAction({
|
|
|
492
469
|
if (!fileContent || !(fileContent instanceof ArrayBuffer)) {
|
|
493
470
|
throw new Error("Support bundle upload requires file content");
|
|
494
471
|
}
|
|
495
|
-
const endpoint = `${getApiOrigin()}/
|
|
472
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;
|
|
496
473
|
if (process.env.NODE_ENV !== "production") {
|
|
497
474
|
console.debug("[portal-components] uploading support bundle via %s", endpoint);
|
|
498
475
|
}
|
|
@@ -520,7 +497,7 @@ var uploadSupportBundle = defineServerAction({
|
|
|
520
497
|
}
|
|
521
498
|
});
|
|
522
499
|
var getSupportBundleUploadUrl = (appId) => {
|
|
523
|
-
return `${getApiOrigin()}/
|
|
500
|
+
return `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;
|
|
524
501
|
};
|
|
525
502
|
var listReleases = defineServerAction({
|
|
526
503
|
id: "releases/list",
|
|
@@ -531,10 +508,10 @@ var listReleases = defineServerAction({
|
|
|
531
508
|
if (!token || typeof token !== "string") {
|
|
532
509
|
throw new Error("List releases requires a session token");
|
|
533
510
|
}
|
|
534
|
-
const endpoint = `${getApiOrigin()}/
|
|
535
|
-
|
|
536
|
-
endpoint
|
|
537
|
-
}
|
|
511
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/releases`;
|
|
512
|
+
if (process.env.NODE_ENV !== "production") {
|
|
513
|
+
console.debug("[portal-components] fetching releases via %s (Enterprise Portal API)", endpoint);
|
|
514
|
+
}
|
|
538
515
|
const response = await authenticatedFetch(endpoint, {
|
|
539
516
|
method: "GET",
|
|
540
517
|
token,
|
|
@@ -547,7 +524,6 @@ var listReleases = defineServerAction({
|
|
|
547
524
|
console.warn("[portal-components] listReleases read error", error);
|
|
548
525
|
return null;
|
|
549
526
|
});
|
|
550
|
-
console.log("[portal-components] listReleases response", response.status, bodyText);
|
|
551
527
|
if (!response.ok) {
|
|
552
528
|
throw new Error(
|
|
553
529
|
`List releases request failed (${response.status} ${response.statusText})`
|
|
@@ -844,7 +820,10 @@ var fetchLicenseDetails = defineServerAction({
|
|
|
844
820
|
if (typeof token !== "string" || token.trim().length === 0) {
|
|
845
821
|
throw new Error("fetchLicenseDetails requires a non-empty token");
|
|
846
822
|
}
|
|
847
|
-
const endpoint = `${getApiOrigin()}/
|
|
823
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
824
|
+
if (process.env.NODE_ENV !== "production") {
|
|
825
|
+
console.debug("[portal-components] fetching license via %s (Enterprise Portal API)", endpoint);
|
|
826
|
+
}
|
|
848
827
|
const response = await authenticatedFetch(endpoint, {
|
|
849
828
|
method: "GET",
|
|
850
829
|
token,
|
|
@@ -859,10 +838,11 @@ var fetchLicenseDetails = defineServerAction({
|
|
|
859
838
|
);
|
|
860
839
|
}
|
|
861
840
|
const payload = await response.json();
|
|
862
|
-
const
|
|
841
|
+
const licenseData = payload.data;
|
|
842
|
+
const license = normalizeLicensePayload(licenseData);
|
|
863
843
|
return {
|
|
864
844
|
license,
|
|
865
|
-
raw:
|
|
845
|
+
raw: licenseData ?? null
|
|
866
846
|
};
|
|
867
847
|
}
|
|
868
848
|
});
|
|
@@ -875,7 +855,10 @@ var fetchInstallOptions = defineServerAction({
|
|
|
875
855
|
if (typeof token !== "string" || token.trim().length === 0) {
|
|
876
856
|
throw new Error("fetchInstallOptions requires a non-empty token");
|
|
877
857
|
}
|
|
878
|
-
const endpoint = `${getApiOrigin()}/
|
|
858
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
859
|
+
if (process.env.NODE_ENV !== "production") {
|
|
860
|
+
console.debug("[portal-components] fetching install options via %s (Enterprise Portal API)", endpoint);
|
|
861
|
+
}
|
|
879
862
|
const response = await authenticatedFetch(endpoint, {
|
|
880
863
|
method: "GET",
|
|
881
864
|
token,
|
|
@@ -889,7 +872,8 @@ var fetchInstallOptions = defineServerAction({
|
|
|
889
872
|
`License request failed (${response.status} ${response.statusText})`
|
|
890
873
|
);
|
|
891
874
|
}
|
|
892
|
-
const
|
|
875
|
+
const envelope = await response.json();
|
|
876
|
+
const licenseData = envelope.data;
|
|
893
877
|
const getBoolean2 = (obj, key) => {
|
|
894
878
|
if (obj && typeof obj === "object" && key in obj) {
|
|
895
879
|
const val = obj[key];
|
|
@@ -897,9 +881,8 @@ var fetchInstallOptions = defineServerAction({
|
|
|
897
881
|
}
|
|
898
882
|
return false;
|
|
899
883
|
};
|
|
900
|
-
const
|
|
901
|
-
const
|
|
902
|
-
const showHelm = getBoolean2(license, "isHelmInstallEnabled");
|
|
884
|
+
const showLinux = getBoolean2(licenseData, "isEmbeddedClusterDownloadEnabled");
|
|
885
|
+
const showHelm = getBoolean2(licenseData, "isHelmInstallEnabled");
|
|
903
886
|
return {
|
|
904
887
|
showLinux,
|
|
905
888
|
showHelm
|
|
@@ -915,7 +898,10 @@ var fetchLicenseSummary = defineServerAction({
|
|
|
915
898
|
if (typeof token !== "string" || token.trim().length === 0) {
|
|
916
899
|
throw new Error("fetchLicenseSummary requires a non-empty token");
|
|
917
900
|
}
|
|
918
|
-
const endpoint = `${getApiOrigin()}/
|
|
901
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
902
|
+
if (process.env.NODE_ENV !== "production") {
|
|
903
|
+
console.debug("[portal-components] fetching license summary via %s (Enterprise Portal API)", endpoint);
|
|
904
|
+
}
|
|
919
905
|
const response = await authenticatedFetch(endpoint, {
|
|
920
906
|
method: "GET",
|
|
921
907
|
token,
|
|
@@ -929,8 +915,9 @@ var fetchLicenseSummary = defineServerAction({
|
|
|
929
915
|
`License request failed (${response.status} ${response.statusText})`
|
|
930
916
|
);
|
|
931
917
|
}
|
|
932
|
-
const
|
|
933
|
-
const
|
|
918
|
+
const envelope = await response.json();
|
|
919
|
+
const licenseData = envelope.data;
|
|
920
|
+
const license = normalizeLicensePayload(licenseData);
|
|
934
921
|
const type = license.environment || "Unknown";
|
|
935
922
|
const expiresAt = license.expiresAt || null;
|
|
936
923
|
return {
|
|
@@ -948,7 +935,10 @@ var fetchCustomers = defineServerAction({
|
|
|
948
935
|
if (typeof token !== "string" || token.trim().length === 0) {
|
|
949
936
|
throw new Error("fetchCustomers requires a non-empty token");
|
|
950
937
|
}
|
|
951
|
-
const endpoint = `${getApiOrigin()}/
|
|
938
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user`;
|
|
939
|
+
if (process.env.NODE_ENV !== "production") {
|
|
940
|
+
console.debug("[portal-components] fetching customers via %s (Enterprise Portal API)", endpoint);
|
|
941
|
+
}
|
|
952
942
|
const response = await authenticatedFetch(endpoint, {
|
|
953
943
|
method: "GET",
|
|
954
944
|
token,
|
|
@@ -962,9 +952,10 @@ var fetchCustomers = defineServerAction({
|
|
|
962
952
|
`Fetch customers request failed (${response.status} ${response.statusText})`
|
|
963
953
|
);
|
|
964
954
|
}
|
|
965
|
-
const
|
|
955
|
+
const envelope = await response.json();
|
|
956
|
+
const userData = envelope.data;
|
|
966
957
|
return {
|
|
967
|
-
customers:
|
|
958
|
+
customers: userData?.customers || []
|
|
968
959
|
};
|
|
969
960
|
}
|
|
970
961
|
});
|
|
@@ -980,10 +971,10 @@ var switchCustomer = defineServerAction({
|
|
|
980
971
|
if (typeof customerId !== "string" || customerId.trim().length === 0) {
|
|
981
972
|
throw new Error("switchCustomer requires a non-empty customerId");
|
|
982
973
|
}
|
|
983
|
-
const endpoint = `${getApiOrigin()}/
|
|
974
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/auth/switch-team`;
|
|
984
975
|
const requestBody = { customer_id: customerId };
|
|
985
976
|
const response = await authenticatedFetch(endpoint, {
|
|
986
|
-
method: "
|
|
977
|
+
method: "POST",
|
|
987
978
|
token,
|
|
988
979
|
headers: {
|
|
989
980
|
"content-type": "application/json",
|
|
@@ -992,7 +983,6 @@ var switchCustomer = defineServerAction({
|
|
|
992
983
|
body: JSON.stringify(requestBody),
|
|
993
984
|
signal: context?.signal
|
|
994
985
|
});
|
|
995
|
-
console.log("[portal-components] switchCustomer response status:", response.status);
|
|
996
986
|
if (!response.ok) {
|
|
997
987
|
const errorText = await response.text();
|
|
998
988
|
console.error("[portal-components] switchCustomer error response:", errorText);
|
|
@@ -1001,9 +991,7 @@ var switchCustomer = defineServerAction({
|
|
|
1001
991
|
);
|
|
1002
992
|
}
|
|
1003
993
|
const payload = await response.json();
|
|
1004
|
-
console.log("[portal-components] switchCustomer response payload:", payload);
|
|
1005
994
|
const newToken = payload.jwt || payload.token || token;
|
|
1006
|
-
console.log("[portal-components] switchCustomer using token field:", payload.jwt ? "jwt" : payload.token ? "token" : "fallback");
|
|
1007
995
|
return {
|
|
1008
996
|
token: newToken
|
|
1009
997
|
};
|
|
@@ -1018,16 +1006,14 @@ var getSecurityInfo = defineServerAction({
|
|
|
1018
1006
|
if (!token || typeof token !== "string") {
|
|
1019
1007
|
throw new Error("Security info request requires a session token");
|
|
1020
1008
|
}
|
|
1021
|
-
const customerId = getCustomerIdFromToken(token);
|
|
1022
1009
|
const params = new URLSearchParams({
|
|
1023
|
-
customer_id: customerId,
|
|
1024
1010
|
install_type: installType,
|
|
1025
1011
|
channel_sequence: channelSequence.toString(),
|
|
1026
1012
|
is_airgap: isAirgap.toString()
|
|
1027
1013
|
});
|
|
1028
|
-
const url = `${getApiOrigin()}/
|
|
1014
|
+
const url = `${getApiOrigin()}/enterprise-portal/security?${params.toString()}`;
|
|
1029
1015
|
if (process.env.NODE_ENV !== "production") {
|
|
1030
|
-
console.debug("[portal-components] fetching security info via %s", url);
|
|
1016
|
+
console.debug("[portal-components] fetching security info via %s (Enterprise Portal API)", url);
|
|
1031
1017
|
}
|
|
1032
1018
|
const response = await authenticatedFetch(url, {
|
|
1033
1019
|
token,
|
|
@@ -1039,8 +1025,8 @@ var getSecurityInfo = defineServerAction({
|
|
|
1039
1025
|
`Security info request failed (${response.status} ${response.statusText})`
|
|
1040
1026
|
);
|
|
1041
1027
|
}
|
|
1042
|
-
const
|
|
1043
|
-
return data;
|
|
1028
|
+
const payload = await response.json();
|
|
1029
|
+
return payload.data;
|
|
1044
1030
|
}
|
|
1045
1031
|
});
|
|
1046
1032
|
var getSecurityInfoDiff = defineServerAction({
|
|
@@ -1052,15 +1038,13 @@ var getSecurityInfoDiff = defineServerAction({
|
|
|
1052
1038
|
if (!token || typeof token !== "string") {
|
|
1053
1039
|
throw new Error("Security info diff request requires a session token");
|
|
1054
1040
|
}
|
|
1055
|
-
const customerId = getCustomerIdFromToken(token);
|
|
1056
1041
|
const params = new URLSearchParams({
|
|
1057
|
-
customer_id: customerId,
|
|
1058
1042
|
install_type: installType,
|
|
1059
1043
|
from_channel_sequence: fromChannelSequence.toString(),
|
|
1060
1044
|
to_channel_sequence: toChannelSequence.toString(),
|
|
1061
1045
|
is_airgap: isAirgap.toString()
|
|
1062
1046
|
});
|
|
1063
|
-
const url = `${getApiOrigin()}/
|
|
1047
|
+
const url = `${getApiOrigin()}/enterprise-portal/security-diff?${params.toString()}`;
|
|
1064
1048
|
if (process.env.NODE_ENV !== "production") {
|
|
1065
1049
|
console.debug("[portal-components] fetching security info diff via %s", url);
|
|
1066
1050
|
}
|
|
@@ -1074,8 +1058,8 @@ var getSecurityInfoDiff = defineServerAction({
|
|
|
1074
1058
|
`Security info diff request failed (${response.status} ${response.statusText})`
|
|
1075
1059
|
);
|
|
1076
1060
|
}
|
|
1077
|
-
const
|
|
1078
|
-
return data;
|
|
1061
|
+
const envelope = await response.json();
|
|
1062
|
+
return envelope.data;
|
|
1079
1063
|
}
|
|
1080
1064
|
});
|
|
1081
1065
|
var getSecurityInfoSBOM = defineServerAction({
|
|
@@ -1087,15 +1071,13 @@ var getSecurityInfoSBOM = defineServerAction({
|
|
|
1087
1071
|
if (!token || typeof token !== "string") {
|
|
1088
1072
|
throw new Error("Security SBOM request requires a session token");
|
|
1089
1073
|
}
|
|
1090
|
-
const customerId = getCustomerIdFromToken(token);
|
|
1091
1074
|
const params = new URLSearchParams({
|
|
1092
|
-
customer_id: customerId,
|
|
1093
1075
|
install_type: installType,
|
|
1094
1076
|
channel_sequence: channelSequence.toString(),
|
|
1095
1077
|
is_airgap: isAirgap.toString(),
|
|
1096
1078
|
unified_sbom: unifiedSbom.toString()
|
|
1097
1079
|
});
|
|
1098
|
-
const url = `${getApiOrigin()}/
|
|
1080
|
+
const url = `${getApiOrigin()}/enterprise-portal/security-sbom?${params.toString()}`;
|
|
1099
1081
|
if (process.env.NODE_ENV !== "production") {
|
|
1100
1082
|
console.debug("[portal-components] fetching security SBOM via %s", url);
|
|
1101
1083
|
}
|
|
@@ -1112,8 +1094,77 @@ var getSecurityInfoSBOM = defineServerAction({
|
|
|
1112
1094
|
`Security SBOM request failed (${response.status} ${response.statusText})`
|
|
1113
1095
|
);
|
|
1114
1096
|
}
|
|
1115
|
-
const
|
|
1116
|
-
return data;
|
|
1097
|
+
const envelope = await response.json();
|
|
1098
|
+
return envelope.data;
|
|
1099
|
+
}
|
|
1100
|
+
});
|
|
1101
|
+
var fetchDashboardComposite = defineServerAction({
|
|
1102
|
+
id: "dashboard/fetch-composite",
|
|
1103
|
+
description: "Fetches all dashboard data from the composite Enterprise Portal API endpoint",
|
|
1104
|
+
visibility: "customer",
|
|
1105
|
+
tags: ["dashboard", "enterprise-portal-api"],
|
|
1106
|
+
async run({ token }, context) {
|
|
1107
|
+
if (!token || typeof token !== "string") {
|
|
1108
|
+
throw new Error("Dashboard request requires a session token");
|
|
1109
|
+
}
|
|
1110
|
+
const origin = getApiOrigin();
|
|
1111
|
+
const url = `${origin}/enterprise-portal/dashboard`;
|
|
1112
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1113
|
+
console.debug("[portal-components] fetching dashboard via %s (Enterprise Portal API)", url);
|
|
1114
|
+
}
|
|
1115
|
+
const response = await authenticatedFetch(url, {
|
|
1116
|
+
method: "GET",
|
|
1117
|
+
token,
|
|
1118
|
+
headers: { accept: "application/json" },
|
|
1119
|
+
signal: context?.signal
|
|
1120
|
+
});
|
|
1121
|
+
if (!response.ok) {
|
|
1122
|
+
throw new Error(
|
|
1123
|
+
`Dashboard request failed (${response.status} ${response.statusText})`
|
|
1124
|
+
);
|
|
1125
|
+
}
|
|
1126
|
+
const payload = await response.json();
|
|
1127
|
+
const data = payload.data;
|
|
1128
|
+
const allInstances = data?.instances || [];
|
|
1129
|
+
const channelReleases = data?.channelReleases || [];
|
|
1130
|
+
const licenseData = data?.license || {};
|
|
1131
|
+
const teamStats = data?.teamStats || {};
|
|
1132
|
+
const onlineInstances = allInstances.filter((i) => !i.isAirgap);
|
|
1133
|
+
const airgapInstances = allInstances.filter((i) => i.isAirgap);
|
|
1134
|
+
const twentyFourHoursAgo = Date.now() - 24 * 60 * 60 * 1e3;
|
|
1135
|
+
const activeOnlineInstances = onlineInstances.filter((instance) => {
|
|
1136
|
+
const lastCheckin = instance.lastCheckin ? new Date(instance.lastCheckin).getTime() : 0;
|
|
1137
|
+
return lastCheckin > twentyFourHoursAgo;
|
|
1138
|
+
});
|
|
1139
|
+
const onlineActiveCount = activeOnlineInstances.length;
|
|
1140
|
+
const airgapCount = airgapInstances.length;
|
|
1141
|
+
const calculateUpdates = (instances) => {
|
|
1142
|
+
if (!channelReleases.length) return 0;
|
|
1143
|
+
let numUpdates = 0;
|
|
1144
|
+
for (const instance of instances) {
|
|
1145
|
+
const instanceSequence = instance.channelSequence ?? 0;
|
|
1146
|
+
const matchingReleases = channelReleases.filter(
|
|
1147
|
+
(release) => release.channelId === instance.channelId
|
|
1148
|
+
);
|
|
1149
|
+
for (const release of matchingReleases) {
|
|
1150
|
+
if ((release.channelSequence ?? 0) > instanceSequence) {
|
|
1151
|
+
numUpdates++;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
return numUpdates;
|
|
1156
|
+
};
|
|
1157
|
+
const onlineUpdates = calculateUpdates(activeOnlineInstances);
|
|
1158
|
+
const airgapUpdates = calculateUpdates(airgapInstances);
|
|
1159
|
+
return {
|
|
1160
|
+
onlineActiveCount,
|
|
1161
|
+
airgapCount,
|
|
1162
|
+
onlineUpdates,
|
|
1163
|
+
airgapUpdates,
|
|
1164
|
+
// Additional data available from the composite endpoint
|
|
1165
|
+
license: licenseData,
|
|
1166
|
+
teamStats
|
|
1167
|
+
};
|
|
1117
1168
|
}
|
|
1118
1169
|
});
|
|
1119
1170
|
var fetchTeamStats = defineServerAction({
|
|
@@ -1262,7 +1313,7 @@ var fetchCurrentUser = defineServerAction({
|
|
|
1262
1313
|
if (!token || typeof token !== "string") {
|
|
1263
1314
|
throw new Error("Fetch current user requires a session token");
|
|
1264
1315
|
}
|
|
1265
|
-
const endpoint = `${getApiOrigin()}/
|
|
1316
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user/profile`;
|
|
1266
1317
|
if (process.env.NODE_ENV !== "production") {
|
|
1267
1318
|
console.debug("[portal-components] fetching current user via %s", endpoint);
|
|
1268
1319
|
}
|
|
@@ -1299,7 +1350,7 @@ var updateUser = defineServerAction({
|
|
|
1299
1350
|
if (!firstName && !lastName) {
|
|
1300
1351
|
throw new Error("At least one of firstName or lastName must be provided");
|
|
1301
1352
|
}
|
|
1302
|
-
const endpoint = `${getApiOrigin()}/
|
|
1353
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user/profile`;
|
|
1303
1354
|
if (process.env.NODE_ENV !== "production") {
|
|
1304
1355
|
console.debug("[portal-components] updating user via %s", endpoint);
|
|
1305
1356
|
}
|
|
@@ -1307,7 +1358,7 @@ var updateUser = defineServerAction({
|
|
|
1307
1358
|
if (firstName !== void 0) body.firstName = firstName;
|
|
1308
1359
|
if (lastName !== void 0) body.lastName = lastName;
|
|
1309
1360
|
const response = await authenticatedFetch(endpoint, {
|
|
1310
|
-
method: "
|
|
1361
|
+
method: "PUT",
|
|
1311
1362
|
token,
|
|
1312
1363
|
headers: {
|
|
1313
1364
|
"content-type": "application/json",
|
|
@@ -1335,9 +1386,9 @@ var fetchNotifications = defineServerAction({
|
|
|
1335
1386
|
throw new Error("Fetch notifications requires a session token");
|
|
1336
1387
|
}
|
|
1337
1388
|
if (!customerId || typeof customerId !== "string") {
|
|
1338
|
-
throw new Error("Fetch notifications requires a customerId");
|
|
1389
|
+
throw new Error("Fetch notifications requires a valid customerId");
|
|
1339
1390
|
}
|
|
1340
|
-
const endpoint = `${getApiOrigin()}/
|
|
1391
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user/notifications?customer_id=${encodeURIComponent(customerId)}`;
|
|
1341
1392
|
if (process.env.NODE_ENV !== "production") {
|
|
1342
1393
|
console.debug("[portal-components] fetching notifications via %s", endpoint);
|
|
1343
1394
|
}
|
|
@@ -1368,12 +1419,12 @@ var updateNotifications = defineServerAction({
|
|
|
1368
1419
|
throw new Error("Update notifications requires a session token");
|
|
1369
1420
|
}
|
|
1370
1421
|
if (!customerId || typeof customerId !== "string") {
|
|
1371
|
-
throw new Error("Update notifications requires a customerId");
|
|
1422
|
+
throw new Error("Update notifications requires a valid customerId");
|
|
1372
1423
|
}
|
|
1373
1424
|
if (!Array.isArray(notifications)) {
|
|
1374
1425
|
throw new Error("Update notifications requires a notifications array");
|
|
1375
1426
|
}
|
|
1376
|
-
const endpoint = `${getApiOrigin()}/
|
|
1427
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user/notifications?customer_id=${encodeURIComponent(customerId)}`;
|
|
1377
1428
|
if (process.env.NODE_ENV !== "production") {
|
|
1378
1429
|
console.debug("[portal-components] updating notifications via %s", endpoint);
|
|
1379
1430
|
}
|
|
@@ -1414,7 +1465,7 @@ var fetchTeamUsers = defineServerAction({
|
|
|
1414
1465
|
limit: limit.toString(),
|
|
1415
1466
|
offset: offset.toString()
|
|
1416
1467
|
});
|
|
1417
|
-
const endpoint = `${getApiOrigin()}/
|
|
1468
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/team/users?${params.toString()}`;
|
|
1418
1469
|
if (process.env.NODE_ENV !== "production") {
|
|
1419
1470
|
console.debug("[portal-components] fetching team users via %s", endpoint);
|
|
1420
1471
|
}
|
|
@@ -1448,12 +1499,11 @@ var inviteUser = defineServerAction({
|
|
|
1448
1499
|
if (!email || typeof email !== "string") {
|
|
1449
1500
|
throw new Error("Invite user requires an email address");
|
|
1450
1501
|
}
|
|
1451
|
-
|
|
1502
|
+
getCustomerIdFromToken(token);
|
|
1452
1503
|
const params = new URLSearchParams({
|
|
1453
|
-
customer_id: customerId,
|
|
1454
1504
|
email_address: email
|
|
1455
1505
|
});
|
|
1456
|
-
const endpoint = `${getApiOrigin()}/
|
|
1506
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/team/invite?${params.toString()}`;
|
|
1457
1507
|
if (process.env.NODE_ENV !== "production") {
|
|
1458
1508
|
console.debug("[portal-components] inviting user via %s", endpoint);
|
|
1459
1509
|
}
|
|
@@ -1477,24 +1527,20 @@ var inviteUser = defineServerAction({
|
|
|
1477
1527
|
});
|
|
1478
1528
|
var deleteUser = defineServerAction({
|
|
1479
1529
|
id: "team/delete-user",
|
|
1480
|
-
description: "Removes a user from the team",
|
|
1530
|
+
description: "Removes a user or pending invite from the team by ID",
|
|
1481
1531
|
visibility: "customer",
|
|
1482
1532
|
tags: ["team", "users", "delete"],
|
|
1483
|
-
async run({ token,
|
|
1533
|
+
async run({ token, id, isPendingInvite }, context) {
|
|
1484
1534
|
if (!token || typeof token !== "string") {
|
|
1485
1535
|
throw new Error("Delete user requires a session token");
|
|
1486
1536
|
}
|
|
1487
|
-
if (!
|
|
1488
|
-
throw new Error("Delete user requires an
|
|
1537
|
+
if (!id || typeof id !== "string") {
|
|
1538
|
+
throw new Error("Delete user requires an ID");
|
|
1489
1539
|
}
|
|
1490
|
-
const
|
|
1491
|
-
const
|
|
1492
|
-
customer_id: customerId,
|
|
1493
|
-
email_address: email
|
|
1494
|
-
});
|
|
1495
|
-
const endpoint = `${getApiOrigin()}/v3/user?${params.toString()}`;
|
|
1540
|
+
const resource = isPendingInvite ? "invites" : "users";
|
|
1541
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/team/${resource}/${encodeURIComponent(id)}`;
|
|
1496
1542
|
if (process.env.NODE_ENV !== "production") {
|
|
1497
|
-
console.debug("[portal-components] deleting
|
|
1543
|
+
console.debug("[portal-components] deleting %s %s via %s", resource, id, endpoint);
|
|
1498
1544
|
}
|
|
1499
1545
|
const response = await authenticatedFetch(endpoint, {
|
|
1500
1546
|
method: "DELETE",
|
|
@@ -1503,7 +1549,7 @@ var deleteUser = defineServerAction({
|
|
|
1503
1549
|
signal: context?.signal
|
|
1504
1550
|
});
|
|
1505
1551
|
if (!response.ok) {
|
|
1506
|
-
let errorMessage = "Failed to delete user";
|
|
1552
|
+
let errorMessage = isPendingInvite ? "Failed to delete invite" : "Failed to delete user";
|
|
1507
1553
|
try {
|
|
1508
1554
|
const data = await response.json();
|
|
1509
1555
|
errorMessage = data.message || data.error || errorMessage;
|
|
@@ -1532,7 +1578,7 @@ var fetchServiceAccounts = defineServerAction({
|
|
|
1532
1578
|
if (!includeRevoked) {
|
|
1533
1579
|
params.set("filterRevoked", "false");
|
|
1534
1580
|
}
|
|
1535
|
-
const endpoint = `${getApiOrigin()}/
|
|
1581
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts?${params.toString()}`;
|
|
1536
1582
|
if (process.env.NODE_ENV !== "production") {
|
|
1537
1583
|
console.debug("[portal-components] fetching service accounts via %s", endpoint);
|
|
1538
1584
|
}
|
|
@@ -1566,8 +1612,8 @@ var revokeServiceAccount = defineServerAction({
|
|
|
1566
1612
|
if (!accountId || typeof accountId !== "string") {
|
|
1567
1613
|
throw new Error("Revoke service account requires an account ID");
|
|
1568
1614
|
}
|
|
1569
|
-
|
|
1570
|
-
const endpoint = `${getApiOrigin()}/
|
|
1615
|
+
getCustomerIdFromToken(token);
|
|
1616
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts/${encodeURIComponent(accountId)}`;
|
|
1571
1617
|
if (process.env.NODE_ENV !== "production") {
|
|
1572
1618
|
console.debug("[portal-components] revoking service account via %s", endpoint);
|
|
1573
1619
|
}
|
|
@@ -1601,8 +1647,8 @@ var rotateServiceAccountToken = defineServerAction({
|
|
|
1601
1647
|
if (!accountId || typeof accountId !== "string") {
|
|
1602
1648
|
throw new Error("Rotate service account token requires an account ID");
|
|
1603
1649
|
}
|
|
1604
|
-
|
|
1605
|
-
const endpoint = `${getApiOrigin()}/
|
|
1650
|
+
getCustomerIdFromToken(token);
|
|
1651
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts/${encodeURIComponent(accountId)}/rotate-token`;
|
|
1606
1652
|
if (process.env.NODE_ENV !== "production") {
|
|
1607
1653
|
console.debug("[portal-components] rotating service account token via %s", endpoint);
|
|
1608
1654
|
}
|
|
@@ -1825,9 +1871,9 @@ var acceptInvite = defineServerAction({
|
|
|
1825
1871
|
};
|
|
1826
1872
|
throw error;
|
|
1827
1873
|
}
|
|
1828
|
-
const endpoint = `${getApiOrigin()}/
|
|
1874
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/auth/invite/accept`;
|
|
1829
1875
|
if (process.env.NODE_ENV !== "production") {
|
|
1830
|
-
console.debug("[portal-components] accepting invite via %s", endpoint);
|
|
1876
|
+
console.debug("[portal-components] accepting invite via %s (Enterprise Portal API)", endpoint);
|
|
1831
1877
|
}
|
|
1832
1878
|
const response = await fetch(endpoint, {
|
|
1833
1879
|
method: "POST",
|
|
@@ -1874,9 +1920,9 @@ var refreshInvite = defineServerAction({
|
|
|
1874
1920
|
if (!code || typeof code !== "string") {
|
|
1875
1921
|
throw new Error("Invite code is required");
|
|
1876
1922
|
}
|
|
1877
|
-
const endpoint = `${getApiOrigin()}/
|
|
1923
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/auth/invite/refresh`;
|
|
1878
1924
|
if (process.env.NODE_ENV !== "production") {
|
|
1879
|
-
console.debug("[portal-components] refreshing invite via %s", endpoint);
|
|
1925
|
+
console.debug("[portal-components] refreshing invite via %s (Enterprise Portal API)", endpoint);
|
|
1880
1926
|
}
|
|
1881
1927
|
const response = await fetch(endpoint, {
|
|
1882
1928
|
method: "POST",
|
|
@@ -1910,6 +1956,7 @@ exports.downloadSupportBundle = downloadSupportBundle;
|
|
|
1910
1956
|
exports.fetchCurrentUser = fetchCurrentUser;
|
|
1911
1957
|
exports.fetchCustomBranding = fetchCustomBranding;
|
|
1912
1958
|
exports.fetchCustomers = fetchCustomers;
|
|
1959
|
+
exports.fetchDashboardComposite = fetchDashboardComposite;
|
|
1913
1960
|
exports.fetchDashboardInstances = fetchDashboardInstances;
|
|
1914
1961
|
exports.fetchInstallOptions = fetchInstallOptions;
|
|
1915
1962
|
exports.fetchInstances = fetchInstances;
|