@replicated/portal-components 0.0.19 → 0.0.21
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.js +66 -7
- package/dist/actions/change-team.js.map +1 -1
- package/dist/actions/index.d.mts +3 -1
- package/dist/actions/index.d.ts +3 -1
- package/dist/actions/index.js +182 -465
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/install-actions.d.mts +3 -1
- package/dist/actions/install-actions.d.ts +3 -1
- package/dist/actions/install-actions.js +58 -5
- package/dist/actions/install-actions.js.map +1 -1
- package/dist/actions/service-account.d.mts +3 -1
- package/dist/actions/service-account.d.ts +3 -1
- package/dist/actions/service-account.js +58 -5
- package/dist/actions/service-account.js.map +1 -1
- package/dist/actions/support-bundles.d.mts +3 -1
- package/dist/actions/support-bundles.d.ts +3 -1
- package/dist/actions/support-bundles.js +58 -5
- package/dist/actions/support-bundles.js.map +1 -1
- package/dist/actions/team-settings.d.mts +3 -1
- package/dist/actions/team-settings.d.ts +3 -1
- package/dist/actions/team-settings.js +91 -27
- package/dist/actions/team-settings.js.map +1 -1
- 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 +3 -1
- package/dist/actions/user-settings.d.ts +3 -1
- package/dist/actions/user-settings.js +58 -5
- package/dist/actions/user-settings.js.map +1 -1
- package/dist/airgap-instances.d.mts +3 -1
- package/dist/airgap-instances.d.ts +3 -1
- package/dist/airgap-instances.js +41 -112
- 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 +66 -7
- package/dist/esm/actions/change-team.js.map +1 -1
- package/dist/esm/actions/index.js +181 -462
- package/dist/esm/actions/index.js.map +1 -1
- package/dist/esm/actions/install-actions.js +58 -5
- package/dist/esm/actions/install-actions.js.map +1 -1
- package/dist/esm/actions/service-account.js +58 -5
- package/dist/esm/actions/service-account.js.map +1 -1
- package/dist/esm/actions/support-bundles.js +58 -5
- package/dist/esm/actions/support-bundles.js.map +1 -1
- package/dist/esm/actions/team-settings.js +91 -27
- package/dist/esm/actions/team-settings.js.map +1 -1
- 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 +58 -5
- package/dist/esm/actions/user-settings.js.map +1 -1
- package/dist/esm/airgap-instances.js +40 -112
- 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 +118 -79
- 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 +39 -111
- 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 +95 -41
- 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 +40 -112
- package/dist/esm/online-instance-list.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 +48 -24
- 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 +11 -3
- package/dist/helm-install-wizard.d.ts +11 -3
- package/dist/helm-install-wizard.js +118 -79
- package/dist/helm-install-wizard.js.map +1 -1
- package/dist/{index-BAiVrSSR.d.mts → index-DyzJ0yKD.d.mts} +48 -50
- package/dist/{index-DWt-N5od.d.ts → index-sMbq94M7.d.ts} +48 -50
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +726 -438
- package/dist/index.js.map +1 -1
- package/dist/install-actions.d.mts +4 -2
- package/dist/install-actions.d.ts +4 -2
- package/dist/install-actions.js +40 -5
- package/dist/install-actions.js.map +1 -1
- package/dist/install-card.d.mts +2 -3
- package/dist/install-card.d.ts +2 -3
- 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 +3 -1
- package/dist/instance-card.d.ts +3 -1
- package/dist/instance-card.js +40 -111
- 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 -3
- package/dist/license-card.d.ts +2 -3
- 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 +9 -3
- package/dist/linux-install-wizard.d.ts +9 -3
- package/dist/linux-install-wizard.js +95 -41
- 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 +3 -1
- package/dist/online-instance-list.d.ts +3 -1
- package/dist/online-instance-list.js +41 -112
- package/dist/online-instance-list.js.map +1 -1
- package/dist/pending-installations.d.mts +3 -1
- package/dist/pending-installations.d.ts +3 -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 +3 -1
- package/dist/security-card.d.ts +3 -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 +375 -127
- 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 +47 -23
- package/dist/support-bundle-collection-card.js.map +1 -1
- package/dist/support-bundles-card.d.mts +4 -2
- package/dist/support-bundles-card.d.ts +4 -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 +37 -2
package/dist/esm/index.js
CHANGED
|
@@ -1,16 +1,126 @@
|
|
|
1
1
|
import { forwardRef, cache, useState, useMemo } from 'react';
|
|
2
2
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { Buffer } from 'buffer';
|
|
4
|
+
import { cookies } from 'next/headers';
|
|
4
5
|
import Link from 'next/link';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Enterprise Portal Components
|
|
8
9
|
* This file is generated by tsup. Do not edit manually.
|
|
9
10
|
*/
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
16
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
17
|
+
}) : x)(function(x) {
|
|
18
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
19
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
20
|
+
});
|
|
21
|
+
var __esm = (fn, res) => function __init() {
|
|
22
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
23
|
+
};
|
|
24
|
+
var __export = (target, all) => {
|
|
25
|
+
for (var name in all)
|
|
26
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
+
};
|
|
28
|
+
var __copyProps = (to, from, except, desc) => {
|
|
29
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
30
|
+
for (let key of __getOwnPropNames(from))
|
|
31
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
32
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
33
|
+
}
|
|
34
|
+
return to;
|
|
35
|
+
};
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
|
|
38
|
+
// datadog/tracer.ts
|
|
39
|
+
var tracer_exports = {};
|
|
40
|
+
__export(tracer_exports, {
|
|
41
|
+
default: () => tracer_default
|
|
42
|
+
});
|
|
43
|
+
var rawFlag, isEnabled, tracer, getRoutePattern, tracer_default;
|
|
44
|
+
var init_tracer = __esm({
|
|
45
|
+
"datadog/tracer.ts"() {
|
|
46
|
+
rawFlag = String(process.env.USE_DATADOG_APM || "").toLowerCase();
|
|
47
|
+
isEnabled = rawFlag === "true";
|
|
48
|
+
process.env.DD_TRACE_ENABLED = isEnabled ? "1" : "0";
|
|
49
|
+
tracer = null;
|
|
50
|
+
if (isEnabled) {
|
|
51
|
+
const serviceName = process.env.DD_SERVICE || "enterprise-portal";
|
|
52
|
+
const environment = process.env.DD_ENV || process.env.NODE_ENV || "development";
|
|
53
|
+
const version = process.env.DD_VERSION || process.env.NEXT_PUBLIC_VERSION || "0.0.0-dev";
|
|
54
|
+
const agentHost = process.env.DD_AGENT_HOST || process.env.DATADOG_AGENT_HOST || "127.0.0.1";
|
|
55
|
+
const agentPort = process.env.DD_TRACE_AGENT_PORT || "8126";
|
|
56
|
+
process.env.DD_SERVICE = serviceName;
|
|
57
|
+
process.env.DD_ENV = environment;
|
|
58
|
+
{
|
|
59
|
+
process.env.DD_VERSION = version;
|
|
60
|
+
}
|
|
61
|
+
process.env.DD_AGENT_HOST = agentHost;
|
|
62
|
+
process.env.DD_TRACE_AGENT_PORT = agentPort;
|
|
63
|
+
const dbmPropagationMode = process.env.DD_DBM_PROPAGATION_MODE || "full";
|
|
64
|
+
process.env.DD_DBM_PROPAGATION_MODE = dbmPropagationMode;
|
|
65
|
+
try {
|
|
66
|
+
const ddTrace = __require("dd-trace");
|
|
67
|
+
tracer = ddTrace.init({
|
|
68
|
+
service: serviceName,
|
|
69
|
+
env: environment,
|
|
70
|
+
version,
|
|
71
|
+
logInjection: true,
|
|
72
|
+
runtimeMetrics: true,
|
|
73
|
+
appsec: false,
|
|
74
|
+
profiling: false,
|
|
75
|
+
startupLogs: true
|
|
76
|
+
// Enable for debugging
|
|
77
|
+
});
|
|
78
|
+
console.log(`[datadog] Tracer initialized: service=${serviceName}, env=${environment}, version=${version}, agent=${agentHost}:${agentPort}`);
|
|
79
|
+
tracer.use("dns", false);
|
|
80
|
+
tracer.use("net", false);
|
|
81
|
+
tracer.use("http", {
|
|
82
|
+
server: {
|
|
83
|
+
hooks: {
|
|
84
|
+
request: (span, req) => {
|
|
85
|
+
if (!span) return;
|
|
86
|
+
const url = req?.url || "";
|
|
87
|
+
const method = req?.method || "GET";
|
|
88
|
+
const path = url.split("?")[0];
|
|
89
|
+
if (path.startsWith("/_next/")) {
|
|
90
|
+
span.context()._trace.isRecording = false;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const routePattern = getRoutePattern(path);
|
|
94
|
+
span.setTag("resource.name", `${method} ${routePattern}`);
|
|
95
|
+
span.setTag("http.route", routePattern);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
} catch (err) {
|
|
101
|
+
console.error("[datadog] failed to initialize tracing", err);
|
|
102
|
+
tracer = null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
getRoutePattern = (path) => {
|
|
106
|
+
const routePatterns = [
|
|
107
|
+
// Update instance routes - normalize dynamic segments (capture suffix to preserve sub-routes)
|
|
108
|
+
{ pattern: /^\/update\/instance\/[^/]+(.*)$/, replacement: "/update/instance/[instanceId]$1" }
|
|
109
|
+
];
|
|
110
|
+
for (const { pattern, replacement } of routePatterns) {
|
|
111
|
+
if (pattern.test(path)) {
|
|
112
|
+
return path.replace(pattern, replacement);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return path;
|
|
116
|
+
};
|
|
117
|
+
tracer_default = tracer;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
10
120
|
|
|
11
121
|
// package.json
|
|
12
122
|
var package_default = {
|
|
13
|
-
version: "0.0.
|
|
123
|
+
version: "0.0.21"};
|
|
14
124
|
|
|
15
125
|
// src/tokens/index.ts
|
|
16
126
|
var baseTokens = {
|
|
@@ -126,6 +236,12 @@ var Button = forwardRef(
|
|
|
126
236
|
Button.displayName = "Button";
|
|
127
237
|
|
|
128
238
|
// src/utils/api-client.ts
|
|
239
|
+
var UnauthorizedError = class extends Error {
|
|
240
|
+
constructor(message = "Unauthorized") {
|
|
241
|
+
super(message);
|
|
242
|
+
this.name = "UnauthorizedError";
|
|
243
|
+
}
|
|
244
|
+
};
|
|
129
245
|
function isRedirectError(error) {
|
|
130
246
|
return typeof error === "object" && error !== null && "digest" in error && typeof error.digest === "string" && error.digest.startsWith("NEXT_REDIRECT");
|
|
131
247
|
}
|
|
@@ -151,8 +267,17 @@ async function handle401() {
|
|
|
151
267
|
const { redirect } = await import('next/navigation');
|
|
152
268
|
return redirect("/?expired=1");
|
|
153
269
|
}
|
|
270
|
+
function isErrorPage(url) {
|
|
271
|
+
try {
|
|
272
|
+
const urlObj = new URL(url);
|
|
273
|
+
return urlObj.pathname === "/error";
|
|
274
|
+
} catch {
|
|
275
|
+
return url === "/error" || url.startsWith("/error?");
|
|
276
|
+
}
|
|
277
|
+
}
|
|
154
278
|
async function handleServerError(statusCode) {
|
|
155
279
|
const { redirect } = await import('next/navigation');
|
|
280
|
+
const { cookies: cookies2 } = await import('next/headers');
|
|
156
281
|
let sourceUrl;
|
|
157
282
|
try {
|
|
158
283
|
const { headers } = await import('next/headers');
|
|
@@ -160,12 +285,20 @@ async function handleServerError(statusCode) {
|
|
|
160
285
|
const referer = headersList.get("referer");
|
|
161
286
|
const host = headersList.get("host");
|
|
162
287
|
const pathname = headersList.get("x-invoke-path") || headersList.get("x-forwarded-path");
|
|
163
|
-
if (referer) {
|
|
288
|
+
if (referer && !isErrorPage(referer)) {
|
|
164
289
|
sourceUrl = referer;
|
|
165
290
|
} else if (host && pathname) {
|
|
166
291
|
const protocol = headersList.get("x-forwarded-proto") || "https";
|
|
167
292
|
sourceUrl = `${protocol}://${host}${pathname}`;
|
|
168
293
|
}
|
|
294
|
+
if (!sourceUrl || isErrorPage(sourceUrl)) {
|
|
295
|
+
const cookieStore = await cookies2();
|
|
296
|
+
const preservedSource = cookieStore.get("portal_error_source");
|
|
297
|
+
if (preservedSource?.value) {
|
|
298
|
+
sourceUrl = decodeURIComponent(preservedSource.value);
|
|
299
|
+
cookieStore.delete("portal_error_source");
|
|
300
|
+
}
|
|
301
|
+
}
|
|
169
302
|
} catch (error) {
|
|
170
303
|
console.debug("[portal-components] Could not determine source URL", error);
|
|
171
304
|
}
|
|
@@ -176,6 +309,359 @@ async function handleServerError(statusCode) {
|
|
|
176
309
|
return redirect(`/error?${params.toString()}`);
|
|
177
310
|
}
|
|
178
311
|
|
|
312
|
+
// src/utils/observability/tracing.ts
|
|
313
|
+
var tracerCache = void 0;
|
|
314
|
+
function getTracer() {
|
|
315
|
+
if (tracerCache !== void 0) {
|
|
316
|
+
return tracerCache;
|
|
317
|
+
}
|
|
318
|
+
const rawFlag2 = String(process.env.USE_DATADOG_APM || "").toLowerCase();
|
|
319
|
+
const isEnabled2 = rawFlag2 === "true";
|
|
320
|
+
if (!isEnabled2) {
|
|
321
|
+
tracerCache = null;
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
try {
|
|
325
|
+
const tracerModule = (init_tracer(), __toCommonJS(tracer_exports));
|
|
326
|
+
const tracer2 = tracerModule.default || tracerModule;
|
|
327
|
+
if (tracer2 && typeof tracer2.trace === "function") {
|
|
328
|
+
tracerCache = tracer2;
|
|
329
|
+
return tracerCache;
|
|
330
|
+
}
|
|
331
|
+
} catch (err) {
|
|
332
|
+
console.warn("Failed to load tracer:", err);
|
|
333
|
+
}
|
|
334
|
+
tracerCache = null;
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
async function withTrace(name, fn) {
|
|
338
|
+
const activeTracer = getTracer();
|
|
339
|
+
if (!activeTracer) {
|
|
340
|
+
return fn(void 0);
|
|
341
|
+
}
|
|
342
|
+
return activeTracer.trace(name, async (span) => {
|
|
343
|
+
if (span) {
|
|
344
|
+
span.setTag("component", "application");
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
const result = await fn(span);
|
|
348
|
+
return result;
|
|
349
|
+
} catch (error) {
|
|
350
|
+
if (span) {
|
|
351
|
+
span.setTag("error", error);
|
|
352
|
+
}
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
function traceServerAction(name, fn) {
|
|
358
|
+
const spanName = name.startsWith("server.action.") ? name : `server.action.${name}`;
|
|
359
|
+
const traced = async (...args) => {
|
|
360
|
+
return withTrace(spanName, async (span) => {
|
|
361
|
+
if (span) {
|
|
362
|
+
span.setTag("component", "server-action");
|
|
363
|
+
}
|
|
364
|
+
const result = await fn(...args);
|
|
365
|
+
return result;
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
return traced;
|
|
369
|
+
}
|
|
370
|
+
var deriveInstallMethods = (licenseData) => {
|
|
371
|
+
const methods = [];
|
|
372
|
+
if (licenseData.isKotsInstallEnabled) {
|
|
373
|
+
methods.push("Replicated KOTS");
|
|
374
|
+
}
|
|
375
|
+
if (licenseData.isHelmInstallEnabled) {
|
|
376
|
+
methods.push("Helm");
|
|
377
|
+
}
|
|
378
|
+
if (licenseData.isHelmAirgapEnabled) {
|
|
379
|
+
methods.push("Helm Airgap");
|
|
380
|
+
}
|
|
381
|
+
if (licenseData.isEmbeddedClusterDownloadEnabled || licenseData.isEmbeddedClusterMultiNodeEnabled) {
|
|
382
|
+
methods.push("Embedded Cluster");
|
|
383
|
+
}
|
|
384
|
+
if (licenseData.isKurlInstallEnabled) {
|
|
385
|
+
methods.push("kURL");
|
|
386
|
+
}
|
|
387
|
+
if (licenseData.isGitopsSupported) {
|
|
388
|
+
methods.push("GitOps");
|
|
389
|
+
}
|
|
390
|
+
return Array.from(new Set(methods));
|
|
391
|
+
};
|
|
392
|
+
var convertEntitlementsToFields = (entitlementFields, entitlementValues) => {
|
|
393
|
+
const valuesMap = /* @__PURE__ */ new Map();
|
|
394
|
+
entitlementValues.forEach((ev) => {
|
|
395
|
+
valuesMap.set(ev.name, ev.value);
|
|
396
|
+
});
|
|
397
|
+
return entitlementFields.filter((field) => field.hidden === 0).map((field) => ({
|
|
398
|
+
key: field.name,
|
|
399
|
+
label: field.title || field.name,
|
|
400
|
+
value: valuesMap.get(field.name) || field.defaultVal || null,
|
|
401
|
+
isSecret: field.type === "Password"
|
|
402
|
+
}));
|
|
403
|
+
};
|
|
404
|
+
async function fetchLicenseCore() {
|
|
405
|
+
const sessionStore = await cookies();
|
|
406
|
+
const session = sessionStore.get("portal_session");
|
|
407
|
+
const token = session?.value;
|
|
408
|
+
if (!token) {
|
|
409
|
+
throw new Error("No session found - user must be authenticated");
|
|
410
|
+
}
|
|
411
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
412
|
+
if (process.env.NODE_ENV !== "production") {
|
|
413
|
+
console.debug("[portal-components] fetching license via %s (Enterprise Portal API)", endpoint);
|
|
414
|
+
}
|
|
415
|
+
const response = await authenticatedFetch(endpoint, {
|
|
416
|
+
method: "GET",
|
|
417
|
+
token,
|
|
418
|
+
headers: {
|
|
419
|
+
Accept: "application/json"
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
if (!response.ok) {
|
|
423
|
+
throw new Error(
|
|
424
|
+
`License request failed (${response.status} ${response.statusText})`
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
const envelope = await response.json();
|
|
428
|
+
const licenseData = envelope.data;
|
|
429
|
+
const license = {
|
|
430
|
+
...licenseData,
|
|
431
|
+
// Alias fields for backward compatibility
|
|
432
|
+
expiresAt: licenseData.expireAt,
|
|
433
|
+
environment: licenseData.licenseType,
|
|
434
|
+
// Extract channel names from channels array
|
|
435
|
+
releaseChannels: (licenseData.channels || []).map((ch) => ch.channelName),
|
|
436
|
+
// Derive install methods from feature flags
|
|
437
|
+
installMethods: deriveInstallMethods(licenseData),
|
|
438
|
+
// Convert entitlements to fields format
|
|
439
|
+
fields: convertEntitlementsToFields(licenseData.entitlementFields || [], licenseData.entitlementValues || [])
|
|
440
|
+
};
|
|
441
|
+
return license;
|
|
442
|
+
}
|
|
443
|
+
var fetchLicenseImpl = cache(fetchLicenseCore);
|
|
444
|
+
var fetchLicense = fetchLicenseImpl;
|
|
445
|
+
|
|
446
|
+
// src/utils/constants.ts
|
|
447
|
+
var DEFAULT_FAVICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='1.5'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cellipse cx='12' cy='12' rx='4' ry='10'/%3E%3Cpath d='M2 12h20'/%3E%3C/svg%3E";
|
|
448
|
+
var DEFAULT_PRIMARY_COLOR = "#4f46e5";
|
|
449
|
+
var DEFAULT_SECONDARY_COLOR = "#6366f1";
|
|
450
|
+
var isHttpApiOrigin = () => {
|
|
451
|
+
return process.env.REPLICATED_APP_ORIGIN?.startsWith("http://") || false;
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
// src/utils/branding.ts
|
|
455
|
+
var normalizeColor = (color) => {
|
|
456
|
+
if (!color || typeof color !== "string") {
|
|
457
|
+
return void 0;
|
|
458
|
+
}
|
|
459
|
+
const trimmed = color.trim();
|
|
460
|
+
if (/^#?[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/.test(trimmed)) {
|
|
461
|
+
return trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
|
|
462
|
+
}
|
|
463
|
+
console.debug("[portal-components] Invalid color format rejected (only hex supported):", trimmed);
|
|
464
|
+
return void 0;
|
|
465
|
+
};
|
|
466
|
+
var sanitizeUrlForCss = (url) => {
|
|
467
|
+
if (!url || typeof url !== "string") {
|
|
468
|
+
return void 0;
|
|
469
|
+
}
|
|
470
|
+
const trimmed = url.trim();
|
|
471
|
+
try {
|
|
472
|
+
const urlObj = new URL(trimmed);
|
|
473
|
+
if (!["http:", "https:", "data:"].includes(urlObj.protocol)) {
|
|
474
|
+
console.debug("[portal-components] Invalid URL protocol for background image:", urlObj.protocol);
|
|
475
|
+
return void 0;
|
|
476
|
+
}
|
|
477
|
+
} catch {
|
|
478
|
+
console.debug("[portal-components] Invalid URL format for background image:", trimmed);
|
|
479
|
+
return void 0;
|
|
480
|
+
}
|
|
481
|
+
const escaped = trimmed.replace(/\\/g, "\\\\").replace(/\)/g, "\\)").replace(/"/g, '\\"').replace(/'/g, "\\'").replace(/[\x00-\x1F\x7F]/g, "");
|
|
482
|
+
return escaped;
|
|
483
|
+
};
|
|
484
|
+
var decodeBranding = ({ brandingData }) => {
|
|
485
|
+
if (!brandingData || typeof brandingData !== "string") {
|
|
486
|
+
return {
|
|
487
|
+
primaryColor: DEFAULT_PRIMARY_COLOR,
|
|
488
|
+
secondaryColor: DEFAULT_SECONDARY_COLOR
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
try {
|
|
492
|
+
const decoded = Buffer.from(brandingData, "base64").toString("utf-8");
|
|
493
|
+
const parsed = JSON.parse(decoded);
|
|
494
|
+
const logo = typeof parsed.logo === "string" ? parsed.logo : void 0;
|
|
495
|
+
const titleRaw = typeof parsed.title === "string" ? parsed.title.trim() : "";
|
|
496
|
+
const title = titleRaw ? titleRaw : void 0;
|
|
497
|
+
const favicon = typeof parsed.favicon === "string" ? parsed.favicon : void 0;
|
|
498
|
+
const primaryColorRaw = parsed.primaryColor ?? parsed.primary_color;
|
|
499
|
+
const secondaryColorRaw = parsed.secondaryColor ?? parsed.secondary_color;
|
|
500
|
+
const primaryColor = normalizeColor(primaryColorRaw);
|
|
501
|
+
const secondaryColor = normalizeColor(secondaryColorRaw);
|
|
502
|
+
const supportPortalLink = typeof parsed.supportPortalLink === "string" ? parsed.supportPortalLink : void 0;
|
|
503
|
+
const backgroundRaw = parsed.background;
|
|
504
|
+
const background = backgroundRaw === "minimal" || backgroundRaw === "custom" || backgroundRaw === "image" ? backgroundRaw : void 0;
|
|
505
|
+
const backgroundImage = sanitizeUrlForCss(parsed.backgroundImage);
|
|
506
|
+
const backgroundGradientStart = normalizeColor(parsed.customColor1);
|
|
507
|
+
const backgroundGradientEnd = normalizeColor(parsed.customColor2);
|
|
508
|
+
return {
|
|
509
|
+
logo,
|
|
510
|
+
title,
|
|
511
|
+
favicon,
|
|
512
|
+
primaryColor: primaryColor || DEFAULT_PRIMARY_COLOR,
|
|
513
|
+
secondaryColor: secondaryColor || DEFAULT_SECONDARY_COLOR,
|
|
514
|
+
supportPortalLink,
|
|
515
|
+
background,
|
|
516
|
+
backgroundImage,
|
|
517
|
+
backgroundGradientStart,
|
|
518
|
+
backgroundGradientEnd
|
|
519
|
+
};
|
|
520
|
+
} catch (error) {
|
|
521
|
+
console.debug("[portal-components] unable to parse branding JSON", error);
|
|
522
|
+
return {
|
|
523
|
+
primaryColor: DEFAULT_PRIMARY_COLOR,
|
|
524
|
+
secondaryColor: DEFAULT_SECONDARY_COLOR
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
// src/utils/session.ts
|
|
530
|
+
async function validateSession(token) {
|
|
531
|
+
if (!token || typeof token !== "string" || !token.trim()) {
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
try {
|
|
535
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/user`;
|
|
536
|
+
const response = await fetch(endpoint, {
|
|
537
|
+
method: "GET",
|
|
538
|
+
headers: {
|
|
539
|
+
authorization: `Bearer ${token}`
|
|
540
|
+
},
|
|
541
|
+
// Short timeout for validation
|
|
542
|
+
signal: AbortSignal.timeout(5e3)
|
|
543
|
+
});
|
|
544
|
+
if (response.status === 401) {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
return response.ok;
|
|
548
|
+
} catch (error) {
|
|
549
|
+
console.warn("[portal-components] session validation error:", error);
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async function deleteSessionCookie() {
|
|
554
|
+
const { cookies: cookies2 } = await import('next/headers');
|
|
555
|
+
const cookieStore = await cookies2();
|
|
556
|
+
cookieStore.delete("portal_session");
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/utils/format.ts
|
|
560
|
+
function formatBytes(bytes, decimals = 1) {
|
|
561
|
+
if (bytes === 0) return "0 Bytes";
|
|
562
|
+
const k = 1024;
|
|
563
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
564
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
565
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
566
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
567
|
+
}
|
|
568
|
+
function formatDateShort(dateString) {
|
|
569
|
+
if (!dateString) return "Never";
|
|
570
|
+
const date = new Date(dateString);
|
|
571
|
+
if (isNaN(date.getTime())) {
|
|
572
|
+
return dateString;
|
|
573
|
+
}
|
|
574
|
+
return date.toLocaleDateString("en-US", {
|
|
575
|
+
year: "numeric",
|
|
576
|
+
month: "2-digit",
|
|
577
|
+
day: "2-digit"
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
function formatDate(dateString) {
|
|
581
|
+
if (!dateString) return "Never";
|
|
582
|
+
const date = new Date(dateString);
|
|
583
|
+
if (isNaN(date.getTime())) {
|
|
584
|
+
return dateString;
|
|
585
|
+
}
|
|
586
|
+
return date.toLocaleDateString("en-US", {
|
|
587
|
+
month: "short",
|
|
588
|
+
day: "numeric",
|
|
589
|
+
year: "numeric",
|
|
590
|
+
hour: "numeric",
|
|
591
|
+
minute: "2-digit",
|
|
592
|
+
hour12: true
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
function formatDateTime(dateString) {
|
|
596
|
+
const date = new Date(dateString);
|
|
597
|
+
if (isNaN(date.getTime())) {
|
|
598
|
+
return dateString;
|
|
599
|
+
}
|
|
600
|
+
return date.toLocaleString("en-US", {
|
|
601
|
+
timeZone: "UTC",
|
|
602
|
+
year: "numeric",
|
|
603
|
+
month: "2-digit",
|
|
604
|
+
day: "2-digit",
|
|
605
|
+
hour: "2-digit",
|
|
606
|
+
minute: "2-digit",
|
|
607
|
+
second: "2-digit",
|
|
608
|
+
hour12: false
|
|
609
|
+
}) + " UTC";
|
|
610
|
+
}
|
|
611
|
+
function formatDateTimeLocal(dateString) {
|
|
612
|
+
if (!dateString) return "N/A";
|
|
613
|
+
try {
|
|
614
|
+
const date = new Date(dateString);
|
|
615
|
+
if (isNaN(date.getTime())) {
|
|
616
|
+
return dateString;
|
|
617
|
+
}
|
|
618
|
+
return date.toLocaleDateString("en-US", {
|
|
619
|
+
month: "numeric",
|
|
620
|
+
day: "numeric",
|
|
621
|
+
year: "numeric",
|
|
622
|
+
hour: "numeric",
|
|
623
|
+
minute: "2-digit",
|
|
624
|
+
hour12: true
|
|
625
|
+
});
|
|
626
|
+
} catch {
|
|
627
|
+
return "N/A";
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// src/utils/release-helpers.ts
|
|
632
|
+
function convertToReleaseEntry(release, channelName, options) {
|
|
633
|
+
const sections = [];
|
|
634
|
+
if (release.release_notes && release.release_notes.trim().length > 0) {
|
|
635
|
+
if (options.releaseNotesMode === "markdown") {
|
|
636
|
+
sections.push({
|
|
637
|
+
title: "Release Notes",
|
|
638
|
+
description: release.release_notes
|
|
639
|
+
});
|
|
640
|
+
} else {
|
|
641
|
+
const releaseNotesItems = release.release_notes.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
642
|
+
sections.push({
|
|
643
|
+
title: "Release Notes",
|
|
644
|
+
description: releaseNotesItems.length === 0 ? release.release_notes : void 0,
|
|
645
|
+
items: releaseNotesItems.length > 0 ? releaseNotesItems : void 0
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
const charts = release.helm_charts ? release.helm_charts.filter((chart) => !chart.is_kots_installer_only).map((chart) => `${chart.name} v${chart.version}`) : [];
|
|
650
|
+
if (charts.length > 0) {
|
|
651
|
+
sections.push({
|
|
652
|
+
title: "Helm Charts",
|
|
653
|
+
items: charts,
|
|
654
|
+
description: "Latest chart versions included in this release."
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
return {
|
|
658
|
+
version: release.label || `Release ${release.release_sequence}`,
|
|
659
|
+
channel: channelName || `Channel ${release.channel_sequence}`,
|
|
660
|
+
releasedAt: release.release_date,
|
|
661
|
+
sections
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
|
|
179
665
|
// src/actions/index.ts
|
|
180
666
|
var getApiOrigin = () => {
|
|
181
667
|
return (process.env.REPLICATED_APP_ORIGIN || "https://replicated.app").replace(/\/+$/, "");
|
|
@@ -315,11 +801,15 @@ var fetchCustomBrandingImpl = async () => {
|
|
|
315
801
|
const payload = await response.json();
|
|
316
802
|
const brandingObject = {
|
|
317
803
|
logo: payload.logoUrl,
|
|
318
|
-
title: payload.
|
|
319
|
-
|
|
320
|
-
|
|
804
|
+
title: payload.title,
|
|
805
|
+
primaryColor: payload.primaryColor,
|
|
806
|
+
secondaryColor: payload.secondaryColor,
|
|
321
807
|
favicon: payload.faviconUrl,
|
|
322
|
-
supportPortalLink: payload.supportPortalLink || ""
|
|
808
|
+
supportPortalLink: payload.supportPortalLink || "",
|
|
809
|
+
background: payload.background,
|
|
810
|
+
backgroundImage: payload.backgroundImage,
|
|
811
|
+
customColor1: payload.customColor1,
|
|
812
|
+
customColor2: payload.customColor2
|
|
323
813
|
};
|
|
324
814
|
const brandingData = Buffer.from(JSON.stringify(brandingObject)).toString("base64");
|
|
325
815
|
return {
|
|
@@ -582,353 +1072,38 @@ var uploadSupportBundle = defineServerAction({
|
|
|
582
1072
|
var getSupportBundleUploadUrl = (appId) => {
|
|
583
1073
|
return `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;
|
|
584
1074
|
};
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
console.debug("[portal-components] fetching releases via %s (Enterprise Portal API)", endpoint);
|
|
597
|
-
}
|
|
598
|
-
const response = await authenticatedFetch(endpoint, {
|
|
599
|
-
method: "GET",
|
|
600
|
-
token,
|
|
601
|
-
headers: {
|
|
602
|
-
accept: "application/json"
|
|
603
|
-
},
|
|
604
|
-
signal: context?.signal
|
|
605
|
-
});
|
|
606
|
-
const bodyText = await response.text().catch((error) => {
|
|
607
|
-
console.warn("[portal-components] listReleases read error", error);
|
|
608
|
-
return null;
|
|
609
|
-
});
|
|
610
|
-
if (!response.ok) {
|
|
611
|
-
throw new Error(
|
|
612
|
-
`List releases request failed (${response.status} ${response.statusText})`
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
return {
|
|
616
|
-
status: response.status,
|
|
617
|
-
body: bodyText
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
var asRecord = (value) => {
|
|
622
|
-
if (value && typeof value === "object") {
|
|
623
|
-
return value;
|
|
624
|
-
}
|
|
625
|
-
return void 0;
|
|
626
|
-
};
|
|
627
|
-
var getValue = (record, key) => record ? record[key] : void 0;
|
|
628
|
-
var getString = (record, key) => {
|
|
629
|
-
const value = getValue(record, key);
|
|
630
|
-
return typeof value === "string" ? value : void 0;
|
|
631
|
-
};
|
|
632
|
-
var getBoolean = (record, key) => {
|
|
633
|
-
const value = getValue(record, key);
|
|
634
|
-
if (typeof value === "boolean") {
|
|
635
|
-
return value;
|
|
636
|
-
}
|
|
637
|
-
if (typeof value === "number") {
|
|
638
|
-
return value === 1;
|
|
639
|
-
}
|
|
640
|
-
if (typeof value === "string") {
|
|
641
|
-
const normalized = value.trim().toLowerCase();
|
|
642
|
-
if (["true", "1", "yes"].includes(normalized)) {
|
|
643
|
-
return true;
|
|
644
|
-
}
|
|
645
|
-
if (["false", "0", "no"].includes(normalized)) {
|
|
646
|
-
return false;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return void 0;
|
|
650
|
-
};
|
|
651
|
-
var toDisplayValue = (value) => {
|
|
652
|
-
if (value === null || value === void 0) {
|
|
653
|
-
return null;
|
|
654
|
-
}
|
|
655
|
-
if (typeof value === "string") {
|
|
656
|
-
return value;
|
|
657
|
-
}
|
|
658
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
659
|
-
return String(value);
|
|
660
|
-
}
|
|
661
|
-
try {
|
|
662
|
-
return JSON.stringify(value);
|
|
663
|
-
} catch {
|
|
664
|
-
return String(value);
|
|
665
|
-
}
|
|
666
|
-
};
|
|
667
|
-
var normalizeStringArray = (value) => {
|
|
668
|
-
if (Array.isArray(value)) {
|
|
669
|
-
const normalized = value.map(
|
|
670
|
-
(item) => typeof item === "string" ? item.trim() : ""
|
|
671
|
-
).filter((item) => item.length > 0);
|
|
672
|
-
return normalized.length ? normalized : void 0;
|
|
673
|
-
}
|
|
674
|
-
if (typeof value === "string") {
|
|
675
|
-
const normalized = value.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
|
|
676
|
-
return normalized.length ? normalized : void 0;
|
|
677
|
-
}
|
|
678
|
-
return void 0;
|
|
679
|
-
};
|
|
680
|
-
var normalizeLicenseFields = (input) => {
|
|
681
|
-
if (!input) {
|
|
682
|
-
return [];
|
|
683
|
-
}
|
|
684
|
-
if (Array.isArray(input)) {
|
|
685
|
-
return input.map((field, index) => {
|
|
686
|
-
if (!field || typeof field !== "object") {
|
|
687
|
-
return null;
|
|
688
|
-
}
|
|
689
|
-
const candidate = field;
|
|
690
|
-
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}`;
|
|
691
|
-
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;
|
|
692
|
-
let value = candidate.value ?? candidate.data ?? candidate.content;
|
|
693
|
-
if ((value === void 0 || value === null) && typeof candidate.text === "string") {
|
|
694
|
-
value = candidate.text;
|
|
695
|
-
}
|
|
696
|
-
if ((value === void 0 || value === null) && typeof candidate.defaultValue === "string") {
|
|
697
|
-
value = candidate.defaultValue;
|
|
698
|
-
}
|
|
699
|
-
const isSecret = Boolean(
|
|
700
|
-
candidate.isSecret ?? candidate.secret ?? candidate.masked
|
|
701
|
-
);
|
|
702
|
-
const resolved = toDisplayValue(value);
|
|
703
|
-
return {
|
|
704
|
-
key,
|
|
705
|
-
label,
|
|
706
|
-
value: resolved,
|
|
707
|
-
isSecret
|
|
708
|
-
};
|
|
709
|
-
}).filter((field) => Boolean(field));
|
|
710
|
-
}
|
|
711
|
-
if (typeof input === "object") {
|
|
712
|
-
return Object.entries(input).map(
|
|
713
|
-
([key, value]) => {
|
|
714
|
-
let resolvedValue = value;
|
|
715
|
-
let isSecret = false;
|
|
716
|
-
if (value && typeof value === "object") {
|
|
717
|
-
const obj = value;
|
|
718
|
-
if ("value" in obj) {
|
|
719
|
-
resolvedValue = obj.value;
|
|
720
|
-
}
|
|
721
|
-
isSecret = Boolean(obj.isSecret ?? obj.secret ?? obj.masked);
|
|
722
|
-
}
|
|
723
|
-
const normalized = toDisplayValue(resolvedValue);
|
|
724
|
-
return {
|
|
725
|
-
key,
|
|
726
|
-
label: key,
|
|
727
|
-
value: normalized,
|
|
728
|
-
isSecret
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
);
|
|
732
|
-
}
|
|
733
|
-
return [];
|
|
734
|
-
};
|
|
735
|
-
var extractChannelNames = (input) => {
|
|
736
|
-
if (!Array.isArray(input)) {
|
|
737
|
-
return void 0;
|
|
1075
|
+
async function listReleasesImpl() {
|
|
1076
|
+
const { cookies: cookies2 } = await import('next/headers');
|
|
1077
|
+
const sessionStore = await cookies2();
|
|
1078
|
+
const session = sessionStore.get("portal_session");
|
|
1079
|
+
const token = session?.value;
|
|
1080
|
+
if (!token) {
|
|
1081
|
+
throw new Error("List releases requires a session token");
|
|
1082
|
+
}
|
|
1083
|
+
const endpoint = `${getApiOrigin()}/enterprise-portal/releases`;
|
|
1084
|
+
if (process.env.NODE_ENV !== "production") {
|
|
1085
|
+
console.debug("[portal-components] fetching releases via %s (Enterprise Portal API)", endpoint);
|
|
738
1086
|
}
|
|
739
|
-
const
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
if (!record) {
|
|
745
|
-
return null;
|
|
746
|
-
}
|
|
747
|
-
return getString(record, "name") ?? getString(record, "channelName") ?? getString(record, "channel") ?? getString(record, "channelSlug") ?? getString(record, "slug") ?? void 0;
|
|
748
|
-
}).filter((name) => Boolean(name && name.length));
|
|
749
|
-
return names.length ? names : void 0;
|
|
750
|
-
};
|
|
751
|
-
var normalizeEntitlementFields = (fieldsInput, valuesInput) => {
|
|
752
|
-
const valuesMap = /* @__PURE__ */ new Map();
|
|
753
|
-
const assignValue = (key, value) => {
|
|
754
|
-
if (!key) {
|
|
755
|
-
return;
|
|
1087
|
+
const response = await authenticatedFetch(endpoint, {
|
|
1088
|
+
method: "GET",
|
|
1089
|
+
token,
|
|
1090
|
+
headers: {
|
|
1091
|
+
accept: "application/json"
|
|
756
1092
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
const record = asRecord(item);
|
|
762
|
-
if (!record) {
|
|
763
|
-
if (typeof item === "string") {
|
|
764
|
-
assignValue(item, item);
|
|
765
|
-
}
|
|
766
|
-
return;
|
|
767
|
-
}
|
|
768
|
-
const key = getString(record, "name") ?? getString(record, "field") ?? getString(record, "title") ?? getString(record, "label") ?? getString(record, "slug") ?? (() => {
|
|
769
|
-
const idValue = getValue(record, "id");
|
|
770
|
-
if (typeof idValue === "string" || typeof idValue === "number") {
|
|
771
|
-
return String(idValue);
|
|
772
|
-
}
|
|
773
|
-
return void 0;
|
|
774
|
-
})();
|
|
775
|
-
const value = getValue(record, "value") ?? getValue(record, "currentValue") ?? getValue(record, "entitlementValue") ?? getValue(record, "content") ?? getValue(record, "data") ?? getValue(record, "defaultVal") ?? getValue(record, "defaultValue");
|
|
776
|
-
assignValue(key, value);
|
|
777
|
-
});
|
|
778
|
-
} else if (valuesInput && typeof valuesInput === "object") {
|
|
779
|
-
Object.entries(valuesInput).forEach(
|
|
780
|
-
([key, value]) => assignValue(key, value)
|
|
1093
|
+
});
|
|
1094
|
+
if (!response.ok) {
|
|
1095
|
+
throw new Error(
|
|
1096
|
+
`List releases request failed (${response.status} ${response.statusText})`
|
|
781
1097
|
);
|
|
782
1098
|
}
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
return;
|
|
789
|
-
}
|
|
790
|
-
const baseKey = getString(record, "name") ?? getString(record, "field") ?? getString(record, "slug") ?? `entitlement-${index}`;
|
|
791
|
-
const key = `entitlement-${baseKey}`;
|
|
792
|
-
const label = getString(record, "title") ?? getString(record, "label") ?? baseKey;
|
|
793
|
-
const defaultValue = getString(record, "defaultVal") ?? getString(record, "default") ?? getString(record, "defaultValue");
|
|
794
|
-
const value = valuesMap.get(baseKey) ?? valuesMap.get(label) ?? defaultValue ?? null;
|
|
795
|
-
const isSecret = Boolean(
|
|
796
|
-
getBoolean(record, "secret") ?? getBoolean(record, "isSecret") ?? getBoolean(record, "masked")
|
|
797
|
-
);
|
|
798
|
-
normalized.push({
|
|
799
|
-
key,
|
|
800
|
-
label,
|
|
801
|
-
value,
|
|
802
|
-
isSecret
|
|
803
|
-
});
|
|
804
|
-
});
|
|
805
|
-
}
|
|
806
|
-
valuesMap.forEach((value, key) => {
|
|
807
|
-
const normalizedKey = `entitlement-${key}`;
|
|
808
|
-
if (!normalized.some((field) => field.key === normalizedKey)) {
|
|
809
|
-
normalized.push({
|
|
810
|
-
key: normalizedKey,
|
|
811
|
-
label: key,
|
|
812
|
-
value
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
|
-
});
|
|
816
|
-
return normalized;
|
|
817
|
-
};
|
|
818
|
-
var normalizeLicensePayload = (payload) => {
|
|
819
|
-
const payloadRecord = asRecord(payload);
|
|
820
|
-
const rootRecord = asRecord(getValue(payloadRecord, "license")) ?? asRecord(getValue(payloadRecord, "data")) ?? payloadRecord ?? {};
|
|
821
|
-
const sourceRecord = asRecord(getValue(rootRecord, "metadata")) ?? rootRecord;
|
|
822
|
-
const customer = asRecord(getValue(rootRecord, "customer")) ?? asRecord(getValue(sourceRecord, "customer")) ?? asRecord(getValue(payloadRecord, "customer")) ?? {};
|
|
823
|
-
let releaseChannels = normalizeStringArray(
|
|
824
|
-
getValue(rootRecord, "releaseChannels") ?? getValue(sourceRecord, "releaseChannels") ?? getValue(sourceRecord, "channels") ?? getValue(rootRecord, "channels") ?? getValue(sourceRecord, "channel") ?? getValue(rootRecord, "channel")
|
|
825
|
-
) ?? void 0;
|
|
826
|
-
if (!releaseChannels) {
|
|
827
|
-
releaseChannels = extractChannelNames(getValue(rootRecord, "channels")) ?? extractChannelNames(getValue(sourceRecord, "channels")) ?? void 0;
|
|
828
|
-
}
|
|
829
|
-
let installMethods = normalizeStringArray(
|
|
830
|
-
getValue(rootRecord, "installMethods") ?? getValue(sourceRecord, "installMethods") ?? getValue(sourceRecord, "install_options") ?? getValue(rootRecord, "install_options") ?? getValue(sourceRecord, "installOptions")
|
|
831
|
-
) ?? void 0;
|
|
832
|
-
if (!installMethods || installMethods.length === 0) {
|
|
833
|
-
const resolved = [];
|
|
834
|
-
const flag = (key) => getBoolean(rootRecord, key) ?? getBoolean(sourceRecord, key) ?? false;
|
|
835
|
-
if (flag("isKotsInstallEnabled")) {
|
|
836
|
-
resolved.push("Replicated KOTS");
|
|
837
|
-
}
|
|
838
|
-
if (flag("isHelmInstallEnabled")) {
|
|
839
|
-
resolved.push("Helm");
|
|
840
|
-
}
|
|
841
|
-
if (flag("isHelmAirgapEnabled")) {
|
|
842
|
-
resolved.push("Helm Airgap");
|
|
843
|
-
}
|
|
844
|
-
if (flag("isEmbeddedClusterDownloadEnabled") || flag("isEmbeddedClusterMultiNodeEnabled")) {
|
|
845
|
-
resolved.push("Embedded Cluster");
|
|
846
|
-
}
|
|
847
|
-
if (flag("isKurlInstallEnabled")) {
|
|
848
|
-
resolved.push("kURL");
|
|
849
|
-
}
|
|
850
|
-
if (flag("isGitopsSupported")) {
|
|
851
|
-
resolved.push("GitOps");
|
|
852
|
-
}
|
|
853
|
-
if (resolved.length) {
|
|
854
|
-
installMethods = Array.from(new Set(resolved));
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
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");
|
|
858
|
-
const expiresAt = typeof expiresAtSource === "string" && expiresAtSource.trim().length ? expiresAtSource : expiresAtSource === null ? null : void 0;
|
|
859
|
-
const baseFields = normalizeLicenseFields(
|
|
860
|
-
getValue(rootRecord, "additionalFields") ?? getValue(sourceRecord, "additionalFields") ?? getValue(sourceRecord, "fields") ?? getValue(rootRecord, "fields") ?? getValue(payloadRecord, "fields") ?? getValue(payloadRecord, "additional_fields")
|
|
861
|
-
);
|
|
862
|
-
const entitlementFields = normalizeEntitlementFields(
|
|
863
|
-
getValue(rootRecord, "entitlementFields") ?? getValue(sourceRecord, "entitlementFields"),
|
|
864
|
-
getValue(rootRecord, "entitlementValues") ?? getValue(sourceRecord, "entitlementValues")
|
|
865
|
-
);
|
|
866
|
-
const fields = [
|
|
867
|
-
...baseFields,
|
|
868
|
-
...entitlementFields.filter(
|
|
869
|
-
(field) => !baseFields.some((existing) => existing.key === field.key)
|
|
870
|
-
)
|
|
871
|
-
];
|
|
872
|
-
const statusFromSource = getString(sourceRecord, "status") ?? getString(sourceRecord, "state");
|
|
873
|
-
const statusLabelFromSource = getString(sourceRecord, "statusLabel") ?? getString(sourceRecord, "stateLabel");
|
|
874
|
-
const expiredFlag = getBoolean(sourceRecord, "isExpired") ?? getBoolean(rootRecord, "isExpired");
|
|
875
|
-
const derivedStatus = statusFromSource ?? (typeof expiredFlag === "boolean" ? expiredFlag ? "expired" : "active" : void 0);
|
|
876
|
-
const statusLabel = statusLabelFromSource ?? (derivedStatus ? derivedStatus.charAt(0).toUpperCase() + derivedStatus.slice(1) : void 0);
|
|
877
|
-
const licenseType = getString(sourceRecord, "licenseType") ?? getString(rootRecord, "licenseType");
|
|
878
|
-
const status = derivedStatus;
|
|
879
|
-
const license = {
|
|
880
|
-
id: getString(rootRecord, "id") ?? getString(sourceRecord, "id") ?? getString(sourceRecord, "licenseId") ?? getString(customer, "licenseId") ?? void 0,
|
|
881
|
-
status,
|
|
882
|
-
statusLabel,
|
|
883
|
-
environment: getString(sourceRecord, "environment") ?? getString(sourceRecord, "tier") ?? licenseType ?? void 0,
|
|
884
|
-
expiresAt: expiresAt ?? null,
|
|
885
|
-
releaseChannels: releaseChannels ?? [
|
|
886
|
-
getString(rootRecord, "channelName") ?? getString(rootRecord, "channel") ?? void 0
|
|
887
|
-
].filter((value) => Boolean(value)),
|
|
888
|
-
installMethods,
|
|
889
|
-
installNotes: getString(sourceRecord, "installNotes"),
|
|
890
|
-
customerName: getString(sourceRecord, "customerName") ?? getString(customer, "name") ?? void 0,
|
|
891
|
-
customerId: getString(sourceRecord, "customerId") ?? getString(customer, "id") ?? getString(rootRecord, "customerId") ?? void 0,
|
|
892
|
-
customerOrganization: getString(customer, "organization") ?? getString(sourceRecord, "customerOrganization") ?? getString(rootRecord, "customerOrganization") ?? void 0,
|
|
893
|
-
fields
|
|
1099
|
+
const envelope = await response.json();
|
|
1100
|
+
const data = envelope.data;
|
|
1101
|
+
return {
|
|
1102
|
+
releases: Array.isArray(data?.releases) ? data.releases : [],
|
|
1103
|
+
totalCount: data?.totalCount || 0
|
|
894
1104
|
};
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
var fetchLicenseDetails = defineServerAction({
|
|
898
|
-
id: "license/fetch-details",
|
|
899
|
-
description: "Fetches the authenticated user's enterprise license details.",
|
|
900
|
-
visibility: "customer",
|
|
901
|
-
tags: ["license", "entitlements"],
|
|
902
|
-
async run({ token }, context) {
|
|
903
|
-
if (typeof token !== "string" || token.trim().length === 0) {
|
|
904
|
-
throw new Error("fetchLicenseDetails requires a non-empty token");
|
|
905
|
-
}
|
|
906
|
-
const endpoint = `${getApiOrigin()}/enterprise-portal/license`;
|
|
907
|
-
if (process.env.NODE_ENV !== "production") {
|
|
908
|
-
console.debug("[portal-components] fetching license via %s (Enterprise Portal API)", endpoint);
|
|
909
|
-
}
|
|
910
|
-
const response = await authenticatedFetch(endpoint, {
|
|
911
|
-
method: "GET",
|
|
912
|
-
token,
|
|
913
|
-
headers: {
|
|
914
|
-
accept: "application/json"
|
|
915
|
-
},
|
|
916
|
-
signal: context?.signal
|
|
917
|
-
});
|
|
918
|
-
if (!response.ok) {
|
|
919
|
-
throw new Error(
|
|
920
|
-
`License request failed (${response.status} ${response.statusText})`
|
|
921
|
-
);
|
|
922
|
-
}
|
|
923
|
-
const payload = await response.json();
|
|
924
|
-
const licenseData = payload.data;
|
|
925
|
-
const license = normalizeLicensePayload(licenseData);
|
|
926
|
-
return {
|
|
927
|
-
license,
|
|
928
|
-
raw: licenseData ?? null
|
|
929
|
-
};
|
|
930
|
-
}
|
|
931
|
-
});
|
|
1105
|
+
}
|
|
1106
|
+
var listReleases = traceServerAction("listReleases", listReleasesImpl);
|
|
932
1107
|
var getSecurityInfo = defineServerAction({
|
|
933
1108
|
id: "security/get-info",
|
|
934
1109
|
description: "Fetches CVE security scan results for a specific release",
|
|
@@ -1407,12 +1582,12 @@ var InfoRow = ({
|
|
|
1407
1582
|
icon,
|
|
1408
1583
|
title,
|
|
1409
1584
|
children
|
|
1410
|
-
}) => /* @__PURE__ */ jsxs("div", {
|
|
1411
|
-
/* @__PURE__ */
|
|
1412
|
-
|
|
1413
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium text-gray-900", children: title })
|
|
1414
|
-
|
|
1415
|
-
|
|
1585
|
+
}) => /* @__PURE__ */ jsxs("div", { children: [
|
|
1586
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
1587
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-4 w-4 flex-shrink-0 items-center justify-center text-gray-900", children: icon }),
|
|
1588
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium leading-4 text-gray-900", children: title })
|
|
1589
|
+
] }),
|
|
1590
|
+
/* @__PURE__ */ jsx("div", { className: "pl-6", children })
|
|
1416
1591
|
] });
|
|
1417
1592
|
var renderInstallOrChannel = (values) => {
|
|
1418
1593
|
if (!values || values.length === 0) {
|
|
@@ -1427,12 +1602,12 @@ var buildPrimaryRows = (license) => {
|
|
|
1427
1602
|
node: /* @__PURE__ */ jsxs(
|
|
1428
1603
|
InfoRow,
|
|
1429
1604
|
{
|
|
1430
|
-
icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-
|
|
1605
|
+
icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-4 w-4" }),
|
|
1431
1606
|
title: "License Status",
|
|
1432
1607
|
children: [
|
|
1433
1608
|
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex items-center text-sm text-gray-600", children: [
|
|
1434
1609
|
/* @__PURE__ */ jsx(CheckIcon, { className: "mr-1.5 h-4 w-4 text-green-500" }),
|
|
1435
|
-
/* @__PURE__ */ jsx("span", { children: license.
|
|
1610
|
+
/* @__PURE__ */ jsx("span", { children: license.isExpired ? "Expired" : "Active" })
|
|
1436
1611
|
] }),
|
|
1437
1612
|
license.environment ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: license.environment }) : null
|
|
1438
1613
|
]
|
|
@@ -1444,7 +1619,7 @@ var buildPrimaryRows = (license) => {
|
|
|
1444
1619
|
node: /* @__PURE__ */ jsx(
|
|
1445
1620
|
InfoRow,
|
|
1446
1621
|
{
|
|
1447
|
-
icon: /* @__PURE__ */ jsx(CalendarIcon, { className: "h-
|
|
1622
|
+
icon: /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4" }),
|
|
1448
1623
|
title: "Expiration Date",
|
|
1449
1624
|
children: /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: formatExpiration(license.expiresAt) })
|
|
1450
1625
|
}
|
|
@@ -1455,7 +1630,7 @@ var buildPrimaryRows = (license) => {
|
|
|
1455
1630
|
node: /* @__PURE__ */ jsx(
|
|
1456
1631
|
InfoRow,
|
|
1457
1632
|
{
|
|
1458
|
-
icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-
|
|
1633
|
+
icon: /* @__PURE__ */ jsx(ShieldIcon, { className: "h-4 w-4" }),
|
|
1459
1634
|
title: "Release Channel(s)",
|
|
1460
1635
|
children: renderInstallOrChannel(license.releaseChannels)
|
|
1461
1636
|
}
|
|
@@ -1466,7 +1641,7 @@ var buildPrimaryRows = (license) => {
|
|
|
1466
1641
|
node: /* @__PURE__ */ jsx(
|
|
1467
1642
|
InfoRow,
|
|
1468
1643
|
{
|
|
1469
|
-
icon: /* @__PURE__ */ jsx(DownloadIcon, { className: "h-
|
|
1644
|
+
icon: /* @__PURE__ */ jsx(DownloadIcon, { className: "h-4 w-4" }),
|
|
1470
1645
|
title: "Install Options",
|
|
1471
1646
|
children: renderInstallOrChannel(license.installMethods)
|
|
1472
1647
|
}
|
|
@@ -1477,7 +1652,7 @@ var buildPrimaryRows = (license) => {
|
|
|
1477
1652
|
node: /* @__PURE__ */ jsxs(
|
|
1478
1653
|
InfoRow,
|
|
1479
1654
|
{
|
|
1480
|
-
icon: /* @__PURE__ */ jsx(BuildingIcon, { className: "h-
|
|
1655
|
+
icon: /* @__PURE__ */ jsx(BuildingIcon, { className: "h-4 w-4" }),
|
|
1481
1656
|
title: "Customer Name",
|
|
1482
1657
|
children: [
|
|
1483
1658
|
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: license.customerName ?? "Unknown customer" }),
|
|
@@ -1495,7 +1670,7 @@ var renderFields = (fields) => {
|
|
|
1495
1670
|
if (!fields.length) {
|
|
1496
1671
|
return /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No additional fields available." });
|
|
1497
1672
|
}
|
|
1498
|
-
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2
|
|
1673
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3", children: fields.map((field) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
1499
1674
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900", children: field.label }),
|
|
1500
1675
|
/* @__PURE__ */ jsx(
|
|
1501
1676
|
"p",
|
|
@@ -1516,9 +1691,7 @@ var LicenseDetails = async ({
|
|
|
1516
1691
|
if (typeof token !== "string" || token.trim().length === 0) {
|
|
1517
1692
|
throw new Error("LicenseDetails component requires a non-empty token");
|
|
1518
1693
|
}
|
|
1519
|
-
const
|
|
1520
|
-
console.debug("[portal-components] license response", response.raw);
|
|
1521
|
-
const { license } = response;
|
|
1694
|
+
const license = await fetchLicense();
|
|
1522
1695
|
const rows = buildPrimaryRows(license);
|
|
1523
1696
|
return /* @__PURE__ */ jsxs("div", { className: "rounded border border-gray-100 bg-white p-8 shadow-[0_18px_45px_rgba(17,24,39,0.08)]", children: [
|
|
1524
1697
|
/* @__PURE__ */ jsxs("header", { className: "flex flex-col border-b border-gray-100 pb-6", children: [
|
|
@@ -1526,7 +1699,7 @@ var LicenseDetails = async ({
|
|
|
1526
1699
|
description ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-600", children: description }) : null
|
|
1527
1700
|
] }),
|
|
1528
1701
|
/* @__PURE__ */ jsxs("div", { className: "mt-6 space-y-6", children: [
|
|
1529
|
-
/* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-100 bg-white p-6 sm:p-8", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2
|
|
1702
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-lg border border-gray-100 bg-white p-6 sm:p-8", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 items-start gap-6 md:grid-cols-2 xl:grid-cols-3", children: rows.map((row) => /* @__PURE__ */ jsx("div", { children: row.node }, row.key)) }) }),
|
|
1530
1703
|
/* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-gray-100 bg-white p-6 sm:p-8", children: [
|
|
1531
1704
|
/* @__PURE__ */ jsx("h2", { className: "mb-4 text-lg font-medium text-gray-900", children: "Additional License Fields" }),
|
|
1532
1705
|
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: renderFields(license.fields ?? []) })
|
|
@@ -1719,57 +1892,49 @@ var TopNav = async ({
|
|
|
1719
1892
|
currentCustomerId,
|
|
1720
1893
|
onChangeTeam,
|
|
1721
1894
|
userMenuChildren,
|
|
1722
|
-
logoutButton
|
|
1895
|
+
logoutButton,
|
|
1896
|
+
branding: brandingProp
|
|
1723
1897
|
}) => {
|
|
1724
1898
|
const displayLabel = userMenuLabel || (customerName ? `Team: ${customerName}` : "Team: Example");
|
|
1725
1899
|
let logo;
|
|
1726
1900
|
let brandTitle;
|
|
1727
|
-
let
|
|
1728
|
-
let
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
if (
|
|
1735
|
-
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
if (branding.brandingData) {
|
|
1742
|
-
const decoded = Buffer.from(branding.brandingData, "base64").toString(
|
|
1743
|
-
"utf-8"
|
|
1744
|
-
);
|
|
1745
|
-
try {
|
|
1746
|
-
const parsed = JSON.parse(decoded);
|
|
1747
|
-
if (parsed?.logo && typeof parsed.logo === "string") {
|
|
1748
|
-
logo = parsed.logo;
|
|
1749
|
-
}
|
|
1750
|
-
if (parsed?.title && typeof parsed.title === "string") {
|
|
1751
|
-
const normalizedTitle = parsed.title.trim();
|
|
1752
|
-
if (normalizedTitle) {
|
|
1753
|
-
brandTitle = normalizedTitle;
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
if (parsed?.customColor1 && typeof parsed.customColor1 === "string") {
|
|
1757
|
-
customColor1 = normalizeColor(parsed.customColor1);
|
|
1758
|
-
}
|
|
1759
|
-
if (parsed?.customColor2 && typeof parsed.customColor2 === "string") {
|
|
1760
|
-
customColor2 = normalizeColor(parsed.customColor2);
|
|
1761
|
-
}
|
|
1762
|
-
} catch (error) {
|
|
1763
|
-
console.debug(
|
|
1764
|
-
"[portal-components] unable to parse branding JSON",
|
|
1765
|
-
error
|
|
1766
|
-
);
|
|
1901
|
+
let primaryColor;
|
|
1902
|
+
let secondaryColor;
|
|
1903
|
+
let background;
|
|
1904
|
+
let backgroundImageUrl;
|
|
1905
|
+
let backgroundGradientStart;
|
|
1906
|
+
let backgroundGradientEnd;
|
|
1907
|
+
if (brandingProp) {
|
|
1908
|
+
if (brandingProp.logo && typeof brandingProp.logo === "string") {
|
|
1909
|
+
logo = brandingProp.logo;
|
|
1910
|
+
}
|
|
1911
|
+
if (brandingProp.title && typeof brandingProp.title === "string") {
|
|
1912
|
+
const normalizedTitle = brandingProp.title.trim();
|
|
1913
|
+
if (normalizedTitle) {
|
|
1914
|
+
brandTitle = normalizedTitle;
|
|
1767
1915
|
}
|
|
1768
|
-
} else {
|
|
1769
|
-
console.debug("[portal-components] branding", branding);
|
|
1770
1916
|
}
|
|
1771
|
-
|
|
1772
|
-
|
|
1917
|
+
primaryColor = normalizeColor(brandingProp.primaryColor);
|
|
1918
|
+
secondaryColor = normalizeColor(brandingProp.secondaryColor);
|
|
1919
|
+
background = brandingProp.background;
|
|
1920
|
+
backgroundImageUrl = brandingProp.backgroundImage;
|
|
1921
|
+
backgroundGradientStart = normalizeColor(brandingProp.backgroundGradientStart);
|
|
1922
|
+
backgroundGradientEnd = normalizeColor(brandingProp.backgroundGradientEnd);
|
|
1923
|
+
} else {
|
|
1924
|
+
try {
|
|
1925
|
+
const brandingResponse = await fetchCustomBranding();
|
|
1926
|
+
const branding = decodeBranding({ brandingData: brandingResponse.brandingData });
|
|
1927
|
+
logo = branding.logo;
|
|
1928
|
+
brandTitle = branding.title;
|
|
1929
|
+
primaryColor = branding.primaryColor;
|
|
1930
|
+
secondaryColor = branding.secondaryColor;
|
|
1931
|
+
background = branding.background;
|
|
1932
|
+
backgroundImageUrl = branding.backgroundImage;
|
|
1933
|
+
backgroundGradientStart = branding.backgroundGradientStart;
|
|
1934
|
+
backgroundGradientEnd = branding.backgroundGradientEnd;
|
|
1935
|
+
} catch (error) {
|
|
1936
|
+
console.debug("[portal-components] branding fetch failed", error);
|
|
1937
|
+
}
|
|
1773
1938
|
}
|
|
1774
1939
|
const baseLinks = links ?? defaultTopNavLinks;
|
|
1775
1940
|
const hiddenSet = hiddenLabels ? new Set(hiddenLabels) : null;
|
|
@@ -1780,20 +1945,32 @@ var TopNav = async ({
|
|
|
1780
1945
|
resolvedLinks = [...resolvedLinks, ...additionalLinks];
|
|
1781
1946
|
}
|
|
1782
1947
|
resolvedLinks = orderLinks(resolvedLinks, order);
|
|
1783
|
-
const
|
|
1784
|
-
|
|
1948
|
+
const getHeaderBackgroundStyle = () => {
|
|
1949
|
+
if (background === "image" && backgroundImageUrl) {
|
|
1950
|
+
return {
|
|
1951
|
+
background: `url(${backgroundImageUrl})`,
|
|
1952
|
+
backgroundImage: `linear-gradient(to top, rgba(255, 255, 255, 0.3) 30%, rgba(255, 255, 255, 0)), url(${backgroundImageUrl})`,
|
|
1953
|
+
backgroundSize: "cover",
|
|
1954
|
+
backgroundPosition: "center",
|
|
1955
|
+
backgroundRepeat: "no-repeat"
|
|
1956
|
+
};
|
|
1957
|
+
}
|
|
1958
|
+
const gradientStart = background === "custom" && backgroundGradientStart ? backgroundGradientStart : primaryColor;
|
|
1959
|
+
const gradientEnd = background === "custom" && backgroundGradientEnd ? backgroundGradientEnd : secondaryColor;
|
|
1960
|
+
return {
|
|
1961
|
+
backgroundImage: `linear-gradient(to top, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0) 33%), linear-gradient(${gradientStart}, ${gradientEnd})`,
|
|
1962
|
+
backgroundRepeat: "no-repeat",
|
|
1963
|
+
backgroundSize: "100% 100%"
|
|
1964
|
+
};
|
|
1965
|
+
};
|
|
1785
1966
|
return /* @__PURE__ */ jsx(
|
|
1786
1967
|
"div",
|
|
1787
1968
|
{
|
|
1788
1969
|
className: "relative flex h-[280px] w-full items-start justify-center",
|
|
1789
|
-
style:
|
|
1790
|
-
|
|
1791
|
-
backgroundRepeat: "no-repeat",
|
|
1792
|
-
backgroundSize: "100% 100%"
|
|
1793
|
-
},
|
|
1794
|
-
children: /* @__PURE__ */ jsx("div", { className: "mx-auto mt-[30px] w-full max-w-[1248px] px-6", children: /* @__PURE__ */ jsxs("div", { className: "flex h-[135px] flex-col justify-between space-y-4 rounded bg-[#ffffffe6] px-6 pt-6 pb-4 shadow-[0_10px_60px_rgba(16,16,16,0.35)]", children: [
|
|
1970
|
+
style: getHeaderBackgroundStyle(),
|
|
1971
|
+
children: /* @__PURE__ */ jsx("div", { className: "mx-auto mt-[30px] w-full max-w-[1248px] px-6", children: /* @__PURE__ */ jsxs("div", { className: "flex h-[142px] flex-col justify-between space-y-4 rounded bg-[#ffffffe6] px-6 pt-6 pb-4 shadow-[0_10px_60px_rgba(16,16,16,0.35)]", children: [
|
|
1795
1972
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1796
|
-
|
|
1973
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
1797
1974
|
logo ? (
|
|
1798
1975
|
// eslint-disable-next-line @next/next/no-img-element
|
|
1799
1976
|
/* @__PURE__ */ jsx(
|
|
@@ -1808,9 +1985,24 @@ var TopNav = async ({
|
|
|
1808
1985
|
}
|
|
1809
1986
|
}
|
|
1810
1987
|
)
|
|
1811
|
-
) :
|
|
1812
|
-
|
|
1813
|
-
|
|
1988
|
+
) : /* @__PURE__ */ jsxs(
|
|
1989
|
+
"svg",
|
|
1990
|
+
{
|
|
1991
|
+
className: "h-8 w-8 text-gray-400",
|
|
1992
|
+
viewBox: "0 0 24 24",
|
|
1993
|
+
fill: "none",
|
|
1994
|
+
stroke: "currentColor",
|
|
1995
|
+
strokeWidth: "1.5",
|
|
1996
|
+
"aria-hidden": "true",
|
|
1997
|
+
children: [
|
|
1998
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1999
|
+
/* @__PURE__ */ jsx("ellipse", { cx: "12", cy: "12", rx: "4", ry: "10" }),
|
|
2000
|
+
/* @__PURE__ */ jsx("path", { d: "M2 12h20" })
|
|
2001
|
+
]
|
|
2002
|
+
}
|
|
2003
|
+
),
|
|
2004
|
+
/* @__PURE__ */ jsx("span", { className: "text-xl font-bold text-gray-900", children: brandTitle || "Enterprise Portal" })
|
|
2005
|
+
] }),
|
|
1814
2006
|
/* @__PURE__ */ jsxs("details", { className: "group relative", children: [
|
|
1815
2007
|
/* @__PURE__ */ jsxs("summary", { className: "flex cursor-pointer items-center gap-2 text-sm font-medium text-gray-600 hover:text-gray-900 list-none", children: [
|
|
1816
2008
|
/* @__PURE__ */ jsxs(
|
|
@@ -1872,7 +2064,7 @@ var TopNav = async ({
|
|
|
1872
2064
|
] })
|
|
1873
2065
|
] })
|
|
1874
2066
|
] }),
|
|
1875
|
-
/* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-3
|
|
2067
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-3 pb-2 text-sm font-medium text-gray-500", children: resolvedLinks.map(({ label, icon, href }) => {
|
|
1876
2068
|
const isActive = activeLabel === label;
|
|
1877
2069
|
const className = `flex items-center gap-2 px-4 py-1 transition text-gray-500 ${isActive ? "underline underline-offset-8 decoration-2" : ""}`;
|
|
1878
2070
|
if (href) {
|
|
@@ -1925,9 +2117,17 @@ var headingClass = "text-lg font-semibold text-gray-900";
|
|
|
1925
2117
|
var contentClass = "mt-4 flex-1 space-y-3";
|
|
1926
2118
|
var itemClass = "flex items-center gap-3 text-sm text-gray-600";
|
|
1927
2119
|
var iconClass = "h-5 w-5 text-gray-500";
|
|
1928
|
-
var footerClass = "mt-6 flex justify-end text-sm font-semibold
|
|
1929
|
-
var badgeClass = "ml-2 inline-flex h-5 min-w-[20px] items-center justify-center rounded-full
|
|
1930
|
-
var Badge = ({ count }) => /* @__PURE__ */ jsx(
|
|
2120
|
+
var footerClass = "mt-6 flex justify-end text-sm font-semibold hover:opacity-80";
|
|
2121
|
+
var badgeClass = "ml-2 inline-flex h-5 min-w-[20px] items-center justify-center rounded-full px-1.5 text-xs font-medium text-white";
|
|
2122
|
+
var Badge = ({ count }) => /* @__PURE__ */ jsx(
|
|
2123
|
+
"span",
|
|
2124
|
+
{
|
|
2125
|
+
className: badgeClass,
|
|
2126
|
+
style: { backgroundColor: `var(--portal-branding-primary, ${DEFAULT_SECONDARY_COLOR})` },
|
|
2127
|
+
"aria-label": `${count} updates available`,
|
|
2128
|
+
children: count
|
|
2129
|
+
}
|
|
2130
|
+
);
|
|
1931
2131
|
var UpdatesCard = ({
|
|
1932
2132
|
onlineActiveCount = 0,
|
|
1933
2133
|
airgapCount = 0,
|
|
@@ -1955,7 +2155,7 @@ var UpdatesCard = ({
|
|
|
1955
2155
|
airgapUpdates > 0 && /* @__PURE__ */ jsx(Badge, { count: airgapUpdates })
|
|
1956
2156
|
] })
|
|
1957
2157
|
] }),
|
|
1958
|
-
/* @__PURE__ */ jsx("footer", { className: footerClass, children: /* @__PURE__ */ jsx(Link, { href: "/update", children: "View updates \u2192" }) })
|
|
2158
|
+
/* @__PURE__ */ jsx("footer", { className: footerClass, children: /* @__PURE__ */ jsx(Link, { href: "/update", style: { color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }, children: "View updates \u2192" }) })
|
|
1959
2159
|
] });
|
|
1960
2160
|
UpdatesCard.displayName = "UpdatesCard";
|
|
1961
2161
|
var UploadIcon = (props) => /* @__PURE__ */ jsx(
|
|
@@ -2120,7 +2320,7 @@ var TeamsSection = ({
|
|
|
2120
2320
|
type: "button",
|
|
2121
2321
|
onClick: () => !isCurrentTeam && onTeamSwitch?.(team),
|
|
2122
2322
|
disabled: isCurrentTeam,
|
|
2123
|
-
className: `flex w-full items-center justify-between rounded-lg border p-4 text-left transition ${isCurrentTeam ? "cursor-default border-gray-300 bg-gray-50" : "cursor-pointer border-gray-200 hover:border-
|
|
2323
|
+
className: `flex w-full items-center justify-between rounded-lg border p-4 text-left transition ${isCurrentTeam ? "cursor-default border-gray-300 bg-gray-50" : "cursor-pointer border-gray-200 hover:border-gray-400"}`,
|
|
2124
2324
|
style: !isCurrentTeam && primaryColor ? { "--hover-border": primaryColor } : void 0,
|
|
2125
2325
|
children: [
|
|
2126
2326
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
@@ -2128,7 +2328,7 @@ var TeamsSection = ({
|
|
|
2128
2328
|
"svg",
|
|
2129
2329
|
{
|
|
2130
2330
|
className: "h-4 w-4",
|
|
2131
|
-
style: { color: primaryColor ||
|
|
2331
|
+
style: { color: primaryColor || DEFAULT_SECONDARY_COLOR },
|
|
2132
2332
|
fill: "none",
|
|
2133
2333
|
viewBox: "0 0 24 24",
|
|
2134
2334
|
stroke: "currentColor",
|
|
@@ -2152,7 +2352,7 @@ var TeamsSection = ({
|
|
|
2152
2352
|
"svg",
|
|
2153
2353
|
{
|
|
2154
2354
|
className: "h-4 w-4",
|
|
2155
|
-
style: { color: primaryColor ||
|
|
2355
|
+
style: { color: primaryColor || DEFAULT_SECONDARY_COLOR },
|
|
2156
2356
|
fill: "none",
|
|
2157
2357
|
viewBox: "0 0 24 24",
|
|
2158
2358
|
stroke: "currentColor",
|
|
@@ -2217,7 +2417,10 @@ var ProfileSection = ({
|
|
|
2217
2417
|
resetForm();
|
|
2218
2418
|
setIsEditing(true);
|
|
2219
2419
|
};
|
|
2220
|
-
const buttonStyle =
|
|
2420
|
+
const buttonStyle = {
|
|
2421
|
+
backgroundColor: primaryColor || DEFAULT_SECONDARY_COLOR,
|
|
2422
|
+
borderColor: primaryColor || DEFAULT_SECONDARY_COLOR
|
|
2423
|
+
};
|
|
2221
2424
|
return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-gray-200 bg-white p-6 shadow-sm", children: [
|
|
2222
2425
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
2223
2426
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -2244,7 +2447,7 @@ var ProfileSection = ({
|
|
|
2244
2447
|
onClick: handleSave,
|
|
2245
2448
|
disabled: isUpdating,
|
|
2246
2449
|
style: buttonStyle,
|
|
2247
|
-
className: "inline-flex items-center rounded-md
|
|
2450
|
+
className: "inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium text-white shadow-sm transition-opacity duration-200 hover:opacity-90 disabled:opacity-50 min-w-[70px]",
|
|
2248
2451
|
children: isUpdating ? "Saving..." : "Save"
|
|
2249
2452
|
}
|
|
2250
2453
|
)
|
|
@@ -2254,7 +2457,7 @@ var ProfileSection = ({
|
|
|
2254
2457
|
type: "button",
|
|
2255
2458
|
onClick: handleEdit,
|
|
2256
2459
|
style: buttonStyle,
|
|
2257
|
-
className: "inline-flex items-center rounded-md
|
|
2460
|
+
className: "inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium text-white shadow-sm transition-opacity duration-200 hover:opacity-90 min-w-[70px]",
|
|
2258
2461
|
children: "Edit"
|
|
2259
2462
|
}
|
|
2260
2463
|
)
|
|
@@ -2370,11 +2573,11 @@ UserSettings.displayName = "UserSettings";
|
|
|
2370
2573
|
var baseCardClass3 = "flex h-full flex-col rounded-xl border border-gray-200 bg-white p-6 shadow-[0_16px_32px_rgba(15,23,42,0.05)]";
|
|
2371
2574
|
var headingClass3 = "text-lg font-semibold text-gray-900";
|
|
2372
2575
|
var bodySpacerClass = "mt-4 flex-1";
|
|
2373
|
-
var footerClass3 = "mt-6 flex justify-end text-sm font-semibold
|
|
2576
|
+
var footerClass3 = "mt-6 flex justify-end text-sm font-semibold hover:opacity-80";
|
|
2374
2577
|
var UserSettingsCard = () => /* @__PURE__ */ jsxs("section", { className: baseCardClass3, "aria-labelledby": "user-settings-card-heading", children: [
|
|
2375
2578
|
/* @__PURE__ */ jsx("header", { children: /* @__PURE__ */ jsx("h2", { id: "user-settings-card-heading", className: headingClass3, children: "User Settings" }) }),
|
|
2376
2579
|
/* @__PURE__ */ jsx("div", { className: bodySpacerClass }),
|
|
2377
|
-
/* @__PURE__ */ jsx("footer", { className: footerClass3, children: /* @__PURE__ */ jsx(Link, { href: "/user-settings", children: "View user settings \u2192" }) })
|
|
2580
|
+
/* @__PURE__ */ jsx("footer", { className: footerClass3, children: /* @__PURE__ */ jsx(Link, { href: "/user-settings", style: { color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }, children: "View user settings \u2192" }) })
|
|
2378
2581
|
] });
|
|
2379
2582
|
UserSettingsCard.displayName = "UserSettingsCard";
|
|
2380
2583
|
var UsersIcon = (props) => /* @__PURE__ */ jsx(
|
|
@@ -2412,7 +2615,7 @@ var headingClass4 = "text-lg font-semibold text-gray-900";
|
|
|
2412
2615
|
var contentClass3 = "mt-4 flex-1 space-y-3";
|
|
2413
2616
|
var itemClass3 = "flex items-center gap-3 text-sm text-gray-600";
|
|
2414
2617
|
var iconClass3 = "h-5 w-5 text-gray-500";
|
|
2415
|
-
var footerClass4 = "mt-6 flex justify-end text-sm font-semibold
|
|
2618
|
+
var footerClass4 = "mt-6 flex justify-end text-sm font-semibold hover:opacity-80";
|
|
2416
2619
|
var TeamSettingsCard = ({
|
|
2417
2620
|
userCount = 0,
|
|
2418
2621
|
serviceAccountCount = 0
|
|
@@ -2436,7 +2639,7 @@ var TeamSettingsCard = ({
|
|
|
2436
2639
|
] })
|
|
2437
2640
|
] })
|
|
2438
2641
|
] }),
|
|
2439
|
-
/* @__PURE__ */ jsx("footer", { className: footerClass4, children: /* @__PURE__ */ jsx(Link, { href: "/team-settings", children: "View team settings \u2192" }) })
|
|
2642
|
+
/* @__PURE__ */ jsx("footer", { className: footerClass4, children: /* @__PURE__ */ jsx(Link, { href: "/team-settings", style: { color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }, children: "View team settings \u2192" }) })
|
|
2440
2643
|
] });
|
|
2441
2644
|
TeamSettingsCard.displayName = "TeamSettingsCard";
|
|
2442
2645
|
var UpdateLayout = ({ children }) => {
|
|
@@ -2447,9 +2650,74 @@ var UpdateLayout = ({ children }) => {
|
|
|
2447
2650
|
};
|
|
2448
2651
|
UpdateLayout.displayName = "UpdateLayout";
|
|
2449
2652
|
|
|
2653
|
+
// src/saml-handlers.ts
|
|
2654
|
+
async function setSamlSessionImpl(token) {
|
|
2655
|
+
try {
|
|
2656
|
+
if (!token) {
|
|
2657
|
+
return { success: false, message: "No token provided" };
|
|
2658
|
+
}
|
|
2659
|
+
const cleanToken = token.startsWith("Bearer ") ? token.slice(7) : token;
|
|
2660
|
+
const { cookies: cookies2 } = await import('next/headers');
|
|
2661
|
+
const cookieStore = await cookies2();
|
|
2662
|
+
const isHttpOrigin = process.env.REPLICATED_APP_ORIGIN?.startsWith("http://");
|
|
2663
|
+
const secure = true;
|
|
2664
|
+
const sameSiteValue = isHttpOrigin ? "none" : "lax";
|
|
2665
|
+
cookieStore.set("portal_session", cleanToken, {
|
|
2666
|
+
httpOnly: true,
|
|
2667
|
+
secure,
|
|
2668
|
+
sameSite: sameSiteValue,
|
|
2669
|
+
path: "/"
|
|
2670
|
+
});
|
|
2671
|
+
return { success: true };
|
|
2672
|
+
} catch (error) {
|
|
2673
|
+
console.error("[saml-handlers] Error setting session:", error);
|
|
2674
|
+
return {
|
|
2675
|
+
success: false,
|
|
2676
|
+
message: "Failed to establish session"
|
|
2677
|
+
};
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
async function handleSamlAcs(request) {
|
|
2681
|
+
try {
|
|
2682
|
+
const apiOrigin = getApiOrigin();
|
|
2683
|
+
const formData = await request.formData();
|
|
2684
|
+
const response = await fetch(`${apiOrigin}/saml/acs`, {
|
|
2685
|
+
method: "POST",
|
|
2686
|
+
body: formData,
|
|
2687
|
+
redirect: "manual"
|
|
2688
|
+
});
|
|
2689
|
+
if (response.status === 302 || response.status === 301) {
|
|
2690
|
+
const location = response.headers.get("Location");
|
|
2691
|
+
if (location) {
|
|
2692
|
+
return Response.redirect(location, response.status);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
console.error("[saml-acs] Error response from backend:", {
|
|
2696
|
+
status: response.status,
|
|
2697
|
+
statusText: response.statusText
|
|
2698
|
+
});
|
|
2699
|
+
let errorMessage = "SAML authentication failed";
|
|
2700
|
+
if (response.status === 401 || response.status === 403) {
|
|
2701
|
+
errorMessage = "Authentication failed. Please check your credentials or contact your administrator.";
|
|
2702
|
+
} else if (response.status === 400) {
|
|
2703
|
+
errorMessage = "Invalid SAML request. Please try again.";
|
|
2704
|
+
}
|
|
2705
|
+
return Response.redirect(
|
|
2706
|
+
new URL(`/error?code=${response.status}&message=${encodeURIComponent(errorMessage)}`, request.url),
|
|
2707
|
+
302
|
|
2708
|
+
);
|
|
2709
|
+
} catch (error) {
|
|
2710
|
+
console.error("[saml-acs] Error processing SAML response:", error);
|
|
2711
|
+
return Response.redirect(
|
|
2712
|
+
new URL(`/error?code=500&message=${encodeURIComponent("SAML authentication error")}`, request.url),
|
|
2713
|
+
302
|
|
2714
|
+
);
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2450
2718
|
// src/index.ts
|
|
2451
2719
|
var portalComponentsVersion = package_default.version;
|
|
2452
2720
|
|
|
2453
|
-
export { Button, LicenseDetails, SupportCard, TeamSettingsCard, TopNav, UpdateLayout, UpdatesCard, UserSettings, UserSettingsCard, createPortalTheme, decodeJwtPayload, defaultTopNavLinks, defineServerAction, deleteSupportBundle, downloadSecuritySBOM, downloadSupportBundle, fetchCurrentUser, fetchCustomBranding, fetchDashboardComposite,
|
|
2721
|
+
export { Button, DEFAULT_FAVICON, DEFAULT_PRIMARY_COLOR, DEFAULT_SECONDARY_COLOR, LicenseDetails, SupportCard, TeamSettingsCard, TopNav, UnauthorizedError, UpdateLayout, UpdatesCard, UserSettings, UserSettingsCard, authenticatedFetch, convertToReleaseEntry, createPortalTheme, decodeBranding, decodeJwtPayload, defaultTopNavLinks, defineServerAction, deleteSessionCookie, deleteSupportBundle, downloadSecuritySBOM, downloadSupportBundle, fetchCurrentUser, fetchCustomBranding, fetchDashboardComposite, fetchLicense, fetchNotifications, formatBytes, formatDate, formatDateShort, formatDateTime, formatDateTimeLocal, getCustomerIdFromToken, getSecurityInfo, getSecurityInfoDiff, getSecurityInfoSBOM, getSupportBundleUploadUrl, handleSamlAcs, initiateLogin, isHttpApiOrigin, isRedirectError, listReleases, listSupportBundles, normalizeColor, portalComponentsVersion, portalThemeTokens, sanitizeUrlForCss, setSamlSessionImpl, updateNotifications, updateUser, uploadSupportBundle, validateSession, verifyMagicLink };
|
|
2454
2722
|
//# sourceMappingURL=index.js.map
|
|
2455
2723
|
//# sourceMappingURL=index.js.map
|