@replicated/portal-components 0.0.18 → 0.0.20
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/change-team.d.mts +10 -0
- package/dist/actions/change-team.d.ts +10 -0
- package/dist/actions/change-team.js +458 -0
- package/dist/actions/change-team.js.map +1 -0
- package/dist/actions/index.d.mts +4 -1
- package/dist/actions/index.d.ts +4 -1
- package/dist/actions/index.js +1232 -430
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/install-actions.d.mts +4 -0
- package/dist/actions/install-actions.d.ts +4 -0
- package/dist/actions/install-actions.js +680 -0
- package/dist/actions/install-actions.js.map +1 -0
- package/dist/actions/service-account.d.mts +4 -0
- package/dist/actions/service-account.d.ts +4 -0
- package/dist/actions/service-account.js +373 -0
- package/dist/actions/service-account.js.map +1 -0
- package/dist/actions/support-bundles.d.mts +4 -0
- package/dist/actions/support-bundles.d.ts +4 -0
- package/dist/actions/support-bundles.js +659 -0
- package/dist/actions/support-bundles.js.map +1 -0
- package/dist/actions/team-settings.d.mts +4 -0
- package/dist/actions/team-settings.d.ts +4 -0
- package/dist/actions/team-settings.js +1040 -0
- package/dist/actions/team-settings.js.map +1 -0
- package/dist/actions/trial-signup.d.mts +24 -0
- package/dist/actions/trial-signup.d.ts +24 -0
- package/dist/actions/trial-signup.js +482 -0
- package/dist/actions/trial-signup.js.map +1 -0
- package/dist/actions/user-settings.d.mts +4 -0
- package/dist/actions/user-settings.d.ts +4 -0
- package/dist/actions/user-settings.js +621 -0
- package/dist/actions/user-settings.js.map +1 -0
- package/dist/airgap-instances.d.mts +4 -1
- package/dist/airgap-instances.d.ts +4 -1
- package/dist/airgap-instances.js +177 -32
- package/dist/airgap-instances.js.map +1 -1
- package/dist/branding-BsMSywts.d.mts +36 -0
- package/dist/branding-BsMSywts.d.ts +36 -0
- package/dist/error-page.js +10 -2
- package/dist/error-page.js.map +1 -1
- package/dist/error.js +10 -2
- package/dist/error.js.map +1 -1
- package/dist/esm/actions/change-team.js +455 -0
- package/dist/esm/actions/change-team.js.map +1 -0
- package/dist/esm/actions/index.js +1200 -428
- package/dist/esm/actions/index.js.map +1 -1
- package/dist/esm/actions/install-actions.js +673 -0
- package/dist/esm/actions/install-actions.js.map +1 -0
- package/dist/esm/actions/service-account.js +371 -0
- package/dist/esm/actions/service-account.js.map +1 -0
- package/dist/esm/actions/support-bundles.js +654 -0
- package/dist/esm/actions/support-bundles.js.map +1 -0
- package/dist/esm/actions/team-settings.js +1026 -0
- package/dist/esm/actions/team-settings.js.map +1 -0
- package/dist/esm/actions/trial-signup.js +478 -0
- package/dist/esm/actions/trial-signup.js.map +1 -0
- package/dist/esm/actions/user-settings.js +615 -0
- package/dist/esm/actions/user-settings.js.map +1 -0
- package/dist/esm/airgap-instances.js +176 -32
- package/dist/esm/airgap-instances.js.map +1 -1
- package/dist/esm/error-page.js +10 -2
- package/dist/esm/error-page.js.map +1 -1
- package/dist/esm/error.js +10 -2
- package/dist/esm/error.js.map +1 -1
- package/dist/esm/helm-install-wizard.js +127 -81
- package/dist/esm/helm-install-wizard.js.map +1 -1
- package/dist/esm/index.js +706 -438
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-actions.js +40 -5
- package/dist/esm/install-actions.js.map +1 -1
- package/dist/esm/install-card.js +9 -6
- package/dist/esm/install-card.js.map +1 -1
- package/dist/esm/install-targets.js +9 -2
- package/dist/esm/install-targets.js.map +1 -1
- package/dist/esm/instance-card.js +175 -31
- package/dist/esm/instance-card.js.map +1 -1
- package/dist/esm/join-team.js +9 -3
- package/dist/esm/join-team.js.map +1 -1
- package/dist/esm/license-card.js +24 -22
- package/dist/esm/license-card.js.map +1 -1
- package/dist/esm/license-details.js +128 -334
- package/dist/esm/license-details.js.map +1 -1
- package/dist/esm/linux-install-wizard.js +219 -133
- package/dist/esm/linux-install-wizard.js.map +1 -1
- package/dist/esm/login.js +20 -4
- package/dist/esm/login.js.map +1 -1
- package/dist/esm/middleware.js +33 -0
- package/dist/esm/middleware.js.map +1 -0
- package/dist/esm/online-instance-list.js +176 -32
- package/dist/esm/online-instance-list.js.map +1 -1
- package/dist/esm/pending-installations.js +4 -3
- package/dist/esm/pending-installations.js.map +1 -1
- package/dist/esm/release-history-panel.js +27 -14
- package/dist/esm/release-history-panel.js.map +1 -1
- package/dist/esm/saml-callback-client.js +82 -0
- package/dist/esm/saml-callback-client.js.map +1 -0
- package/dist/esm/saml-handlers.js +138 -0
- package/dist/esm/saml-handlers.js.map +1 -0
- package/dist/esm/security-card.js +53 -38
- package/dist/esm/security-card.js.map +1 -1
- package/dist/esm/service-accounts-tab.js +800 -0
- package/dist/esm/service-accounts-tab.js.map +1 -0
- package/dist/esm/support-bundle-collection-card.js +55 -25
- package/dist/esm/support-bundle-collection-card.js.map +1 -1
- package/dist/esm/support-bundles-card.js +10 -5
- package/dist/esm/support-bundles-card.js.map +1 -1
- package/dist/esm/support-card.js +37 -5
- package/dist/esm/support-card.js.map +1 -1
- package/dist/esm/team-selection.js +5 -1
- package/dist/esm/team-selection.js.map +1 -1
- package/dist/esm/team-settings-card.js +5 -2
- package/dist/esm/team-settings-card.js.map +1 -1
- package/dist/esm/team-settings.js +7 -2
- package/dist/esm/team-settings.js.map +1 -1
- package/dist/esm/top-nav-user-menu.js +5 -1
- package/dist/esm/top-nav-user-menu.js.map +1 -1
- package/dist/esm/top-nav.js +175 -62
- package/dist/esm/top-nav.js.map +1 -1
- package/dist/esm/trial-signup.js +256 -0
- package/dist/esm/trial-signup.js.map +1 -0
- package/dist/esm/update-layout.js +175 -62
- package/dist/esm/update-layout.js.map +1 -1
- package/dist/esm/updates-card.js +15 -4
- package/dist/esm/updates-card.js.map +1 -1
- package/dist/esm/upload-support-bundle-modal.js +9 -4
- package/dist/esm/upload-support-bundle-modal.js.map +1 -1
- package/dist/esm/user-settings-card.js +5 -2
- package/dist/esm/user-settings-card.js.map +1 -1
- package/dist/esm/user-settings.js +12 -6
- package/dist/esm/user-settings.js.map +1 -1
- package/dist/esm/utils/index.js +204 -13
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/fetch-license-iTyF7_GY.d.mts +81 -0
- package/dist/fetch-license-iTyF7_GY.d.ts +81 -0
- package/dist/helm-install-wizard.d.mts +12 -3
- package/dist/helm-install-wizard.d.ts +12 -3
- package/dist/helm-install-wizard.js +127 -81
- package/dist/helm-install-wizard.js.map +1 -1
- package/dist/{index-DkjaogsF.d.ts → index-DyzJ0yKD.d.mts} +194 -49
- package/dist/{index-DkjaogsF.d.mts → index-sMbq94M7.d.ts} +194 -49
- package/dist/index.d.mts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +726 -438
- package/dist/index.js.map +1 -1
- package/dist/install-actions.d.mts +5 -2
- package/dist/install-actions.d.ts +5 -2
- package/dist/install-actions.js +40 -5
- package/dist/install-actions.js.map +1 -1
- package/dist/install-card.d.mts +2 -2
- package/dist/install-card.d.ts +2 -2
- package/dist/install-card.js +9 -6
- package/dist/install-card.js.map +1 -1
- package/dist/install-targets.js +9 -2
- package/dist/install-targets.js.map +1 -1
- package/dist/instance-card.d.mts +4 -1
- package/dist/instance-card.d.ts +4 -1
- package/dist/instance-card.js +176 -31
- package/dist/instance-card.js.map +1 -1
- package/dist/join-team.js +9 -3
- package/dist/join-team.js.map +1 -1
- package/dist/license-card.d.mts +2 -2
- package/dist/license-card.d.ts +2 -2
- package/dist/license-card.js +24 -22
- package/dist/license-card.js.map +1 -1
- package/dist/license-details.js +128 -334
- package/dist/license-details.js.map +1 -1
- package/dist/linux-install-wizard.d.mts +12 -6
- package/dist/linux-install-wizard.d.ts +12 -6
- package/dist/linux-install-wizard.js +219 -133
- package/dist/linux-install-wizard.js.map +1 -1
- package/dist/login.d.mts +4 -0
- package/dist/login.d.ts +4 -0
- package/dist/login.js +20 -4
- package/dist/login.js.map +1 -1
- package/dist/middleware.d.mts +13 -0
- package/dist/middleware.d.ts +13 -0
- package/dist/middleware.js +35 -0
- package/dist/middleware.js.map +1 -0
- package/dist/online-instance-list.d.mts +4 -1
- package/dist/online-instance-list.d.ts +4 -1
- package/dist/online-instance-list.js +177 -32
- package/dist/online-instance-list.js.map +1 -1
- package/dist/pending-installations.d.mts +8 -3
- package/dist/pending-installations.d.ts +8 -3
- package/dist/pending-installations.js +4 -3
- package/dist/pending-installations.js.map +1 -1
- package/dist/release-history-panel.js +27 -14
- package/dist/release-history-panel.js.map +1 -1
- package/dist/saml-callback-client.d.mts +36 -0
- package/dist/saml-callback-client.d.ts +36 -0
- package/dist/saml-callback-client.js +88 -0
- package/dist/saml-callback-client.js.map +1 -0
- package/dist/saml-handlers.d.mts +50 -0
- package/dist/saml-handlers.d.ts +50 -0
- package/dist/saml-handlers.js +141 -0
- package/dist/saml-handlers.js.map +1 -0
- package/dist/security-card.d.mts +4 -1
- package/dist/security-card.d.ts +4 -1
- package/dist/security-card.js +53 -38
- package/dist/security-card.js.map +1 -1
- package/dist/service-accounts-tab.d.mts +51 -0
- package/dist/service-accounts-tab.d.ts +51 -0
- package/dist/service-accounts-tab.js +802 -0
- package/dist/service-accounts-tab.js.map +1 -0
- package/dist/styles.css +380 -143
- package/dist/support-bundle-collection-card.d.mts +1 -1
- package/dist/support-bundle-collection-card.d.ts +1 -1
- package/dist/support-bundle-collection-card.js +54 -24
- package/dist/support-bundle-collection-card.js.map +1 -1
- package/dist/support-bundles-card.d.mts +5 -2
- package/dist/support-bundles-card.d.ts +5 -2
- package/dist/support-bundles-card.js +10 -5
- package/dist/support-bundles-card.js.map +1 -1
- package/dist/support-card.js +37 -5
- package/dist/support-card.js.map +1 -1
- package/dist/team-selection.js +5 -1
- package/dist/team-selection.js.map +1 -1
- package/dist/team-settings-card.js +5 -2
- package/dist/team-settings-card.js.map +1 -1
- package/dist/team-settings.js +7 -2
- package/dist/team-settings.js.map +1 -1
- package/dist/{top-nav-IRIn66wS.d.ts → top-nav-BUQAGoG1.d.mts} +14 -2
- package/dist/{top-nav-IRIn66wS.d.mts → top-nav-CEqw0KpO.d.ts} +14 -2
- package/dist/top-nav-user-menu.js +5 -1
- package/dist/top-nav-user-menu.js.map +1 -1
- package/dist/top-nav.d.mts +2 -1
- package/dist/top-nav.d.ts +2 -1
- package/dist/top-nav.js +175 -62
- package/dist/top-nav.js.map +1 -1
- package/dist/trial-signup.d.mts +31 -0
- package/dist/trial-signup.d.ts +31 -0
- package/dist/trial-signup.js +258 -0
- package/dist/trial-signup.js.map +1 -0
- package/dist/update-layout.js +175 -62
- package/dist/update-layout.js.map +1 -1
- package/dist/updates-card.js +15 -4
- package/dist/updates-card.js.map +1 -1
- package/dist/upload-support-bundle-modal.js +9 -4
- package/dist/upload-support-bundle-modal.js.map +1 -1
- package/dist/user-settings-card.js +5 -2
- package/dist/user-settings-card.js.map +1 -1
- package/dist/user-settings.js +12 -6
- package/dist/user-settings.js.map +1 -1
- package/dist/utils/index.d.mts +74 -16
- package/dist/utils/index.d.ts +74 -16
- package/dist/utils/index.js +215 -12
- package/dist/utils/index.js.map +1 -1
- package/package.json +67 -1
package/dist/actions/index.js
CHANGED
|
@@ -2,14 +2,127 @@
|
|
|
2
2
|
|
|
3
3
|
var buffer = require('buffer');
|
|
4
4
|
var react = require('react');
|
|
5
|
+
var headers = require('next/headers');
|
|
6
|
+
var cache = require('next/cache');
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Enterprise Portal Components
|
|
8
10
|
* This file is generated by tsup. Do not edit manually.
|
|
9
11
|
*/
|
|
12
|
+
var __defProp = Object.defineProperty;
|
|
13
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
14
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
17
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
18
|
+
}) : x)(function(x) {
|
|
19
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
20
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
21
|
+
});
|
|
22
|
+
var __esm = (fn, res) => function __init() {
|
|
23
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
24
|
+
};
|
|
25
|
+
var __export = (target, all) => {
|
|
26
|
+
for (var name in all)
|
|
27
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
28
|
+
};
|
|
29
|
+
var __copyProps = (to, from, except, desc) => {
|
|
30
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
31
|
+
for (let key of __getOwnPropNames(from))
|
|
32
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
33
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
34
|
+
}
|
|
35
|
+
return to;
|
|
36
|
+
};
|
|
37
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
10
38
|
|
|
39
|
+
// datadog/tracer.ts
|
|
40
|
+
var tracer_exports = {};
|
|
41
|
+
__export(tracer_exports, {
|
|
42
|
+
default: () => tracer_default
|
|
43
|
+
});
|
|
44
|
+
var rawFlag, isEnabled, tracer, getRoutePattern, tracer_default;
|
|
45
|
+
var init_tracer = __esm({
|
|
46
|
+
"datadog/tracer.ts"() {
|
|
47
|
+
rawFlag = String(process.env.USE_DATADOG_APM || "").toLowerCase();
|
|
48
|
+
isEnabled = rawFlag === "true";
|
|
49
|
+
process.env.DD_TRACE_ENABLED = isEnabled ? "1" : "0";
|
|
50
|
+
tracer = null;
|
|
51
|
+
if (isEnabled) {
|
|
52
|
+
const serviceName = process.env.DD_SERVICE || "enterprise-portal";
|
|
53
|
+
const environment = process.env.DD_ENV || process.env.NODE_ENV || "development";
|
|
54
|
+
const version = process.env.DD_VERSION || process.env.NEXT_PUBLIC_VERSION || "0.0.0-dev";
|
|
55
|
+
const agentHost = process.env.DD_AGENT_HOST || process.env.DATADOG_AGENT_HOST || "127.0.0.1";
|
|
56
|
+
const agentPort = process.env.DD_TRACE_AGENT_PORT || "8126";
|
|
57
|
+
process.env.DD_SERVICE = serviceName;
|
|
58
|
+
process.env.DD_ENV = environment;
|
|
59
|
+
{
|
|
60
|
+
process.env.DD_VERSION = version;
|
|
61
|
+
}
|
|
62
|
+
process.env.DD_AGENT_HOST = agentHost;
|
|
63
|
+
process.env.DD_TRACE_AGENT_PORT = agentPort;
|
|
64
|
+
const dbmPropagationMode = process.env.DD_DBM_PROPAGATION_MODE || "full";
|
|
65
|
+
process.env.DD_DBM_PROPAGATION_MODE = dbmPropagationMode;
|
|
66
|
+
try {
|
|
67
|
+
const ddTrace = __require("dd-trace");
|
|
68
|
+
tracer = ddTrace.init({
|
|
69
|
+
service: serviceName,
|
|
70
|
+
env: environment,
|
|
71
|
+
version,
|
|
72
|
+
logInjection: true,
|
|
73
|
+
runtimeMetrics: true,
|
|
74
|
+
appsec: false,
|
|
75
|
+
profiling: false,
|
|
76
|
+
startupLogs: true
|
|
77
|
+
// Enable for debugging
|
|
78
|
+
});
|
|
79
|
+
console.log(`[datadog] Tracer initialized: service=${serviceName}, env=${environment}, version=${version}, agent=${agentHost}:${agentPort}`);
|
|
80
|
+
tracer.use("dns", false);
|
|
81
|
+
tracer.use("net", false);
|
|
82
|
+
tracer.use("http", {
|
|
83
|
+
server: {
|
|
84
|
+
hooks: {
|
|
85
|
+
request: (span, req) => {
|
|
86
|
+
if (!span) return;
|
|
87
|
+
const url = req?.url || "";
|
|
88
|
+
const method = req?.method || "GET";
|
|
89
|
+
const path = url.split("?")[0];
|
|
90
|
+
if (path.startsWith("/_next/")) {
|
|
91
|
+
span.context()._trace.isRecording = false;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const routePattern = getRoutePattern(path);
|
|
95
|
+
span.setTag("resource.name", `${method} ${routePattern}`);
|
|
96
|
+
span.setTag("http.route", routePattern);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.error("[datadog] failed to initialize tracing", err);
|
|
103
|
+
tracer = null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
getRoutePattern = (path) => {
|
|
107
|
+
const routePatterns = [
|
|
108
|
+
// Update instance routes - normalize dynamic segments (capture suffix to preserve sub-routes)
|
|
109
|
+
{ pattern: /^\/update\/instance\/[^/]+(.*)$/, replacement: "/update/instance/[instanceId]$1" }
|
|
110
|
+
];
|
|
111
|
+
for (const { pattern, replacement } of routePatterns) {
|
|
112
|
+
if (pattern.test(path)) {
|
|
113
|
+
return path.replace(pattern, replacement);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return path;
|
|
117
|
+
};
|
|
118
|
+
tracer_default = tracer;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
11
121
|
|
|
12
122
|
// src/utils/api-client.ts
|
|
123
|
+
function isRedirectError(error) {
|
|
124
|
+
return typeof error === "object" && error !== null && "digest" in error && typeof error.digest === "string" && error.digest.startsWith("NEXT_REDIRECT");
|
|
125
|
+
}
|
|
13
126
|
async function authenticatedFetch(url, options = {}) {
|
|
14
127
|
const { token, ...fetchOptions } = options;
|
|
15
128
|
const headers = new Headers(fetchOptions.headers);
|
|
@@ -32,8 +145,17 @@ async function handle401() {
|
|
|
32
145
|
const { redirect } = await import('next/navigation');
|
|
33
146
|
return redirect("/?expired=1");
|
|
34
147
|
}
|
|
148
|
+
function isErrorPage(url) {
|
|
149
|
+
try {
|
|
150
|
+
const urlObj = new URL(url);
|
|
151
|
+
return urlObj.pathname === "/error";
|
|
152
|
+
} catch {
|
|
153
|
+
return url === "/error" || url.startsWith("/error?");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
35
156
|
async function handleServerError(statusCode) {
|
|
36
157
|
const { redirect } = await import('next/navigation');
|
|
158
|
+
const { cookies: cookies9 } = await import('next/headers');
|
|
37
159
|
let sourceUrl;
|
|
38
160
|
try {
|
|
39
161
|
const { headers } = await import('next/headers');
|
|
@@ -41,12 +163,20 @@ async function handleServerError(statusCode) {
|
|
|
41
163
|
const referer = headersList.get("referer");
|
|
42
164
|
const host = headersList.get("host");
|
|
43
165
|
const pathname = headersList.get("x-invoke-path") || headersList.get("x-forwarded-path");
|
|
44
|
-
if (referer) {
|
|
166
|
+
if (referer && !isErrorPage(referer)) {
|
|
45
167
|
sourceUrl = referer;
|
|
46
168
|
} else if (host && pathname) {
|
|
47
169
|
const protocol = headersList.get("x-forwarded-proto") || "https";
|
|
48
170
|
sourceUrl = `${protocol}://${host}${pathname}`;
|
|
49
171
|
}
|
|
172
|
+
if (!sourceUrl || isErrorPage(sourceUrl)) {
|
|
173
|
+
const cookieStore = await cookies9();
|
|
174
|
+
const preservedSource = cookieStore.get("portal_error_source");
|
|
175
|
+
if (preservedSource?.value) {
|
|
176
|
+
sourceUrl = decodeURIComponent(preservedSource.value);
|
|
177
|
+
cookieStore.delete("portal_error_source");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
50
180
|
} catch (error) {
|
|
51
181
|
console.debug("[portal-components] Could not determine source URL", error);
|
|
52
182
|
}
|
|
@@ -57,6 +187,1039 @@ async function handleServerError(statusCode) {
|
|
|
57
187
|
return redirect(`/error?${params.toString()}`);
|
|
58
188
|
}
|
|
59
189
|
|
|
190
|
+
// src/utils/observability/tracing.ts
|
|
191
|
+
var tracerCache = void 0;
|
|
192
|
+
function getTracer() {
|
|
193
|
+
if (tracerCache !== void 0) {
|
|
194
|
+
return tracerCache;
|
|
195
|
+
}
|
|
196
|
+
const rawFlag2 = String(process.env.USE_DATADOG_APM || "").toLowerCase();
|
|
197
|
+
const isEnabled2 = rawFlag2 === "true";
|
|
198
|
+
if (!isEnabled2) {
|
|
199
|
+
tracerCache = null;
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const tracerModule = (init_tracer(), __toCommonJS(tracer_exports));
|
|
204
|
+
const tracer2 = tracerModule.default || tracerModule;
|
|
205
|
+
if (tracer2 && typeof tracer2.trace === "function") {
|
|
206
|
+
tracerCache = tracer2;
|
|
207
|
+
return tracerCache;
|
|
208
|
+
}
|
|
209
|
+
} catch (err) {
|
|
210
|
+
console.warn("Failed to load tracer:", err);
|
|
211
|
+
}
|
|
212
|
+
tracerCache = null;
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
async function withTrace(name, fn) {
|
|
216
|
+
const activeTracer = getTracer();
|
|
217
|
+
if (!activeTracer) {
|
|
218
|
+
return fn(void 0);
|
|
219
|
+
}
|
|
220
|
+
return activeTracer.trace(name, async (span) => {
|
|
221
|
+
if (span) {
|
|
222
|
+
span.setTag("component", "application");
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
const result = await fn(span);
|
|
226
|
+
return result;
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (span) {
|
|
229
|
+
span.setTag("error", error);
|
|
230
|
+
}
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function traceServerAction(name, fn) {
|
|
236
|
+
const spanName = name.startsWith("server.action.") ? name : `server.action.${name}`;
|
|
237
|
+
const traced = async (...args) => {
|
|
238
|
+
return withTrace(spanName, async (span) => {
|
|
239
|
+
if (span) {
|
|
240
|
+
span.setTag("component", "server-action");
|
|
241
|
+
}
|
|
242
|
+
const result = await fn(...args);
|
|
243
|
+
return result;
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
return traced;
|
|
247
|
+
}
|
|
248
|
+
var deriveInstallMethods = (licenseData) => {
|
|
249
|
+
const methods = [];
|
|
250
|
+
if (licenseData.isKotsInstallEnabled) {
|
|
251
|
+
methods.push("Replicated KOTS");
|
|
252
|
+
}
|
|
253
|
+
if (licenseData.isHelmInstallEnabled) {
|
|
254
|
+
methods.push("Helm");
|
|
255
|
+
}
|
|
256
|
+
if (licenseData.isHelmAirgapEnabled) {
|
|
257
|
+
methods.push("Helm Airgap");
|
|
258
|
+
}
|
|
259
|
+
if (licenseData.isEmbeddedClusterDownloadEnabled || licenseData.isEmbeddedClusterMultiNodeEnabled) {
|
|
260
|
+
methods.push("Embedded Cluster");
|
|
261
|
+
}
|
|
262
|
+
if (licenseData.isKurlInstallEnabled) {
|
|
263
|
+
methods.push("kURL");
|
|
264
|
+
}
|
|
265
|
+
if (licenseData.isGitopsSupported) {
|
|
266
|
+
methods.push("GitOps");
|
|
267
|
+
}
|
|
268
|
+
return Array.from(new Set(methods));
|
|
269
|
+
};
|
|
270
|
+
var convertEntitlementsToFields = (entitlementFields, entitlementValues) => {
|
|
271
|
+
const valuesMap = /* @__PURE__ */ new Map();
|
|
272
|
+
entitlementValues.forEach((ev) => {
|
|
273
|
+
valuesMap.set(ev.name, ev.value);
|
|
274
|
+
});
|
|
275
|
+
return entitlementFields.filter((field) => field.hidden === 0).map((field) => ({
|
|
276
|
+
key: field.name,
|
|
277
|
+
label: field.title || field.name,
|
|
278
|
+
value: valuesMap.get(field.name) || field.defaultVal || null,
|
|
279
|
+
isSecret: field.type === "Password"
|
|
280
|
+
}));
|
|
281
|
+
};
|
|
282
|
+
async function fetchLicenseCore() {
|
|
283
|
+
const sessionStore = await headers.cookies();
|
|
284
|
+
const session = sessionStore.get("portal_session");
|
|
285
|
+
const token = session?.value;
|
|
286
|
+
if (!token) {
|
|
287
|
+
throw new Error("No session found - user must be authenticated");
|
|
288
|
+
}
|
|
289
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
290
|
+
if (process.env.NODE_ENV !== "production") {
|
|
291
|
+
console.debug("[portal-components] fetching license via %s (Enterprise Portal API)", endpoint);
|
|
292
|
+
}
|
|
293
|
+
const response = await authenticatedFetch(endpoint, {
|
|
294
|
+
method: "GET",
|
|
295
|
+
token,
|
|
296
|
+
headers: {
|
|
297
|
+
Accept: "application/json"
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
if (!response.ok) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`License request failed (${response.status} ${response.statusText})`
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
const envelope = await response.json();
|
|
306
|
+
const licenseData = envelope.data;
|
|
307
|
+
const license = {
|
|
308
|
+
...licenseData,
|
|
309
|
+
// Alias fields for backward compatibility
|
|
310
|
+
expiresAt: licenseData.expireAt,
|
|
311
|
+
environment: licenseData.licenseType,
|
|
312
|
+
// Extract channel names from channels array
|
|
313
|
+
releaseChannels: (licenseData.channels || []).map((ch) => ch.channelName),
|
|
314
|
+
// Derive install methods from feature flags
|
|
315
|
+
installMethods: deriveInstallMethods(licenseData),
|
|
316
|
+
// Convert entitlements to fields format
|
|
317
|
+
fields: convertEntitlementsToFields(licenseData.entitlementFields || [], licenseData.entitlementValues || [])
|
|
318
|
+
};
|
|
319
|
+
return license;
|
|
320
|
+
}
|
|
321
|
+
var fetchLicenseImpl = react.cache(fetchLicenseCore);
|
|
322
|
+
var fetchLicense = fetchLicenseImpl;
|
|
323
|
+
|
|
324
|
+
// src/actions/install.ts
|
|
325
|
+
async function fetchChannelReleases(input, context) {
|
|
326
|
+
const { token, channelId } = input;
|
|
327
|
+
if (!token || typeof token !== "string") {
|
|
328
|
+
throw new Error("fetchChannelReleases requires a session token");
|
|
329
|
+
}
|
|
330
|
+
const origin = getApiOrigin();
|
|
331
|
+
const url = new URL(`${origin}/enterprise-portal/channel-releases`);
|
|
332
|
+
if (channelId) {
|
|
333
|
+
url.searchParams.set("channel_id", channelId);
|
|
334
|
+
}
|
|
335
|
+
if (process.env.NODE_ENV !== "production") {
|
|
336
|
+
console.debug("[portal-components] fetching channel releases via %s (Enterprise Portal API)", url.toString());
|
|
337
|
+
}
|
|
338
|
+
const response = await authenticatedFetch(url.toString(), {
|
|
339
|
+
method: "GET",
|
|
340
|
+
token,
|
|
341
|
+
headers: {
|
|
342
|
+
accept: "application/json"
|
|
343
|
+
},
|
|
344
|
+
signal: context?.signal
|
|
345
|
+
});
|
|
346
|
+
if (!response.ok) {
|
|
347
|
+
const errorText = await response.text();
|
|
348
|
+
throw new Error(
|
|
349
|
+
`Channel releases request failed (${response.status} ${response.statusText}): ${errorText}`
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
const envelope = await response.json();
|
|
353
|
+
const payload = envelope.data;
|
|
354
|
+
return {
|
|
355
|
+
channelReleases: payload?.channelReleases || []
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
async function createInstallOptions(input, context) {
|
|
359
|
+
const {
|
|
360
|
+
token,
|
|
361
|
+
installType,
|
|
362
|
+
instanceName,
|
|
363
|
+
serviceAccountId,
|
|
364
|
+
networkAvailability,
|
|
365
|
+
isMultiNode = false,
|
|
366
|
+
channelId,
|
|
367
|
+
channelReleaseSequence,
|
|
368
|
+
registryAvailability,
|
|
369
|
+
kubernetesDistribution
|
|
370
|
+
} = input;
|
|
371
|
+
if (!token || typeof token !== "string") {
|
|
372
|
+
throw new Error("createInstallOptions requires a session token");
|
|
373
|
+
}
|
|
374
|
+
if (!instanceName?.trim()) {
|
|
375
|
+
throw new Error("Instance name is required");
|
|
376
|
+
}
|
|
377
|
+
if (!serviceAccountId?.trim()) {
|
|
378
|
+
throw new Error("Service account ID is required");
|
|
379
|
+
}
|
|
380
|
+
const origin = getApiOrigin();
|
|
381
|
+
const endpoint = `${origin}/enterprise-portal/install-options?includeInstructions=true`;
|
|
382
|
+
const body = {
|
|
383
|
+
install_type: installType,
|
|
384
|
+
instance_name: instanceName.trim(),
|
|
385
|
+
service_account_id: serviceAccountId.trim(),
|
|
386
|
+
network_availability: networkAvailability,
|
|
387
|
+
is_multi_node: isMultiNode
|
|
388
|
+
};
|
|
389
|
+
if (channelId) {
|
|
390
|
+
body.channel_id = channelId;
|
|
391
|
+
}
|
|
392
|
+
if (channelReleaseSequence !== void 0) {
|
|
393
|
+
body.channel_release_sequence = channelReleaseSequence;
|
|
394
|
+
}
|
|
395
|
+
if (registryAvailability) {
|
|
396
|
+
body.registry_availability = registryAvailability;
|
|
397
|
+
}
|
|
398
|
+
if (kubernetesDistribution) {
|
|
399
|
+
body.kubernetes_distribution = kubernetesDistribution;
|
|
400
|
+
}
|
|
401
|
+
if (process.env.NODE_ENV !== "production") {
|
|
402
|
+
console.debug("[portal-components] creating install options via %s", endpoint);
|
|
403
|
+
}
|
|
404
|
+
const response = await authenticatedFetch(endpoint, {
|
|
405
|
+
method: "POST",
|
|
406
|
+
token,
|
|
407
|
+
headers: {
|
|
408
|
+
"content-type": "application/json",
|
|
409
|
+
accept: "application/json"
|
|
410
|
+
},
|
|
411
|
+
body: JSON.stringify(body),
|
|
412
|
+
signal: context?.signal
|
|
413
|
+
});
|
|
414
|
+
if (!response.ok) {
|
|
415
|
+
const errorText = await response.text();
|
|
416
|
+
throw new Error(
|
|
417
|
+
`Create install options failed (${response.status} ${response.statusText}): ${errorText}`
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
return await response.json();
|
|
421
|
+
}
|
|
422
|
+
async function getInstallOptions(input, context) {
|
|
423
|
+
const {
|
|
424
|
+
token,
|
|
425
|
+
installOptionsId,
|
|
426
|
+
includeInstructions = true,
|
|
427
|
+
privateRegistryHostname,
|
|
428
|
+
proxyUrl
|
|
429
|
+
} = input;
|
|
430
|
+
if (!token || typeof token !== "string") {
|
|
431
|
+
throw new Error("getInstallOptions requires a session token");
|
|
432
|
+
}
|
|
433
|
+
if (!installOptionsId?.trim()) {
|
|
434
|
+
throw new Error("Install options ID is required");
|
|
435
|
+
}
|
|
436
|
+
const origin = getApiOrigin();
|
|
437
|
+
const url = new URL(`${origin}/enterprise-portal/install-options/${installOptionsId.trim()}`);
|
|
438
|
+
if (includeInstructions) {
|
|
439
|
+
url.searchParams.set("includeInstructions", "true");
|
|
440
|
+
}
|
|
441
|
+
if (privateRegistryHostname) {
|
|
442
|
+
url.searchParams.set("privateRegistryHostname", privateRegistryHostname);
|
|
443
|
+
}
|
|
444
|
+
if (proxyUrl) {
|
|
445
|
+
url.searchParams.set("proxyUrl", proxyUrl);
|
|
446
|
+
}
|
|
447
|
+
if (process.env.NODE_ENV !== "production") {
|
|
448
|
+
console.debug("[portal-components] fetching install options via %s (Enterprise Portal API)", url.toString());
|
|
449
|
+
}
|
|
450
|
+
const response = await authenticatedFetch(url.toString(), {
|
|
451
|
+
method: "GET",
|
|
452
|
+
token,
|
|
453
|
+
headers: {
|
|
454
|
+
accept: "application/json"
|
|
455
|
+
},
|
|
456
|
+
signal: context?.signal
|
|
457
|
+
});
|
|
458
|
+
if (!response.ok) {
|
|
459
|
+
const errorText = await response.text();
|
|
460
|
+
throw new Error(
|
|
461
|
+
`Get install options failed (${response.status} ${response.statusText}): ${errorText}`
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
const envelope = await response.json();
|
|
465
|
+
return envelope.data;
|
|
466
|
+
}
|
|
467
|
+
async function updateInstallOptions(input, context) {
|
|
468
|
+
const {
|
|
469
|
+
token,
|
|
470
|
+
installOptionsId,
|
|
471
|
+
installType,
|
|
472
|
+
channelId,
|
|
473
|
+
channelReleaseSequence,
|
|
474
|
+
networkAvailability,
|
|
475
|
+
registryAvailability,
|
|
476
|
+
kubernetesDistribution,
|
|
477
|
+
isMultiNode,
|
|
478
|
+
serviceAccountId,
|
|
479
|
+
adminConsoleUrl,
|
|
480
|
+
status,
|
|
481
|
+
includeInstructions = true,
|
|
482
|
+
privateRegistryHostname,
|
|
483
|
+
proxyUrl
|
|
484
|
+
} = input;
|
|
485
|
+
if (!token || typeof token !== "string") {
|
|
486
|
+
throw new Error("updateInstallOptions requires a session token");
|
|
487
|
+
}
|
|
488
|
+
if (!installOptionsId?.trim()) {
|
|
489
|
+
throw new Error("Install options ID is required");
|
|
490
|
+
}
|
|
491
|
+
const origin = getApiOrigin();
|
|
492
|
+
const url = new URL(`${origin}/enterprise-portal/install-options/${installOptionsId.trim()}`);
|
|
493
|
+
if (includeInstructions) {
|
|
494
|
+
url.searchParams.set("includeInstructions", "true");
|
|
495
|
+
}
|
|
496
|
+
if (privateRegistryHostname) {
|
|
497
|
+
url.searchParams.set("privateRegistryHostname", privateRegistryHostname);
|
|
498
|
+
}
|
|
499
|
+
if (proxyUrl) {
|
|
500
|
+
url.searchParams.set("proxyUrl", proxyUrl);
|
|
501
|
+
}
|
|
502
|
+
const body = {};
|
|
503
|
+
if (installType !== void 0) {
|
|
504
|
+
body.install_type = installType;
|
|
505
|
+
}
|
|
506
|
+
if (channelId !== void 0) {
|
|
507
|
+
body.channel_id = channelId;
|
|
508
|
+
}
|
|
509
|
+
if (channelReleaseSequence !== void 0) {
|
|
510
|
+
body.channel_release_sequence = channelReleaseSequence;
|
|
511
|
+
}
|
|
512
|
+
if (networkAvailability !== void 0) {
|
|
513
|
+
body.network_availability = networkAvailability;
|
|
514
|
+
}
|
|
515
|
+
if (registryAvailability !== void 0) {
|
|
516
|
+
body.registry_availability = registryAvailability;
|
|
517
|
+
}
|
|
518
|
+
if (kubernetesDistribution !== void 0) {
|
|
519
|
+
body.kubernetes_distribution = kubernetesDistribution;
|
|
520
|
+
}
|
|
521
|
+
if (isMultiNode !== void 0) {
|
|
522
|
+
body.is_multi_node = isMultiNode;
|
|
523
|
+
}
|
|
524
|
+
if (serviceAccountId !== void 0) {
|
|
525
|
+
body.service_account_id = serviceAccountId;
|
|
526
|
+
}
|
|
527
|
+
if (adminConsoleUrl !== void 0) {
|
|
528
|
+
body.admin_console_url = adminConsoleUrl;
|
|
529
|
+
}
|
|
530
|
+
if (status !== void 0) {
|
|
531
|
+
body.status = status;
|
|
532
|
+
}
|
|
533
|
+
if (process.env.NODE_ENV !== "production") {
|
|
534
|
+
console.debug("[portal-components] updating install options via %s", url.toString());
|
|
535
|
+
}
|
|
536
|
+
const response = await authenticatedFetch(url.toString(), {
|
|
537
|
+
method: "PATCH",
|
|
538
|
+
token,
|
|
539
|
+
headers: {
|
|
540
|
+
"content-type": "application/json",
|
|
541
|
+
accept: "application/json"
|
|
542
|
+
},
|
|
543
|
+
body: JSON.stringify(body),
|
|
544
|
+
signal: context?.signal
|
|
545
|
+
});
|
|
546
|
+
if (!response.ok) {
|
|
547
|
+
const errorText = await response.text();
|
|
548
|
+
throw new Error(
|
|
549
|
+
`Update install options failed (${response.status} ${response.statusText}): ${errorText}`
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
return await response.json();
|
|
553
|
+
}
|
|
554
|
+
async function fetchPendingInstallations(input, context) {
|
|
555
|
+
const { token } = input;
|
|
556
|
+
if (typeof token !== "string" || token.trim().length === 0) {
|
|
557
|
+
throw new Error("fetchPendingInstallations requires a non-empty token");
|
|
558
|
+
}
|
|
559
|
+
const origin = getApiOrigin();
|
|
560
|
+
const queryParams = new URLSearchParams();
|
|
561
|
+
queryParams.set("status", "in_progress");
|
|
562
|
+
queryParams.set("page_size", "5");
|
|
563
|
+
queryParams.set("order_by", "created_at");
|
|
564
|
+
queryParams.set("order_direction", "desc");
|
|
565
|
+
const endpoint = `${origin}/enterprise-portal/install-options?${queryParams.toString()}`;
|
|
566
|
+
if (process.env.NODE_ENV !== "production") {
|
|
567
|
+
console.debug("[portal-components] fetching pending installations via %s (Enterprise Portal API)", endpoint);
|
|
568
|
+
}
|
|
569
|
+
const response = await authenticatedFetch(endpoint, {
|
|
570
|
+
method: "GET",
|
|
571
|
+
token,
|
|
572
|
+
headers: {
|
|
573
|
+
accept: "application/json"
|
|
574
|
+
},
|
|
575
|
+
signal: context?.signal
|
|
576
|
+
});
|
|
577
|
+
if (!response.ok) {
|
|
578
|
+
throw new Error(
|
|
579
|
+
`Pending installations request failed (${response.status} ${response.statusText})`
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
const envelope = await response.json();
|
|
583
|
+
const payload = envelope.data;
|
|
584
|
+
const installArray = payload?.install_options || [];
|
|
585
|
+
const installations = installArray.map((item) => ({
|
|
586
|
+
id: String(item.id || ""),
|
|
587
|
+
name: String(item.instance_name || "Unknown"),
|
|
588
|
+
method: item.install_type === "helm" ? "helm" : "linux",
|
|
589
|
+
startedBy: String(item.service_account_email_address || "Unknown"),
|
|
590
|
+
startedAt: String(item.started_at || (/* @__PURE__ */ new Date()).toISOString())
|
|
591
|
+
}));
|
|
592
|
+
return {
|
|
593
|
+
installations
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
async function discardInstallation(input, context) {
|
|
597
|
+
const { token, installOptionsId } = input;
|
|
598
|
+
if (typeof token !== "string" || token.trim().length === 0) {
|
|
599
|
+
throw new Error("discardInstallation requires a non-empty token");
|
|
600
|
+
}
|
|
601
|
+
if (typeof installOptionsId !== "string" || installOptionsId.trim().length === 0) {
|
|
602
|
+
throw new Error("discardInstallation requires a non-empty installOptionsId");
|
|
603
|
+
}
|
|
604
|
+
const origin = getApiOrigin();
|
|
605
|
+
const response = await authenticatedFetch(
|
|
606
|
+
`${origin}/enterprise-portal/install-options/${installOptionsId.trim()}`,
|
|
607
|
+
{
|
|
608
|
+
method: "DELETE",
|
|
609
|
+
token,
|
|
610
|
+
headers: {
|
|
611
|
+
accept: "application/json"
|
|
612
|
+
},
|
|
613
|
+
signal: context?.signal
|
|
614
|
+
}
|
|
615
|
+
);
|
|
616
|
+
if (!response.ok) {
|
|
617
|
+
const errorText = await response.text();
|
|
618
|
+
throw new Error(
|
|
619
|
+
`Discard install options failed (${response.status} ${response.statusText}): ${errorText}`
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
return {
|
|
623
|
+
success: true
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// src/actions/install-actions.ts
|
|
628
|
+
async function fetchPendingInstallationsActionImpl() {
|
|
629
|
+
const sessionStore = await headers.cookies();
|
|
630
|
+
const session = sessionStore.get("portal_session");
|
|
631
|
+
const token = session?.value || "";
|
|
632
|
+
if (!token) {
|
|
633
|
+
return { installations: [] };
|
|
634
|
+
}
|
|
635
|
+
return fetchPendingInstallations({ token });
|
|
636
|
+
}
|
|
637
|
+
var fetchPendingInstallationsAction = traceServerAction("fetchPendingInstallationsAction", fetchPendingInstallationsActionImpl);
|
|
638
|
+
async function fetchChannelReleasesActionImpl(token, channelId) {
|
|
639
|
+
return fetchChannelReleases({ token, channelId });
|
|
640
|
+
}
|
|
641
|
+
var fetchChannelReleasesAction = traceServerAction("fetchChannelReleasesAction", fetchChannelReleasesActionImpl);
|
|
642
|
+
async function createInstallOptionsActionImpl(input) {
|
|
643
|
+
return createInstallOptions(input);
|
|
644
|
+
}
|
|
645
|
+
var createInstallOptionsAction = traceServerAction("createInstallOptionsAction", createInstallOptionsActionImpl);
|
|
646
|
+
async function getInstallOptionsActionImpl(input) {
|
|
647
|
+
return getInstallOptions({
|
|
648
|
+
...input,
|
|
649
|
+
includeInstructions: input.includeInstructions ?? true
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
var getInstallOptionsAction = traceServerAction("getInstallOptionsAction", getInstallOptionsActionImpl);
|
|
653
|
+
async function updateInstallOptionsActionImpl(input) {
|
|
654
|
+
return updateInstallOptions({
|
|
655
|
+
...input,
|
|
656
|
+
includeInstructions: input.includeInstructions ?? true
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
var updateInstallOptionsAction = traceServerAction("updateInstallOptionsAction", updateInstallOptionsActionImpl);
|
|
660
|
+
async function discardInstallationActionImpl(installOptionsId) {
|
|
661
|
+
const sessionStore = await headers.cookies();
|
|
662
|
+
const session = sessionStore.get("portal_session");
|
|
663
|
+
const token = session?.value || "";
|
|
664
|
+
if (!token) {
|
|
665
|
+
throw new Error("Authentication required");
|
|
666
|
+
}
|
|
667
|
+
return discardInstallation({ token, installOptionsId });
|
|
668
|
+
}
|
|
669
|
+
var discardInstallationAction = traceServerAction("discardInstallationAction", discardInstallationActionImpl);
|
|
670
|
+
|
|
671
|
+
// src/actions/service-account.ts
|
|
672
|
+
async function createServiceAccountActionImpl(name, token) {
|
|
673
|
+
return createServiceAccount.run({ name, token });
|
|
674
|
+
}
|
|
675
|
+
var createServiceAccountAction = traceServerAction("createServiceAccountAction", createServiceAccountActionImpl);
|
|
676
|
+
async function fetchAppInfoImpl() {
|
|
677
|
+
let appName = "Application";
|
|
678
|
+
let channelName = "";
|
|
679
|
+
const sessionStore = await headers.cookies();
|
|
680
|
+
const session = sessionStore.get("portal_session");
|
|
681
|
+
const token = session?.value;
|
|
682
|
+
if (!token) {
|
|
683
|
+
return { appName, channelName };
|
|
684
|
+
}
|
|
685
|
+
try {
|
|
686
|
+
const branding = await fetchCustomBranding();
|
|
687
|
+
if (branding?.brandingData) {
|
|
688
|
+
const decoded = buffer.Buffer.from(branding.brandingData, "base64").toString("utf-8");
|
|
689
|
+
const brandingObj = JSON.parse(decoded);
|
|
690
|
+
if (brandingObj.title) {
|
|
691
|
+
appName = brandingObj.title;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
} catch (error) {
|
|
695
|
+
console.error("[fetch-app-info] fetchCustomBranding failed", error);
|
|
696
|
+
}
|
|
697
|
+
const license = await fetchLicense();
|
|
698
|
+
if (license?.releaseChannels && license.releaseChannels.length > 0) {
|
|
699
|
+
const channel = license.releaseChannels[0];
|
|
700
|
+
if (channel) {
|
|
701
|
+
channelName = channel;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
return { appName, channelName };
|
|
705
|
+
}
|
|
706
|
+
var fetchAppInfo = traceServerAction("fetchAppInfo", fetchAppInfoImpl);
|
|
707
|
+
async function fetchTeamUsersActionImpl(limit = 25, offset = 0) {
|
|
708
|
+
const sessionStore = await headers.cookies();
|
|
709
|
+
const session = sessionStore.get("portal_session");
|
|
710
|
+
if (!session?.value) {
|
|
711
|
+
throw new Error("No session found");
|
|
712
|
+
}
|
|
713
|
+
const result = await fetchTeamUsers.run({
|
|
714
|
+
token: session.value,
|
|
715
|
+
limit,
|
|
716
|
+
offset
|
|
717
|
+
});
|
|
718
|
+
let currentUserEmail;
|
|
719
|
+
try {
|
|
720
|
+
const payload = decodeJwtPayload(session.value);
|
|
721
|
+
currentUserEmail = payload?.email;
|
|
722
|
+
} catch {
|
|
723
|
+
}
|
|
724
|
+
return {
|
|
725
|
+
users: result.users,
|
|
726
|
+
total: result.total,
|
|
727
|
+
currentUserEmail
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
var fetchTeamUsersAction = traceServerAction("fetchTeamUsersAction", fetchTeamUsersActionImpl);
|
|
731
|
+
async function inviteUserActionImpl(email) {
|
|
732
|
+
const sessionStore = await headers.cookies();
|
|
733
|
+
const session = sessionStore.get("portal_session");
|
|
734
|
+
if (!session?.value) {
|
|
735
|
+
throw new Error("No session found");
|
|
736
|
+
}
|
|
737
|
+
await inviteUser.run({
|
|
738
|
+
token: session.value,
|
|
739
|
+
email
|
|
740
|
+
});
|
|
741
|
+
cache.revalidatePath("/team-settings");
|
|
742
|
+
return { success: true };
|
|
743
|
+
}
|
|
744
|
+
var inviteUserAction = traceServerAction("inviteUserAction", inviteUserActionImpl);
|
|
745
|
+
async function deleteUserActionImpl(id, isPendingInvite) {
|
|
746
|
+
const sessionStore = await headers.cookies();
|
|
747
|
+
const session = sessionStore.get("portal_session");
|
|
748
|
+
if (!session?.value) {
|
|
749
|
+
throw new Error("No session found");
|
|
750
|
+
}
|
|
751
|
+
await deleteUser.run({
|
|
752
|
+
token: session.value,
|
|
753
|
+
id,
|
|
754
|
+
isPendingInvite
|
|
755
|
+
});
|
|
756
|
+
cache.revalidatePath("/team-settings");
|
|
757
|
+
return { success: true };
|
|
758
|
+
}
|
|
759
|
+
var deleteUserAction = traceServerAction("deleteUserAction", deleteUserActionImpl);
|
|
760
|
+
async function fetchServiceAccountsActionImpl(limit = 50, offset = 0, includeRevoked = false) {
|
|
761
|
+
const sessionStore = await headers.cookies();
|
|
762
|
+
const session = sessionStore.get("portal_session");
|
|
763
|
+
if (!session?.value) {
|
|
764
|
+
throw new Error("No session found");
|
|
765
|
+
}
|
|
766
|
+
const result = await fetchServiceAccounts.run({
|
|
767
|
+
token: session.value,
|
|
768
|
+
limit,
|
|
769
|
+
offset,
|
|
770
|
+
includeRevoked
|
|
771
|
+
});
|
|
772
|
+
return {
|
|
773
|
+
serviceAccounts: result.serviceAccounts,
|
|
774
|
+
total: result.total
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
var fetchServiceAccountsAction = traceServerAction("fetchServiceAccountsAction", fetchServiceAccountsActionImpl);
|
|
778
|
+
async function createServiceAccountActionImpl2(name) {
|
|
779
|
+
const sessionStore = await headers.cookies();
|
|
780
|
+
const session = sessionStore.get("portal_session");
|
|
781
|
+
if (!session?.value) {
|
|
782
|
+
throw new Error("No session found");
|
|
783
|
+
}
|
|
784
|
+
const result = await createServiceAccount.run({
|
|
785
|
+
token: session.value,
|
|
786
|
+
name
|
|
787
|
+
});
|
|
788
|
+
cache.revalidatePath("/team-settings");
|
|
789
|
+
return {
|
|
790
|
+
serviceAccount: {
|
|
791
|
+
id: result.service_account.id,
|
|
792
|
+
accountName: result.service_account.accountName
|
|
793
|
+
},
|
|
794
|
+
token: result.token
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
traceServerAction("createServiceAccountAction", createServiceAccountActionImpl2);
|
|
798
|
+
async function revokeServiceAccountActionImpl(accountId) {
|
|
799
|
+
const sessionStore = await headers.cookies();
|
|
800
|
+
const session = sessionStore.get("portal_session");
|
|
801
|
+
if (!session?.value) {
|
|
802
|
+
throw new Error("No session found");
|
|
803
|
+
}
|
|
804
|
+
await revokeServiceAccount.run({
|
|
805
|
+
token: session.value,
|
|
806
|
+
accountId
|
|
807
|
+
});
|
|
808
|
+
cache.revalidatePath("/team-settings");
|
|
809
|
+
return { success: true };
|
|
810
|
+
}
|
|
811
|
+
var revokeServiceAccountAction = traceServerAction("revokeServiceAccountAction", revokeServiceAccountActionImpl);
|
|
812
|
+
async function rotateServiceAccountTokenActionImpl(accountId) {
|
|
813
|
+
const sessionStore = await headers.cookies();
|
|
814
|
+
const session = sessionStore.get("portal_session");
|
|
815
|
+
if (!session?.value) {
|
|
816
|
+
throw new Error("No session found");
|
|
817
|
+
}
|
|
818
|
+
const result = await rotateServiceAccountToken.run({
|
|
819
|
+
token: session.value,
|
|
820
|
+
accountId
|
|
821
|
+
});
|
|
822
|
+
cache.revalidatePath("/team-settings");
|
|
823
|
+
return result;
|
|
824
|
+
}
|
|
825
|
+
var rotateServiceAccountTokenAction = traceServerAction("rotateServiceAccountTokenAction", rotateServiceAccountTokenActionImpl);
|
|
826
|
+
async function fetchInstancesActionImpl() {
|
|
827
|
+
const sessionStore = await headers.cookies();
|
|
828
|
+
const session = sessionStore.get("portal_session");
|
|
829
|
+
if (!session?.value) {
|
|
830
|
+
throw new Error("No session found");
|
|
831
|
+
}
|
|
832
|
+
const result = await fetchInstances.run({
|
|
833
|
+
token: session.value
|
|
834
|
+
});
|
|
835
|
+
return result.instances;
|
|
836
|
+
}
|
|
837
|
+
var fetchInstancesAction = traceServerAction("fetchInstancesAction", fetchInstancesActionImpl);
|
|
838
|
+
async function fetchSamlConfigActionImpl() {
|
|
839
|
+
const sessionStore = await headers.cookies();
|
|
840
|
+
const session = sessionStore.get("portal_session");
|
|
841
|
+
if (!session?.value) {
|
|
842
|
+
throw new Error("No session found");
|
|
843
|
+
}
|
|
844
|
+
const result = await fetchSamlConfig.run({
|
|
845
|
+
token: session.value
|
|
846
|
+
});
|
|
847
|
+
return result.config;
|
|
848
|
+
}
|
|
849
|
+
var fetchSamlConfigAction = traceServerAction("fetchSamlConfigAction", fetchSamlConfigActionImpl);
|
|
850
|
+
async function updateSamlConfigActionImpl(idpMetadataXml, idpPublicCert) {
|
|
851
|
+
const sessionStore = await headers.cookies();
|
|
852
|
+
const session = sessionStore.get("portal_session");
|
|
853
|
+
if (!session?.value) {
|
|
854
|
+
throw new Error("No session found");
|
|
855
|
+
}
|
|
856
|
+
await updateSamlConfig.run({
|
|
857
|
+
token: session.value,
|
|
858
|
+
idpMetadataXml,
|
|
859
|
+
idpPublicCert
|
|
860
|
+
});
|
|
861
|
+
cache.revalidatePath("/team-settings");
|
|
862
|
+
return { success: true };
|
|
863
|
+
}
|
|
864
|
+
var updateSamlConfigAction = traceServerAction("updateSamlConfigAction", updateSamlConfigActionImpl);
|
|
865
|
+
async function toggleSamlEnabledActionImpl(enabled) {
|
|
866
|
+
const sessionStore = await headers.cookies();
|
|
867
|
+
const session = sessionStore.get("portal_session");
|
|
868
|
+
if (!session?.value) {
|
|
869
|
+
throw new Error("No session found");
|
|
870
|
+
}
|
|
871
|
+
const result = await toggleSamlEnabled.run({
|
|
872
|
+
token: session.value,
|
|
873
|
+
enabled
|
|
874
|
+
});
|
|
875
|
+
cache.revalidatePath("/team-settings");
|
|
876
|
+
return result;
|
|
877
|
+
}
|
|
878
|
+
var toggleSamlEnabledAction = traceServerAction("toggleSamlEnabledAction", toggleSamlEnabledActionImpl);
|
|
879
|
+
async function deprovisionSamlActionImpl() {
|
|
880
|
+
const sessionStore = await headers.cookies();
|
|
881
|
+
const session = sessionStore.get("portal_session");
|
|
882
|
+
if (!session?.value) {
|
|
883
|
+
throw new Error("No session found");
|
|
884
|
+
}
|
|
885
|
+
await deprovisionSaml.run({
|
|
886
|
+
token: session.value
|
|
887
|
+
});
|
|
888
|
+
cache.revalidatePath("/team-settings");
|
|
889
|
+
return { success: true };
|
|
890
|
+
}
|
|
891
|
+
var deprovisionSamlAction = traceServerAction("deprovisionSamlAction", deprovisionSamlActionImpl);
|
|
892
|
+
async function fetchAppFeaturesImpl() {
|
|
893
|
+
const sessionStore = await headers.cookies();
|
|
894
|
+
const session = sessionStore.get("portal_session");
|
|
895
|
+
const appSlug = process.env.PORTAL_APP_SLUG;
|
|
896
|
+
if (!appSlug) {
|
|
897
|
+
throw new Error("PORTAL_APP_SLUG is not configured");
|
|
898
|
+
}
|
|
899
|
+
const params = new URLSearchParams({ app_slug: appSlug });
|
|
900
|
+
if (session?.value) {
|
|
901
|
+
try {
|
|
902
|
+
const payload = decodeJwtPayload(session.value);
|
|
903
|
+
const customerId = payload?.customer_id;
|
|
904
|
+
if (customerId) {
|
|
905
|
+
params.set("customer_id", customerId);
|
|
906
|
+
}
|
|
907
|
+
} catch {
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
const url = `${getApiOrigin()}/enterprise-portal/public/app-features?${params.toString()}`;
|
|
911
|
+
const response = await fetch(url, {
|
|
912
|
+
headers: {
|
|
913
|
+
Accept: "application/json"
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
if (!response.ok) {
|
|
917
|
+
throw new Error(`Failed to fetch app features: ${response.status} ${response.statusText}`);
|
|
918
|
+
}
|
|
919
|
+
const data = await response.json();
|
|
920
|
+
return {
|
|
921
|
+
epEnabled: data.ep_enabled ?? false,
|
|
922
|
+
trialSignupEnabled: data.trial_signup_enabled ?? false,
|
|
923
|
+
trialExpirationDays: data.trial_expiration_days ?? 30,
|
|
924
|
+
licenseType: data.license_type ?? "trial",
|
|
925
|
+
termsAndConditionsUrl: data.terms_and_conditions_url ?? "",
|
|
926
|
+
epSecurityCenterEnabled: data.ep_security_center_enabled ?? false,
|
|
927
|
+
epSamlAuthEnabled: data.ep_saml_auth_enabled ?? false,
|
|
928
|
+
epHideSupportBundleUploadEnabled: data.ep_hide_support_bundle_upload_enabled ?? false
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
var fetchAppFeatures = traceServerAction("fetchAppFeatures", fetchAppFeaturesImpl);
|
|
932
|
+
async function fetchCurrentUserActionImpl() {
|
|
933
|
+
const sessionStore = await headers.cookies();
|
|
934
|
+
const session = sessionStore.get("portal_session");
|
|
935
|
+
if (!session?.value) {
|
|
936
|
+
throw new Error("No session found");
|
|
937
|
+
}
|
|
938
|
+
const result = await fetchCurrentUser.run({ token: session.value });
|
|
939
|
+
return result.user;
|
|
940
|
+
}
|
|
941
|
+
var fetchCurrentUserAction = traceServerAction("fetchCurrentUserAction", fetchCurrentUserActionImpl);
|
|
942
|
+
async function updateUserActionImpl(data) {
|
|
943
|
+
const sessionStore = await headers.cookies();
|
|
944
|
+
const session = sessionStore.get("portal_session");
|
|
945
|
+
if (!session?.value) {
|
|
946
|
+
throw new Error("No session found");
|
|
947
|
+
}
|
|
948
|
+
await updateUser.run({
|
|
949
|
+
token: session.value,
|
|
950
|
+
firstName: data.firstName,
|
|
951
|
+
lastName: data.lastName
|
|
952
|
+
});
|
|
953
|
+
cache.revalidatePath("/user-settings");
|
|
954
|
+
return { success: true };
|
|
955
|
+
}
|
|
956
|
+
var updateUserAction = traceServerAction("updateUserAction", updateUserActionImpl);
|
|
957
|
+
async function fetchNotificationsActionImpl(customerId) {
|
|
958
|
+
const sessionStore = await headers.cookies();
|
|
959
|
+
const session = sessionStore.get("portal_session");
|
|
960
|
+
if (!session?.value) {
|
|
961
|
+
throw new Error("No session found");
|
|
962
|
+
}
|
|
963
|
+
const result = await fetchNotifications.run({
|
|
964
|
+
token: session.value,
|
|
965
|
+
customerId
|
|
966
|
+
});
|
|
967
|
+
return result.notifications;
|
|
968
|
+
}
|
|
969
|
+
var fetchNotificationsAction = traceServerAction("fetchNotificationsAction", fetchNotificationsActionImpl);
|
|
970
|
+
async function updateNotificationsActionImpl(customerId, notifications) {
|
|
971
|
+
const sessionStore = await headers.cookies();
|
|
972
|
+
const session = sessionStore.get("portal_session");
|
|
973
|
+
if (!session?.value) {
|
|
974
|
+
throw new Error("No session found");
|
|
975
|
+
}
|
|
976
|
+
const result = await updateNotifications.run({
|
|
977
|
+
token: session.value,
|
|
978
|
+
customerId,
|
|
979
|
+
notifications
|
|
980
|
+
});
|
|
981
|
+
return result.notifications;
|
|
982
|
+
}
|
|
983
|
+
var updateNotificationsAction = traceServerAction("updateNotificationsAction", updateNotificationsActionImpl);
|
|
984
|
+
async function fetchTeamsForUserSettingsImpl() {
|
|
985
|
+
const sessionStore = await headers.cookies();
|
|
986
|
+
const session = sessionStore.get("portal_session");
|
|
987
|
+
if (!session?.value) {
|
|
988
|
+
return { teams: [], currentCustomerId: void 0 };
|
|
989
|
+
}
|
|
990
|
+
const token = session.value;
|
|
991
|
+
const currentCustomerId = getCustomerIdFromToken(token);
|
|
992
|
+
try {
|
|
993
|
+
const result = await fetchCustomers.run({ token });
|
|
994
|
+
const payload = decodeJwtPayload(token);
|
|
995
|
+
const appId = payload?.app_id || "";
|
|
996
|
+
const appSlug = payload?.app_slug || process.env.PORTAL_APP_SLUG || "";
|
|
997
|
+
const appName = appSlug;
|
|
998
|
+
const teams = result.customers.map((c) => ({
|
|
999
|
+
id: c.id,
|
|
1000
|
+
name: c.name,
|
|
1001
|
+
appId,
|
|
1002
|
+
appName,
|
|
1003
|
+
appSlug
|
|
1004
|
+
}));
|
|
1005
|
+
return { teams, currentCustomerId };
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
console.error("[fetch-teams-for-user-settings] Failed to fetch teams:", error);
|
|
1008
|
+
return { teams: [], currentCustomerId };
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
var fetchTeamsForUserSettings = traceServerAction("fetchTeamsForUserSettings", fetchTeamsForUserSettingsImpl);
|
|
1012
|
+
async function changeTeamActionImpl(customerId) {
|
|
1013
|
+
const sessionStore = await headers.cookies();
|
|
1014
|
+
const session = sessionStore.get("portal_session");
|
|
1015
|
+
if (!session?.value) {
|
|
1016
|
+
throw new Error("No session found");
|
|
1017
|
+
}
|
|
1018
|
+
const result = await switchCustomer.run({
|
|
1019
|
+
token: session.value,
|
|
1020
|
+
customerId
|
|
1021
|
+
});
|
|
1022
|
+
sessionStore.delete("portal_session");
|
|
1023
|
+
sessionStore.set("portal_session", result.token, {
|
|
1024
|
+
httpOnly: true,
|
|
1025
|
+
secure: process.env.NODE_ENV === "production",
|
|
1026
|
+
sameSite: "lax",
|
|
1027
|
+
path: "/"
|
|
1028
|
+
});
|
|
1029
|
+
cache.revalidatePath("/", "layout");
|
|
1030
|
+
}
|
|
1031
|
+
var changeTeamAction = traceServerAction("changeTeamAction", changeTeamActionImpl);
|
|
1032
|
+
async function fetchCustomersForMenuImpl() {
|
|
1033
|
+
try {
|
|
1034
|
+
const sessionStore = await headers.cookies();
|
|
1035
|
+
const session = sessionStore.get("portal_session");
|
|
1036
|
+
if (!session?.value) {
|
|
1037
|
+
return { customers: [] };
|
|
1038
|
+
}
|
|
1039
|
+
const token = session.value;
|
|
1040
|
+
const currentCustomerId = getCustomerIdFromToken(token);
|
|
1041
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user`;
|
|
1042
|
+
const response = await authenticatedFetch(endpoint, {
|
|
1043
|
+
method: "GET",
|
|
1044
|
+
token,
|
|
1045
|
+
headers: {
|
|
1046
|
+
Accept: "application/json"
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
1049
|
+
if (!response.ok) {
|
|
1050
|
+
console.error("[fetch-customers-for-menu] Failed to fetch user data:", response.status);
|
|
1051
|
+
return { customers: [], currentCustomerId };
|
|
1052
|
+
}
|
|
1053
|
+
const payload = await response.json();
|
|
1054
|
+
const userData = payload.data;
|
|
1055
|
+
const mappedCustomers = (userData?.customers || []).map((c) => ({
|
|
1056
|
+
id: c.id,
|
|
1057
|
+
name: c.name
|
|
1058
|
+
}));
|
|
1059
|
+
return {
|
|
1060
|
+
customers: mappedCustomers,
|
|
1061
|
+
currentCustomerId
|
|
1062
|
+
};
|
|
1063
|
+
} catch (error) {
|
|
1064
|
+
if (isRedirectError(error)) {
|
|
1065
|
+
throw error;
|
|
1066
|
+
}
|
|
1067
|
+
console.error("[fetch-customers-for-menu] Failed to fetch customers:", error);
|
|
1068
|
+
return { customers: [] };
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
var fetchCustomersForMenu = traceServerAction("fetchCustomersForMenu", fetchCustomersForMenuImpl);
|
|
1072
|
+
async function downloadSupportBundleActionImpl(bundleId) {
|
|
1073
|
+
const sessionStore = await headers.cookies();
|
|
1074
|
+
const session = sessionStore.get("portal_session");
|
|
1075
|
+
if (!session?.value) {
|
|
1076
|
+
return { success: false, error: "Not authenticated" };
|
|
1077
|
+
}
|
|
1078
|
+
try {
|
|
1079
|
+
const result = await downloadSupportBundle.run({
|
|
1080
|
+
token: session.value,
|
|
1081
|
+
bundleId
|
|
1082
|
+
});
|
|
1083
|
+
return { success: true, signedUrl: result.signedUrl };
|
|
1084
|
+
} catch (error) {
|
|
1085
|
+
console.error("[support-bundles] download failed", error);
|
|
1086
|
+
return {
|
|
1087
|
+
success: false,
|
|
1088
|
+
error: error instanceof Error ? error.message : "Failed to download bundle"
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
var downloadSupportBundleAction = traceServerAction("downloadSupportBundleAction", downloadSupportBundleActionImpl);
|
|
1093
|
+
async function deleteSupportBundleActionImpl(bundleId) {
|
|
1094
|
+
const sessionStore = await headers.cookies();
|
|
1095
|
+
const session = sessionStore.get("portal_session");
|
|
1096
|
+
if (!session?.value) {
|
|
1097
|
+
return { success: false, error: "Not authenticated" };
|
|
1098
|
+
}
|
|
1099
|
+
try {
|
|
1100
|
+
await deleteSupportBundle.run({
|
|
1101
|
+
token: session.value,
|
|
1102
|
+
bundleId
|
|
1103
|
+
});
|
|
1104
|
+
return { success: true };
|
|
1105
|
+
} catch (error) {
|
|
1106
|
+
console.error("[support-bundles] delete failed", error);
|
|
1107
|
+
return {
|
|
1108
|
+
success: false,
|
|
1109
|
+
error: error instanceof Error ? error.message : "Failed to delete bundle"
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
var deleteSupportBundleAction = traceServerAction("deleteSupportBundleAction", deleteSupportBundleActionImpl);
|
|
1114
|
+
async function uploadSupportBundleActionImpl(formData) {
|
|
1115
|
+
const sessionStore = await headers.cookies();
|
|
1116
|
+
const session = sessionStore.get("portal_session");
|
|
1117
|
+
if (!session?.value) {
|
|
1118
|
+
return { success: false, error: "Not authenticated" };
|
|
1119
|
+
}
|
|
1120
|
+
const file = formData.get("file");
|
|
1121
|
+
const appId = formData.get("appId");
|
|
1122
|
+
if (!file) {
|
|
1123
|
+
return { success: false, error: "No file provided" };
|
|
1124
|
+
}
|
|
1125
|
+
if (!appId) {
|
|
1126
|
+
return { success: false, error: "No app ID provided" };
|
|
1127
|
+
}
|
|
1128
|
+
const MAX_FILE_SIZE = 500 * 1024 * 1024;
|
|
1129
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
1130
|
+
return { success: false, error: "File size exceeds 500MB limit" };
|
|
1131
|
+
}
|
|
1132
|
+
try {
|
|
1133
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;
|
|
1134
|
+
const response = await authenticatedFetch(endpoint, {
|
|
1135
|
+
method: "POST",
|
|
1136
|
+
token: session.value,
|
|
1137
|
+
headers: {
|
|
1138
|
+
"Content-Type": "application/gzip"
|
|
1139
|
+
},
|
|
1140
|
+
body: file,
|
|
1141
|
+
// @ts-ignore - duplex is needed for streaming but not in TypeScript types yet
|
|
1142
|
+
duplex: "half"
|
|
1143
|
+
});
|
|
1144
|
+
if (!response.ok) {
|
|
1145
|
+
const errorText = await response.text().catch(() => "");
|
|
1146
|
+
throw new Error(`Upload failed: ${response.status} ${response.statusText}${errorText ? `: ${errorText}` : ""}`);
|
|
1147
|
+
}
|
|
1148
|
+
const data = await response.json();
|
|
1149
|
+
return {
|
|
1150
|
+
success: true,
|
|
1151
|
+
bundleId: data.bundleId,
|
|
1152
|
+
bundleSlug: data.slug
|
|
1153
|
+
};
|
|
1154
|
+
} catch (error) {
|
|
1155
|
+
console.error("[support-bundles] upload failed", error);
|
|
1156
|
+
return {
|
|
1157
|
+
success: false,
|
|
1158
|
+
error: error instanceof Error ? error.message : "Failed to upload support bundle"
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
var uploadSupportBundleAction = traceServerAction("uploadSupportBundleAction", uploadSupportBundleActionImpl);
|
|
1163
|
+
async function listSupportBundlesActionImpl() {
|
|
1164
|
+
const sessionStore = await headers.cookies();
|
|
1165
|
+
const session = sessionStore.get("portal_session");
|
|
1166
|
+
if (!session?.value) {
|
|
1167
|
+
return { success: false, error: "Not authenticated" };
|
|
1168
|
+
}
|
|
1169
|
+
try {
|
|
1170
|
+
const result = await listSupportBundles.run({
|
|
1171
|
+
token: session.value
|
|
1172
|
+
});
|
|
1173
|
+
return {
|
|
1174
|
+
success: true,
|
|
1175
|
+
bundles: result.bundles,
|
|
1176
|
+
totalCount: result.totalCount
|
|
1177
|
+
};
|
|
1178
|
+
} catch (error) {
|
|
1179
|
+
console.error("[support-bundles] list failed", error);
|
|
1180
|
+
return {
|
|
1181
|
+
success: false,
|
|
1182
|
+
error: error instanceof Error ? error.message : "Failed to list bundles"
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
var listSupportBundlesAction = traceServerAction("listSupportBundlesAction", listSupportBundlesActionImpl);
|
|
1187
|
+
async function fetchUserCore() {
|
|
1188
|
+
const sessionStore = await headers.cookies();
|
|
1189
|
+
const session = sessionStore.get("portal_session");
|
|
1190
|
+
const token = session?.value;
|
|
1191
|
+
if (!token) {
|
|
1192
|
+
return {};
|
|
1193
|
+
}
|
|
1194
|
+
try {
|
|
1195
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user`;
|
|
1196
|
+
const response = await authenticatedFetch(endpoint, {
|
|
1197
|
+
method: "GET",
|
|
1198
|
+
token,
|
|
1199
|
+
headers: {
|
|
1200
|
+
Accept: "application/json"
|
|
1201
|
+
}
|
|
1202
|
+
});
|
|
1203
|
+
if (!response.ok) {
|
|
1204
|
+
console.error("[fetch-user] API request failed:", response.status);
|
|
1205
|
+
return {};
|
|
1206
|
+
}
|
|
1207
|
+
const data = await response.json();
|
|
1208
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1209
|
+
console.debug("[fetch-user] user data:", data);
|
|
1210
|
+
}
|
|
1211
|
+
return data;
|
|
1212
|
+
} catch (error) {
|
|
1213
|
+
if (isRedirectError(error)) {
|
|
1214
|
+
throw error;
|
|
1215
|
+
}
|
|
1216
|
+
console.error("[fetch-user] Error fetching from API:", error);
|
|
1217
|
+
return {};
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
var fetchUserImpl = traceServerAction("fetchUser", fetchUserCore);
|
|
1221
|
+
var fetchUser = react.cache(fetchUserImpl);
|
|
1222
|
+
|
|
60
1223
|
// src/actions/index.ts
|
|
61
1224
|
var getApiOrigin = () => {
|
|
62
1225
|
return (process.env.REPLICATED_APP_ORIGIN || "https://replicated.app").replace(/\/+$/, "");
|
|
@@ -233,11 +1396,15 @@ var fetchCustomBrandingImpl = async () => {
|
|
|
233
1396
|
const payload = await response.json();
|
|
234
1397
|
const brandingObject = {
|
|
235
1398
|
logo: payload.logoUrl,
|
|
236
|
-
title: payload.
|
|
237
|
-
|
|
238
|
-
|
|
1399
|
+
title: payload.title,
|
|
1400
|
+
primaryColor: payload.primaryColor,
|
|
1401
|
+
secondaryColor: payload.secondaryColor,
|
|
239
1402
|
favicon: payload.faviconUrl,
|
|
240
|
-
supportPortalLink: payload.supportPortalLink || ""
|
|
1403
|
+
supportPortalLink: payload.supportPortalLink || "",
|
|
1404
|
+
background: payload.background,
|
|
1405
|
+
backgroundImage: payload.backgroundImage,
|
|
1406
|
+
customColor1: payload.customColor1,
|
|
1407
|
+
customColor2: payload.customColor2
|
|
241
1408
|
};
|
|
242
1409
|
const brandingData = buffer.Buffer.from(JSON.stringify(brandingObject)).toString("base64");
|
|
243
1410
|
return {
|
|
@@ -500,433 +1667,38 @@ var uploadSupportBundle = defineServerAction({
|
|
|
500
1667
|
var getSupportBundleUploadUrl = (appId) => {
|
|
501
1668
|
return `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;
|
|
502
1669
|
};
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
console.debug("[portal-components] fetching releases via %s (Enterprise Portal API)", endpoint);
|
|
515
|
-
}
|
|
516
|
-
const response = await authenticatedFetch(endpoint, {
|
|
517
|
-
method: "GET",
|
|
518
|
-
token,
|
|
519
|
-
headers: {
|
|
520
|
-
accept: "application/json"
|
|
521
|
-
},
|
|
522
|
-
signal: context?.signal
|
|
523
|
-
});
|
|
524
|
-
const bodyText = await response.text().catch((error) => {
|
|
525
|
-
console.warn("[portal-components] listReleases read error", error);
|
|
526
|
-
return null;
|
|
527
|
-
});
|
|
528
|
-
if (!response.ok) {
|
|
529
|
-
throw new Error(
|
|
530
|
-
`List releases request failed (${response.status} ${response.statusText})`
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
return {
|
|
534
|
-
status: response.status,
|
|
535
|
-
body: bodyText
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
});
|
|
539
|
-
var asRecord = (value) => {
|
|
540
|
-
if (value && typeof value === "object") {
|
|
541
|
-
return value;
|
|
542
|
-
}
|
|
543
|
-
return void 0;
|
|
544
|
-
};
|
|
545
|
-
var getValue = (record, key) => record ? record[key] : void 0;
|
|
546
|
-
var getString = (record, key) => {
|
|
547
|
-
const value = getValue(record, key);
|
|
548
|
-
return typeof value === "string" ? value : void 0;
|
|
549
|
-
};
|
|
550
|
-
var getBoolean = (record, key) => {
|
|
551
|
-
const value = getValue(record, key);
|
|
552
|
-
if (typeof value === "boolean") {
|
|
553
|
-
return value;
|
|
554
|
-
}
|
|
555
|
-
if (typeof value === "number") {
|
|
556
|
-
return value === 1;
|
|
557
|
-
}
|
|
558
|
-
if (typeof value === "string") {
|
|
559
|
-
const normalized = value.trim().toLowerCase();
|
|
560
|
-
if (["true", "1", "yes"].includes(normalized)) {
|
|
561
|
-
return true;
|
|
562
|
-
}
|
|
563
|
-
if (["false", "0", "no"].includes(normalized)) {
|
|
564
|
-
return false;
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
return void 0;
|
|
568
|
-
};
|
|
569
|
-
var toDisplayValue = (value) => {
|
|
570
|
-
if (value === null || value === void 0) {
|
|
571
|
-
return null;
|
|
572
|
-
}
|
|
573
|
-
if (typeof value === "string") {
|
|
574
|
-
return value;
|
|
575
|
-
}
|
|
576
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
577
|
-
return String(value);
|
|
578
|
-
}
|
|
579
|
-
try {
|
|
580
|
-
return JSON.stringify(value);
|
|
581
|
-
} catch {
|
|
582
|
-
return String(value);
|
|
583
|
-
}
|
|
584
|
-
};
|
|
585
|
-
var normalizeStringArray = (value) => {
|
|
586
|
-
if (Array.isArray(value)) {
|
|
587
|
-
const normalized = value.map(
|
|
588
|
-
(item) => typeof item === "string" ? item.trim() : ""
|
|
589
|
-
).filter((item) => item.length > 0);
|
|
590
|
-
return normalized.length ? normalized : void 0;
|
|
591
|
-
}
|
|
592
|
-
if (typeof value === "string") {
|
|
593
|
-
const normalized = value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
594
|
-
return normalized.length ? normalized : void 0;
|
|
595
|
-
}
|
|
596
|
-
return void 0;
|
|
597
|
-
};
|
|
598
|
-
var normalizeLicenseFields = (input) => {
|
|
599
|
-
if (!input) {
|
|
600
|
-
return [];
|
|
601
|
-
}
|
|
602
|
-
if (Array.isArray(input)) {
|
|
603
|
-
return input.map((field, index) => {
|
|
604
|
-
if (!field || typeof field !== "object") {
|
|
605
|
-
return null;
|
|
606
|
-
}
|
|
607
|
-
const candidate = field;
|
|
608
|
-
const key = typeof candidate.key === "string" && candidate.key.trim().length ? candidate.key.trim() : typeof candidate.name === "string" && candidate.name.trim().length ? candidate.name.trim() : typeof candidate.label === "string" && candidate.label.trim().length ? candidate.label.trim() : `field-${index}`;
|
|
609
|
-
const label = typeof candidate.label === "string" && candidate.label.trim().length ? candidate.label.trim() : typeof candidate.name === "string" && candidate.name.trim().length ? candidate.name.trim() : key;
|
|
610
|
-
let value = candidate.value ?? candidate.data ?? candidate.content;
|
|
611
|
-
if ((value === void 0 || value === null) && typeof candidate.text === "string") {
|
|
612
|
-
value = candidate.text;
|
|
613
|
-
}
|
|
614
|
-
if ((value === void 0 || value === null) && typeof candidate.defaultValue === "string") {
|
|
615
|
-
value = candidate.defaultValue;
|
|
616
|
-
}
|
|
617
|
-
const isSecret = Boolean(
|
|
618
|
-
candidate.isSecret ?? candidate.secret ?? candidate.masked
|
|
619
|
-
);
|
|
620
|
-
const resolved = toDisplayValue(value);
|
|
621
|
-
return {
|
|
622
|
-
key,
|
|
623
|
-
label,
|
|
624
|
-
value: resolved,
|
|
625
|
-
isSecret
|
|
626
|
-
};
|
|
627
|
-
}).filter((field) => Boolean(field));
|
|
628
|
-
}
|
|
629
|
-
if (typeof input === "object") {
|
|
630
|
-
return Object.entries(input).map(
|
|
631
|
-
([key, value]) => {
|
|
632
|
-
let resolvedValue = value;
|
|
633
|
-
let isSecret = false;
|
|
634
|
-
if (value && typeof value === "object") {
|
|
635
|
-
const obj = value;
|
|
636
|
-
if ("value" in obj) {
|
|
637
|
-
resolvedValue = obj.value;
|
|
638
|
-
}
|
|
639
|
-
isSecret = Boolean(obj.isSecret ?? obj.secret ?? obj.masked);
|
|
640
|
-
}
|
|
641
|
-
const normalized = toDisplayValue(resolvedValue);
|
|
642
|
-
return {
|
|
643
|
-
key,
|
|
644
|
-
label: key,
|
|
645
|
-
value: normalized,
|
|
646
|
-
isSecret
|
|
647
|
-
};
|
|
648
|
-
}
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
return [];
|
|
652
|
-
};
|
|
653
|
-
var extractChannelNames = (input) => {
|
|
654
|
-
if (!Array.isArray(input)) {
|
|
655
|
-
return void 0;
|
|
1670
|
+
async function listReleasesImpl() {
|
|
1671
|
+
const { cookies: cookies9 } = await import('next/headers');
|
|
1672
|
+
const sessionStore = await cookies9();
|
|
1673
|
+
const session = sessionStore.get("portal_session");
|
|
1674
|
+
const token = session?.value;
|
|
1675
|
+
if (!token) {
|
|
1676
|
+
throw new Error("List releases requires a session token");
|
|
1677
|
+
}
|
|
1678
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/releases`;
|
|
1679
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1680
|
+
console.debug("[portal-components] fetching releases via %s (Enterprise Portal API)", endpoint);
|
|
656
1681
|
}
|
|
657
|
-
const
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
if (!record) {
|
|
663
|
-
return null;
|
|
664
|
-
}
|
|
665
|
-
return getString(record, "name") ?? getString(record, "channelName") ?? getString(record, "channel") ?? getString(record, "channelSlug") ?? getString(record, "slug") ?? void 0;
|
|
666
|
-
}).filter((name) => Boolean(name && name.length));
|
|
667
|
-
return names.length ? names : void 0;
|
|
668
|
-
};
|
|
669
|
-
var normalizeEntitlementFields = (fieldsInput, valuesInput) => {
|
|
670
|
-
const valuesMap = /* @__PURE__ */ new Map();
|
|
671
|
-
const assignValue = (key, value) => {
|
|
672
|
-
if (!key) {
|
|
673
|
-
return;
|
|
1682
|
+
const response = await authenticatedFetch(endpoint, {
|
|
1683
|
+
method: "GET",
|
|
1684
|
+
token,
|
|
1685
|
+
headers: {
|
|
1686
|
+
accept: "application/json"
|
|
674
1687
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
const record = asRecord(item);
|
|
680
|
-
if (!record) {
|
|
681
|
-
if (typeof item === "string") {
|
|
682
|
-
assignValue(item, item);
|
|
683
|
-
}
|
|
684
|
-
return;
|
|
685
|
-
}
|
|
686
|
-
const key = getString(record, "name") ?? getString(record, "field") ?? getString(record, "title") ?? getString(record, "label") ?? getString(record, "slug") ?? (() => {
|
|
687
|
-
const idValue = getValue(record, "id");
|
|
688
|
-
if (typeof idValue === "string" || typeof idValue === "number") {
|
|
689
|
-
return String(idValue);
|
|
690
|
-
}
|
|
691
|
-
return void 0;
|
|
692
|
-
})();
|
|
693
|
-
const value = getValue(record, "value") ?? getValue(record, "currentValue") ?? getValue(record, "entitlementValue") ?? getValue(record, "content") ?? getValue(record, "data") ?? getValue(record, "defaultVal") ?? getValue(record, "defaultValue");
|
|
694
|
-
assignValue(key, value);
|
|
695
|
-
});
|
|
696
|
-
} else if (valuesInput && typeof valuesInput === "object") {
|
|
697
|
-
Object.entries(valuesInput).forEach(
|
|
698
|
-
([key, value]) => assignValue(key, value)
|
|
1688
|
+
});
|
|
1689
|
+
if (!response.ok) {
|
|
1690
|
+
throw new Error(
|
|
1691
|
+
`List releases request failed (${response.status} ${response.statusText})`
|
|
699
1692
|
);
|
|
700
1693
|
}
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
const baseKey = getString(record, "name") ?? getString(record, "field") ?? getString(record, "slug") ?? `entitlement-${index}`;
|
|
709
|
-
const key = `entitlement-${baseKey}`;
|
|
710
|
-
const label = getString(record, "title") ?? getString(record, "label") ?? baseKey;
|
|
711
|
-
const defaultValue = getString(record, "defaultVal") ?? getString(record, "default") ?? getString(record, "defaultValue");
|
|
712
|
-
const value = valuesMap.get(baseKey) ?? valuesMap.get(label) ?? defaultValue ?? null;
|
|
713
|
-
const isSecret = Boolean(
|
|
714
|
-
getBoolean(record, "secret") ?? getBoolean(record, "isSecret") ?? getBoolean(record, "masked")
|
|
715
|
-
);
|
|
716
|
-
normalized.push({
|
|
717
|
-
key,
|
|
718
|
-
label,
|
|
719
|
-
value,
|
|
720
|
-
isSecret
|
|
721
|
-
});
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
valuesMap.forEach((value, key) => {
|
|
725
|
-
const normalizedKey = `entitlement-${key}`;
|
|
726
|
-
if (!normalized.some((field) => field.key === normalizedKey)) {
|
|
727
|
-
normalized.push({
|
|
728
|
-
key: normalizedKey,
|
|
729
|
-
label: key,
|
|
730
|
-
value
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
});
|
|
734
|
-
return normalized;
|
|
735
|
-
};
|
|
736
|
-
var normalizeLicensePayload = (payload) => {
|
|
737
|
-
const payloadRecord = asRecord(payload);
|
|
738
|
-
const rootRecord = asRecord(getValue(payloadRecord, "license")) ?? asRecord(getValue(payloadRecord, "data")) ?? payloadRecord ?? {};
|
|
739
|
-
const sourceRecord = asRecord(getValue(rootRecord, "metadata")) ?? rootRecord;
|
|
740
|
-
const customer = asRecord(getValue(rootRecord, "customer")) ?? asRecord(getValue(sourceRecord, "customer")) ?? asRecord(getValue(payloadRecord, "customer")) ?? {};
|
|
741
|
-
let releaseChannels = normalizeStringArray(
|
|
742
|
-
getValue(rootRecord, "releaseChannels") ?? getValue(sourceRecord, "releaseChannels") ?? getValue(sourceRecord, "channels") ?? getValue(rootRecord, "channels") ?? getValue(sourceRecord, "channel") ?? getValue(rootRecord, "channel")
|
|
743
|
-
) ?? void 0;
|
|
744
|
-
if (!releaseChannels) {
|
|
745
|
-
releaseChannels = extractChannelNames(getValue(rootRecord, "channels")) ?? extractChannelNames(getValue(sourceRecord, "channels")) ?? void 0;
|
|
746
|
-
}
|
|
747
|
-
let installMethods = normalizeStringArray(
|
|
748
|
-
getValue(rootRecord, "installMethods") ?? getValue(sourceRecord, "installMethods") ?? getValue(sourceRecord, "install_options") ?? getValue(rootRecord, "install_options") ?? getValue(sourceRecord, "installOptions")
|
|
749
|
-
) ?? void 0;
|
|
750
|
-
if (!installMethods || installMethods.length === 0) {
|
|
751
|
-
const resolved = [];
|
|
752
|
-
const flag = (key) => getBoolean(rootRecord, key) ?? getBoolean(sourceRecord, key) ?? false;
|
|
753
|
-
if (flag("isKotsInstallEnabled")) {
|
|
754
|
-
resolved.push("Replicated KOTS");
|
|
755
|
-
}
|
|
756
|
-
if (flag("isHelmInstallEnabled")) {
|
|
757
|
-
resolved.push("Helm");
|
|
758
|
-
}
|
|
759
|
-
if (flag("isHelmAirgapEnabled")) {
|
|
760
|
-
resolved.push("Helm Airgap");
|
|
761
|
-
}
|
|
762
|
-
if (flag("isEmbeddedClusterDownloadEnabled") || flag("isEmbeddedClusterMultiNodeEnabled")) {
|
|
763
|
-
resolved.push("Embedded Cluster");
|
|
764
|
-
}
|
|
765
|
-
if (flag("isKurlInstallEnabled")) {
|
|
766
|
-
resolved.push("kURL");
|
|
767
|
-
}
|
|
768
|
-
if (flag("isGitopsSupported")) {
|
|
769
|
-
resolved.push("GitOps");
|
|
770
|
-
}
|
|
771
|
-
if (resolved.length) {
|
|
772
|
-
installMethods = Array.from(new Set(resolved));
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
const expiresAtSource = getValue(sourceRecord, "expiresAt") ?? getValue(sourceRecord, "expireAt") ?? getValue(sourceRecord, "expire_at") ?? getValue(sourceRecord, "expiration") ?? getValue(sourceRecord, "expirationDate") ?? getValue(sourceRecord, "expires_on") ?? getValue(rootRecord, "expiresAt") ?? getValue(rootRecord, "expireAt") ?? getValue(rootRecord, "expire_at") ?? getValue(rootRecord, "expiration");
|
|
776
|
-
const expiresAt = typeof expiresAtSource === "string" && expiresAtSource.trim().length ? expiresAtSource : expiresAtSource === null ? null : void 0;
|
|
777
|
-
const baseFields = normalizeLicenseFields(
|
|
778
|
-
getValue(rootRecord, "additionalFields") ?? getValue(sourceRecord, "additionalFields") ?? getValue(sourceRecord, "fields") ?? getValue(rootRecord, "fields") ?? getValue(payloadRecord, "fields") ?? getValue(payloadRecord, "additional_fields")
|
|
779
|
-
);
|
|
780
|
-
const entitlementFields = normalizeEntitlementFields(
|
|
781
|
-
getValue(rootRecord, "entitlementFields") ?? getValue(sourceRecord, "entitlementFields"),
|
|
782
|
-
getValue(rootRecord, "entitlementValues") ?? getValue(sourceRecord, "entitlementValues")
|
|
783
|
-
);
|
|
784
|
-
const fields = [
|
|
785
|
-
...baseFields,
|
|
786
|
-
...entitlementFields.filter(
|
|
787
|
-
(field) => !baseFields.some((existing) => existing.key === field.key)
|
|
788
|
-
)
|
|
789
|
-
];
|
|
790
|
-
const statusFromSource = getString(sourceRecord, "status") ?? getString(sourceRecord, "state");
|
|
791
|
-
const statusLabelFromSource = getString(sourceRecord, "statusLabel") ?? getString(sourceRecord, "stateLabel");
|
|
792
|
-
const expiredFlag = getBoolean(sourceRecord, "isExpired") ?? getBoolean(rootRecord, "isExpired");
|
|
793
|
-
const derivedStatus = statusFromSource ?? (typeof expiredFlag === "boolean" ? expiredFlag ? "expired" : "active" : void 0);
|
|
794
|
-
const statusLabel = statusLabelFromSource ?? (derivedStatus ? derivedStatus.charAt(0).toUpperCase() + derivedStatus.slice(1) : void 0);
|
|
795
|
-
const licenseType = getString(sourceRecord, "licenseType") ?? getString(rootRecord, "licenseType");
|
|
796
|
-
const status = derivedStatus;
|
|
797
|
-
const license = {
|
|
798
|
-
id: getString(rootRecord, "id") ?? getString(sourceRecord, "id") ?? getString(sourceRecord, "licenseId") ?? getString(customer, "licenseId") ?? void 0,
|
|
799
|
-
status,
|
|
800
|
-
statusLabel,
|
|
801
|
-
environment: getString(sourceRecord, "environment") ?? getString(sourceRecord, "tier") ?? licenseType ?? void 0,
|
|
802
|
-
expiresAt: expiresAt ?? null,
|
|
803
|
-
releaseChannels: releaseChannels ?? [
|
|
804
|
-
getString(rootRecord, "channelName") ?? getString(rootRecord, "channel") ?? void 0
|
|
805
|
-
].filter((value) => Boolean(value)),
|
|
806
|
-
installMethods,
|
|
807
|
-
installNotes: getString(sourceRecord, "installNotes"),
|
|
808
|
-
customerName: getString(sourceRecord, "customerName") ?? getString(customer, "name") ?? void 0,
|
|
809
|
-
customerId: getString(sourceRecord, "customerId") ?? getString(customer, "id") ?? getString(rootRecord, "customerId") ?? void 0,
|
|
810
|
-
customerOrganization: getString(customer, "organization") ?? getString(sourceRecord, "customerOrganization") ?? getString(rootRecord, "customerOrganization") ?? void 0,
|
|
811
|
-
fields
|
|
1694
|
+
const envelope = await response.json();
|
|
1695
|
+
const data = envelope.data;
|
|
1696
|
+
return {
|
|
1697
|
+
releases: Array.isArray(data?.releases) ? data.releases : [],
|
|
1698
|
+
totalCount: data?.totalCount || 0
|
|
812
1699
|
};
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
var fetchLicenseDetails = defineServerAction({
|
|
816
|
-
id: "license/fetch-details",
|
|
817
|
-
description: "Fetches the authenticated user's enterprise license details.",
|
|
818
|
-
visibility: "customer",
|
|
819
|
-
tags: ["license", "entitlements"],
|
|
820
|
-
async run({ token }, context) {
|
|
821
|
-
if (typeof token !== "string" || token.trim().length === 0) {
|
|
822
|
-
throw new Error("fetchLicenseDetails requires a non-empty token");
|
|
823
|
-
}
|
|
824
|
-
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
825
|
-
if (process.env.NODE_ENV !== "production") {
|
|
826
|
-
console.debug("[portal-components] fetching license via %s (Enterprise Portal API)", endpoint);
|
|
827
|
-
}
|
|
828
|
-
const response = await authenticatedFetch(endpoint, {
|
|
829
|
-
method: "GET",
|
|
830
|
-
token,
|
|
831
|
-
headers: {
|
|
832
|
-
accept: "application/json"
|
|
833
|
-
},
|
|
834
|
-
signal: context?.signal
|
|
835
|
-
});
|
|
836
|
-
if (!response.ok) {
|
|
837
|
-
throw new Error(
|
|
838
|
-
`License request failed (${response.status} ${response.statusText})`
|
|
839
|
-
);
|
|
840
|
-
}
|
|
841
|
-
const payload = await response.json();
|
|
842
|
-
const licenseData = payload.data;
|
|
843
|
-
const license = normalizeLicensePayload(licenseData);
|
|
844
|
-
return {
|
|
845
|
-
license,
|
|
846
|
-
raw: licenseData ?? null
|
|
847
|
-
};
|
|
848
|
-
}
|
|
849
|
-
});
|
|
850
|
-
var fetchInstallOptions = defineServerAction({
|
|
851
|
-
id: "license/fetch-install-options",
|
|
852
|
-
description: "Fetches install options based on license entitlements.",
|
|
853
|
-
visibility: "customer",
|
|
854
|
-
tags: ["license", "install"],
|
|
855
|
-
async run({ token }, context) {
|
|
856
|
-
if (typeof token !== "string" || token.trim().length === 0) {
|
|
857
|
-
throw new Error("fetchInstallOptions requires a non-empty token");
|
|
858
|
-
}
|
|
859
|
-
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
860
|
-
if (process.env.NODE_ENV !== "production") {
|
|
861
|
-
console.debug("[portal-components] fetching install options via %s (Enterprise Portal API)", endpoint);
|
|
862
|
-
}
|
|
863
|
-
const response = await authenticatedFetch(endpoint, {
|
|
864
|
-
method: "GET",
|
|
865
|
-
token,
|
|
866
|
-
headers: {
|
|
867
|
-
accept: "application/json"
|
|
868
|
-
},
|
|
869
|
-
signal: context?.signal
|
|
870
|
-
});
|
|
871
|
-
if (!response.ok) {
|
|
872
|
-
throw new Error(
|
|
873
|
-
`License request failed (${response.status} ${response.statusText})`
|
|
874
|
-
);
|
|
875
|
-
}
|
|
876
|
-
const envelope = await response.json();
|
|
877
|
-
const licenseData = envelope.data;
|
|
878
|
-
const getBoolean2 = (obj, key) => {
|
|
879
|
-
if (obj && typeof obj === "object" && key in obj) {
|
|
880
|
-
const val = obj[key];
|
|
881
|
-
return val === true || val === "true";
|
|
882
|
-
}
|
|
883
|
-
return false;
|
|
884
|
-
};
|
|
885
|
-
const showLinux = getBoolean2(licenseData, "isEmbeddedClusterDownloadEnabled");
|
|
886
|
-
const showHelm = getBoolean2(licenseData, "isHelmInstallEnabled");
|
|
887
|
-
return {
|
|
888
|
-
showLinux,
|
|
889
|
-
showHelm
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
});
|
|
893
|
-
var fetchLicenseSummary = defineServerAction({
|
|
894
|
-
id: "license/fetch-summary",
|
|
895
|
-
description: "Fetches license summary for the license card.",
|
|
896
|
-
visibility: "customer",
|
|
897
|
-
tags: ["license"],
|
|
898
|
-
async run({ token }, context) {
|
|
899
|
-
if (typeof token !== "string" || token.trim().length === 0) {
|
|
900
|
-
throw new Error("fetchLicenseSummary requires a non-empty token");
|
|
901
|
-
}
|
|
902
|
-
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
903
|
-
if (process.env.NODE_ENV !== "production") {
|
|
904
|
-
console.debug("[portal-components] fetching license summary via %s (Enterprise Portal API)", endpoint);
|
|
905
|
-
}
|
|
906
|
-
const response = await authenticatedFetch(endpoint, {
|
|
907
|
-
method: "GET",
|
|
908
|
-
token,
|
|
909
|
-
headers: {
|
|
910
|
-
accept: "application/json"
|
|
911
|
-
},
|
|
912
|
-
signal: context?.signal
|
|
913
|
-
});
|
|
914
|
-
if (!response.ok) {
|
|
915
|
-
throw new Error(
|
|
916
|
-
`License request failed (${response.status} ${response.statusText})`
|
|
917
|
-
);
|
|
918
|
-
}
|
|
919
|
-
const envelope = await response.json();
|
|
920
|
-
const licenseData = envelope.data;
|
|
921
|
-
const license = normalizeLicensePayload(licenseData);
|
|
922
|
-
const type = license.environment || "Unknown";
|
|
923
|
-
const expiresAt = license.expiresAt || null;
|
|
924
|
-
return {
|
|
925
|
-
type,
|
|
926
|
-
expiresAt
|
|
927
|
-
};
|
|
928
|
-
}
|
|
929
|
-
});
|
|
1700
|
+
}
|
|
1701
|
+
var listReleases = traceServerAction("listReleases", listReleasesImpl);
|
|
930
1702
|
var fetchCustomers = defineServerAction({
|
|
931
1703
|
id: "auth/fetch-customers",
|
|
932
1704
|
description: "Fetches the list of customers/teams for the authenticated user.",
|
|
@@ -1977,47 +2749,77 @@ var refreshInvite = defineServerAction({
|
|
|
1977
2749
|
});
|
|
1978
2750
|
|
|
1979
2751
|
exports.acceptInvite = acceptInvite;
|
|
2752
|
+
exports.changeTeamAction = changeTeamAction;
|
|
2753
|
+
exports.createInstallOptionsAction = createInstallOptionsAction;
|
|
1980
2754
|
exports.createServiceAccount = createServiceAccount;
|
|
2755
|
+
exports.createServiceAccountAction = createServiceAccountAction;
|
|
1981
2756
|
exports.decodeJwtPayload = decodeJwtPayload;
|
|
1982
2757
|
exports.defineServerAction = defineServerAction;
|
|
1983
2758
|
exports.deleteSupportBundle = deleteSupportBundle;
|
|
2759
|
+
exports.deleteSupportBundleAction = deleteSupportBundleAction;
|
|
1984
2760
|
exports.deleteUser = deleteUser;
|
|
2761
|
+
exports.deleteUserAction = deleteUserAction;
|
|
1985
2762
|
exports.deprovisionSaml = deprovisionSaml;
|
|
2763
|
+
exports.deprovisionSamlAction = deprovisionSamlAction;
|
|
2764
|
+
exports.discardInstallationAction = discardInstallationAction;
|
|
1986
2765
|
exports.downloadSecuritySBOM = downloadSecuritySBOM;
|
|
1987
2766
|
exports.downloadSupportBundle = downloadSupportBundle;
|
|
2767
|
+
exports.downloadSupportBundleAction = downloadSupportBundleAction;
|
|
2768
|
+
exports.fetchAppFeatures = fetchAppFeatures;
|
|
2769
|
+
exports.fetchAppInfo = fetchAppInfo;
|
|
2770
|
+
exports.fetchChannelReleasesAction = fetchChannelReleasesAction;
|
|
1988
2771
|
exports.fetchCurrentUser = fetchCurrentUser;
|
|
2772
|
+
exports.fetchCurrentUserAction = fetchCurrentUserAction;
|
|
1989
2773
|
exports.fetchCustomBranding = fetchCustomBranding;
|
|
1990
2774
|
exports.fetchCustomers = fetchCustomers;
|
|
2775
|
+
exports.fetchCustomersForMenu = fetchCustomersForMenu;
|
|
1991
2776
|
exports.fetchDashboardComposite = fetchDashboardComposite;
|
|
1992
2777
|
exports.fetchDashboardInstances = fetchDashboardInstances;
|
|
1993
|
-
exports.fetchInstallOptions = fetchInstallOptions;
|
|
1994
2778
|
exports.fetchInstances = fetchInstances;
|
|
1995
|
-
exports.
|
|
1996
|
-
exports.
|
|
2779
|
+
exports.fetchInstancesAction = fetchInstancesAction;
|
|
2780
|
+
exports.fetchLicense = fetchLicense;
|
|
1997
2781
|
exports.fetchNotifications = fetchNotifications;
|
|
2782
|
+
exports.fetchNotificationsAction = fetchNotificationsAction;
|
|
2783
|
+
exports.fetchPendingInstallationsAction = fetchPendingInstallationsAction;
|
|
1998
2784
|
exports.fetchSamlConfig = fetchSamlConfig;
|
|
2785
|
+
exports.fetchSamlConfigAction = fetchSamlConfigAction;
|
|
1999
2786
|
exports.fetchServiceAccounts = fetchServiceAccounts;
|
|
2787
|
+
exports.fetchServiceAccountsAction = fetchServiceAccountsAction;
|
|
2000
2788
|
exports.fetchTeamStats = fetchTeamStats;
|
|
2001
2789
|
exports.fetchTeamUsers = fetchTeamUsers;
|
|
2790
|
+
exports.fetchTeamUsersAction = fetchTeamUsersAction;
|
|
2791
|
+
exports.fetchTeamsForUserSettings = fetchTeamsForUserSettings;
|
|
2792
|
+
exports.fetchUser = fetchUser;
|
|
2002
2793
|
exports.getApiOrigin = getApiOrigin;
|
|
2003
2794
|
exports.getCustomerIdFromToken = getCustomerIdFromToken;
|
|
2795
|
+
exports.getInstallOptionsAction = getInstallOptionsAction;
|
|
2004
2796
|
exports.getSecurityInfo = getSecurityInfo;
|
|
2005
2797
|
exports.getSecurityInfoDiff = getSecurityInfoDiff;
|
|
2006
2798
|
exports.getSecurityInfoSBOM = getSecurityInfoSBOM;
|
|
2007
2799
|
exports.getSupportBundleUploadUrl = getSupportBundleUploadUrl;
|
|
2008
2800
|
exports.initiateLogin = initiateLogin;
|
|
2009
2801
|
exports.inviteUser = inviteUser;
|
|
2802
|
+
exports.inviteUserAction = inviteUserAction;
|
|
2010
2803
|
exports.listReleases = listReleases;
|
|
2011
2804
|
exports.listSupportBundles = listSupportBundles;
|
|
2805
|
+
exports.listSupportBundlesAction = listSupportBundlesAction;
|
|
2012
2806
|
exports.refreshInvite = refreshInvite;
|
|
2013
2807
|
exports.revokeServiceAccount = revokeServiceAccount;
|
|
2808
|
+
exports.revokeServiceAccountAction = revokeServiceAccountAction;
|
|
2014
2809
|
exports.rotateServiceAccountToken = rotateServiceAccountToken;
|
|
2810
|
+
exports.rotateServiceAccountTokenAction = rotateServiceAccountTokenAction;
|
|
2015
2811
|
exports.switchCustomer = switchCustomer;
|
|
2016
2812
|
exports.toggleSamlEnabled = toggleSamlEnabled;
|
|
2813
|
+
exports.toggleSamlEnabledAction = toggleSamlEnabledAction;
|
|
2814
|
+
exports.updateInstallOptionsAction = updateInstallOptionsAction;
|
|
2017
2815
|
exports.updateNotifications = updateNotifications;
|
|
2816
|
+
exports.updateNotificationsAction = updateNotificationsAction;
|
|
2018
2817
|
exports.updateSamlConfig = updateSamlConfig;
|
|
2818
|
+
exports.updateSamlConfigAction = updateSamlConfigAction;
|
|
2019
2819
|
exports.updateUser = updateUser;
|
|
2820
|
+
exports.updateUserAction = updateUserAction;
|
|
2020
2821
|
exports.uploadSupportBundle = uploadSupportBundle;
|
|
2822
|
+
exports.uploadSupportBundleAction = uploadSupportBundleAction;
|
|
2021
2823
|
exports.verifyMagicLink = verifyMagicLink;
|
|
2022
2824
|
//# sourceMappingURL=index.js.map
|
|
2023
2825
|
//# sourceMappingURL=index.js.map
|