@replicated/portal-components 0.0.20 → 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/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../datadog/tracer.ts","../../package.json","../../src/tokens/index.ts","../../src/components/button.tsx","../../src/utils/api-client.ts","../../src/utils/observability/tracing.ts","../../src/actions/fetch-license.ts","../../src/utils/constants.ts","../../src/utils/branding.ts","../../src/utils/session.ts","../../src/utils/format.ts","../../src/utils/release-helpers.ts","../../src/actions/index.ts","../../src/components/license-details.tsx","../../src/components/top-nav.tsx","../../src/components/updates-card.tsx","../../src/components/support-card.tsx","../../src/components/user-settings.tsx","../../src/components/user-settings-card.tsx","../../src/components/team-settings-card.tsx","../../src/components/update-layout.tsx","../../src/saml-handlers.ts","../../src/index.ts"],"names":["cookies","rawFlag","isEnabled","tracer","Buffer","error","cache","raw","jsx","jsxs","Link","baseCardClass","headingClass","contentClass","itemClass","iconClass","footerClass"],"mappings":"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","file":"index.js","sourcesContent":["import type { Tracer, Span, init as ddTraceInit } from 'dd-trace';\nimport type { IncomingMessage } from 'http';\n\nconst rawFlag = String(process.env.USE_DATADOG_APM || '').toLowerCase();\nconst isEnabled = rawFlag === 'true';\n\nprocess.env.DD_TRACE_ENABLED = isEnabled ? '1' : '0';\n\nlet tracer: Tracer | null = null;\n\nif (isEnabled) {\n const serviceName = process.env.DD_SERVICE || 'enterprise-portal';\n const environment = process.env.DD_ENV || process.env.NODE_ENV || 'development';\n const version = process.env.DD_VERSION || process.env.NEXT_PUBLIC_VERSION || '0.0.0-dev';\n\n const agentHost = process.env.DD_AGENT_HOST || process.env.DATADOG_AGENT_HOST || '127.0.0.1';\n const agentPort = process.env.DD_TRACE_AGENT_PORT || '8126';\n\n process.env.DD_SERVICE = serviceName;\n process.env.DD_ENV = environment;\n if (version) {\n process.env.DD_VERSION = version;\n }\n process.env.DD_AGENT_HOST = agentHost;\n process.env.DD_TRACE_AGENT_PORT = agentPort;\n\n const dbmPropagationMode = (process.env.DD_DBM_PROPAGATION_MODE || 'full') as 'disabled' | 'service' | 'full';\n\n process.env.DD_DBM_PROPAGATION_MODE = dbmPropagationMode;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const ddTrace = require('dd-trace');\n tracer = (ddTrace.init as typeof ddTraceInit)({\n service: serviceName,\n env: environment,\n version,\n logInjection: true,\n runtimeMetrics: true,\n appsec: false,\n profiling: false,\n startupLogs: true, // Enable for debugging\n }) as Tracer;\n \n console.log(`[datadog] Tracer initialized: service=${serviceName}, env=${environment}, version=${version}, agent=${agentHost}:${agentPort}`);\n\n // Disable low-level network instrumentation for localhost connections\n tracer.use('dns', false);\n tracer.use('net', false);\n // Configure http plugin to normalize route patterns\n tracer.use('http', {\n server: {\n hooks: {\n request: (span?: Span, req?: IncomingMessage) => {\n if (!span) return;\n\n const url = req?.url || '';\n const method = req?.method || 'GET';\n const path = url.split('?')[0];\n\n // Drop Next.js internal requests\n if (path.startsWith('/_next/')) {\n // @ts-expect-error - using internal property to drop the trace\n span.context()._trace.isRecording = false;\n return;\n }\n\n const routePattern = getRoutePattern(path);\n\n span.setTag('resource.name', `${method} ${routePattern}`);\n span.setTag('http.route', routePattern);\n }\n }\n }\n });\n } catch (err) {\n // Do not crash the app if tracing fails to initialize\n console.error('[datadog] failed to initialize tracing', err);\n tracer = null;\n }\n}\n\n// Function to convert actual paths to route patterns\nconst getRoutePattern = (path: string): string => {\n // Define route patterns for dynamic routes in enterprise portal\n const routePatterns = [\n // Update instance routes - normalize dynamic segments (capture suffix to preserve sub-routes)\n { pattern: /^\\/update\\/instance\\/[^/]+(.*)$/, replacement: '/update/instance/[instanceId]$1' },\n ];\n\n for (const { pattern, replacement } of routePatterns) {\n if (pattern.test(path)) {\n return path.replace(pattern, replacement);\n }\n }\n\n // Return original path if no pattern matches\n return path;\n}\n\nexport default tracer;\n","{\n \"name\": \"@replicated/portal-components\",\n \"version\": \"0.0.20\",\n \"description\": \"Opinionated component library for Replicated enterprise portals\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/replicatedhq/enterprise-portal-components.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/replicatedhq/enterprise-portal-components/issues\"\n },\n \"homepage\": \"https://github.com/replicatedhq/enterprise-portal-components#readme\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/esm/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"style\": \"dist/styles.css\",\n \"files\": [\n \"dist\",\n \"components/metadata\",\n \"instrumentation.js\",\n \"instrumentation.d.ts\",\n \"datadog\"\n ],\n \"sideEffects\": [\n \"*.css\",\n \"*.scss\"\n ],\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/esm/index.js\",\n \"require\": \"./dist/index.js\"\n },\n \"./tokens\": {\n \"types\": \"./dist/tokens/index.d.ts\",\n \"import\": \"./dist/esm/tokens/index.js\",\n \"require\": \"./dist/tokens/index.js\"\n },\n \"./utils\": {\n \"types\": \"./dist/utils/index.d.ts\",\n \"import\": \"./dist/esm/utils/index.js\",\n \"require\": \"./dist/utils/index.js\"\n },\n \"./middleware\": {\n \"types\": \"./dist/middleware.d.ts\",\n \"edge-light\": \"./dist/esm/middleware.js\",\n \"worker\": \"./dist/esm/middleware.js\",\n \"import\": \"./dist/esm/middleware.js\",\n \"require\": \"./dist/middleware.js\",\n \"default\": \"./dist/esm/middleware.js\"\n },\n \"./actions\": {\n \"types\": \"./dist/actions/index.d.ts\",\n \"import\": \"./dist/esm/actions/index.js\",\n \"require\": \"./dist/actions/index.js\"\n },\n \"./actions/team-settings\": {\n \"types\": \"./dist/actions/team-settings.d.ts\",\n \"import\": \"./dist/esm/actions/team-settings.js\",\n \"require\": \"./dist/actions/team-settings.js\"\n },\n \"./actions/user-settings\": {\n \"types\": \"./dist/actions/user-settings.d.ts\",\n \"import\": \"./dist/esm/actions/user-settings.js\",\n \"require\": \"./dist/actions/user-settings.js\"\n },\n \"./actions/change-team\": {\n \"types\": \"./dist/actions/change-team.d.ts\",\n \"import\": \"./dist/esm/actions/change-team.js\",\n \"require\": \"./dist/actions/change-team.js\"\n },\n \"./actions/install-actions\": {\n \"types\": \"./dist/actions/install-actions.d.ts\",\n \"import\": \"./dist/esm/actions/install-actions.js\",\n \"require\": \"./dist/actions/install-actions.js\"\n },\n \"./actions/service-account\": {\n \"types\": \"./dist/actions/service-account.d.ts\",\n \"import\": \"./dist/esm/actions/service-account.js\",\n \"require\": \"./dist/actions/service-account.js\"\n },\n \"./actions/support-bundles\": {\n \"types\": \"./dist/actions/support-bundles.d.ts\",\n \"import\": \"./dist/esm/actions/support-bundles.js\",\n \"require\": \"./dist/actions/support-bundles.js\"\n },\n \"./actions/trial-signup\": {\n \"types\": \"./dist/actions/trial-signup.d.ts\",\n \"import\": \"./dist/esm/actions/trial-signup.js\",\n \"require\": \"./dist/actions/trial-signup.js\"\n },\n \"./install-actions\": {\n \"types\": \"./dist/install-actions.d.ts\",\n \"import\": \"./dist/esm/install-actions.js\",\n \"require\": \"./dist/install-actions.js\"\n },\n \"./license-details\": {\n \"types\": \"./dist/license-details.d.ts\",\n \"import\": \"./dist/esm/license-details.js\",\n \"require\": \"./dist/license-details.js\"\n },\n \"./support-bundle-collection-card\": {\n \"types\": \"./dist/support-bundle-collection-card.d.ts\",\n \"import\": \"./dist/esm/support-bundle-collection-card.js\",\n \"require\": \"./dist/support-bundle-collection-card.js\"\n },\n \"./support-bundles-card\": {\n \"types\": \"./dist/support-bundles-card.d.ts\",\n \"import\": \"./dist/esm/support-bundles-card.js\",\n \"require\": \"./dist/support-bundles-card.js\"\n },\n \"./upload-support-bundle-modal\": {\n \"types\": \"./dist/upload-support-bundle-modal.d.ts\",\n \"import\": \"./dist/esm/upload-support-bundle-modal.js\",\n \"require\": \"./dist/upload-support-bundle-modal.js\"\n },\n \"./top-nav\": {\n \"types\": \"./dist/top-nav.d.ts\",\n \"import\": \"./dist/esm/top-nav.js\",\n \"require\": \"./dist/top-nav.js\"\n },\n \"./install-card\": {\n \"types\": \"./dist/install-card.d.ts\",\n \"import\": \"./dist/esm/install-card.js\",\n \"require\": \"./dist/install-card.js\"\n },\n \"./license-card\": {\n \"types\": \"./dist/license-card.d.ts\",\n \"import\": \"./dist/esm/license-card.js\",\n \"require\": \"./dist/license-card.js\"\n },\n \"./updates-card\": {\n \"types\": \"./dist/updates-card.d.ts\",\n \"import\": \"./dist/esm/updates-card.js\",\n \"require\": \"./dist/updates-card.js\"\n },\n \"./support-card\": {\n \"types\": \"./dist/support-card.d.ts\",\n \"import\": \"./dist/esm/support-card.js\",\n \"require\": \"./dist/support-card.js\"\n },\n \"./install-targets\": {\n \"types\": \"./dist/install-targets.d.ts\",\n \"import\": \"./dist/esm/install-targets.js\",\n \"require\": \"./dist/install-targets.js\"\n },\n \"./linux-install-wizard\": {\n \"types\": \"./dist/linux-install-wizard.d.ts\",\n \"import\": \"./dist/esm/linux-install-wizard.js\",\n \"require\": \"./dist/linux-install-wizard.js\"\n },\n \"./helm-install-wizard\": {\n \"types\": \"./dist/helm-install-wizard.d.ts\",\n \"import\": \"./dist/esm/helm-install-wizard.js\",\n \"require\": \"./dist/helm-install-wizard.js\"\n },\n \"./online-instance-list\": {\n \"types\": \"./dist/online-instance-list.d.ts\",\n \"import\": \"./dist/esm/online-instance-list.js\",\n \"require\": \"./dist/online-instance-list.js\"\n },\n \"./instance-card\": {\n \"types\": \"./dist/instance-card.d.ts\",\n \"import\": \"./dist/esm/instance-card.js\",\n \"require\": \"./dist/instance-card.js\"\n },\n \"./airgap-instances\": {\n \"types\": \"./dist/airgap-instances.d.ts\",\n \"import\": \"./dist/esm/airgap-instances.js\",\n \"require\": \"./dist/airgap-instances.js\"\n },\n \"./update-layout\": {\n \"types\": \"./dist/update-layout.d.ts\",\n \"import\": \"./dist/esm/update-layout.js\",\n \"require\": \"./dist/update-layout.js\"\n },\n \"./user-settings-card\": {\n \"types\": \"./dist/user-settings-card.d.ts\",\n \"import\": \"./dist/esm/user-settings-card.js\",\n \"require\": \"./dist/user-settings-card.js\"\n },\n \"./user-settings\": {\n \"types\": \"./dist/user-settings.d.ts\",\n \"import\": \"./dist/esm/user-settings.js\",\n \"require\": \"./dist/user-settings.js\"\n },\n \"./team-settings-card\": {\n \"types\": \"./dist/team-settings-card.d.ts\",\n \"import\": \"./dist/esm/team-settings-card.js\",\n \"require\": \"./dist/team-settings-card.js\"\n },\n \"./team-settings\": {\n \"types\": \"./dist/team-settings.d.ts\",\n \"import\": \"./dist/esm/team-settings.js\",\n \"require\": \"./dist/team-settings.js\"\n },\n \"./release-history-panel\": {\n \"types\": \"./dist/release-history-panel.d.ts\",\n \"import\": \"./dist/esm/release-history-panel.js\",\n \"require\": \"./dist/release-history-panel.js\"\n },\n \"./release-notes-card\": {\n \"types\": \"./dist/release-notes-card.d.ts\",\n \"import\": \"./dist/esm/release-notes-card.js\",\n \"require\": \"./dist/release-notes-card.js\"\n },\n \"./error\": {\n \"types\": \"./dist/error.d.ts\",\n \"import\": \"./dist/esm/error.js\",\n \"require\": \"./dist/error.js\"\n },\n \"./error-page\": {\n \"types\": \"./dist/error-page.d.ts\",\n \"import\": \"./dist/esm/error-page.js\",\n \"require\": \"./dist/error-page.js\"\n },\n \"./pending-installations\": {\n \"types\": \"./dist/pending-installations.d.ts\",\n \"import\": \"./dist/esm/pending-installations.js\",\n \"require\": \"./dist/pending-installations.js\"\n },\n \"./team-selection\": {\n \"types\": \"./dist/team-selection.d.ts\",\n \"import\": \"./dist/esm/team-selection.js\",\n \"require\": \"./dist/team-selection.js\"\n },\n \"./top-nav-user-menu\": {\n \"types\": \"./dist/top-nav-user-menu.d.ts\",\n \"import\": \"./dist/esm/top-nav-user-menu.js\",\n \"require\": \"./dist/top-nav-user-menu.js\"\n },\n \"./login\": {\n \"types\": \"./dist/login.d.ts\",\n \"import\": \"./dist/esm/login.js\",\n \"require\": \"./dist/login.js\"\n },\n \"./security-card\": {\n \"types\": \"./dist/security-card.d.ts\",\n \"import\": \"./dist/esm/security-card.js\",\n \"require\": \"./dist/security-card.js\"\n },\n \"./join-team\": {\n \"types\": \"./dist/join-team.d.ts\",\n \"import\": \"./dist/esm/join-team.js\",\n \"require\": \"./dist/join-team.js\"\n },\n \"./trial-signup\": {\n \"types\": \"./dist/trial-signup.d.ts\",\n \"import\": \"./dist/esm/trial-signup.js\",\n \"require\": \"./dist/trial-signup.js\"\n },\n \"./service-accounts-tab\": {\n \"types\": \"./dist/service-accounts-tab.d.ts\",\n \"import\": \"./dist/esm/service-accounts-tab.js\",\n \"require\": \"./dist/service-accounts-tab.js\"\n },\n \"./observability\": {\n \"types\": \"./dist/utils/observability/index.d.ts\",\n \"import\": \"./dist/esm/utils/observability/index.js\",\n \"require\": \"./dist/utils/observability/index.js\"\n },\n \"./saml-handlers\": {\n \"types\": \"./dist/saml-handlers.d.ts\",\n \"import\": \"./dist/esm/saml-handlers.js\",\n \"require\": \"./dist/saml-handlers.js\"\n },\n \"./saml-callback-client\": {\n \"types\": \"./dist/saml-callback-client.d.ts\",\n \"import\": \"./dist/esm/saml-callback-client.js\",\n \"require\": \"./dist/saml-callback-client.js\"\n },\n \"./instrumentation\": \"./instrumentation.js\",\n \"./styles.css\": \"./dist/styles.css\",\n \"./metadata/registry.json\": \"./components/metadata/registry.json\"\n },\n \"scripts\": {\n \"clean\": \"rimraf dist\",\n \"build\": \"npm run clean && npm run registry:generate && npm run build:css && npm run build:instrumentation && tsup\",\n \"build:css\": \"tailwindcss -i ./src/styles.css -o ./dist/styles.css --config tailwind.config.ts\",\n \"build:instrumentation\": \"tsc instrumentation.ts --outDir . --declaration --module esnext --target es2022 --moduleResolution bundler --skipLibCheck && tsc datadog/tracer.ts --outDir datadog --declaration --module esnext --target es2022 --moduleResolution bundler --skipLibCheck\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"registry:generate\": \"tsx scripts/generate-registry.ts\",\n \"size\": \"size-limit\",\n \"release\": \"changeset\"\n },\n \"dependencies\": {\n \"classnames\": \"^2.5.1\",\n \"dd-trace\": \"^5.70.0\"\n },\n \"peerDependencies\": {\n \"lucide-react\": \">=0.400.0\",\n \"next\": \">=14.0.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.8\",\n \"lucide-react\": \"^0.468.0\",\n \"@size-limit/preset-big-lib\": \"^12.0.0\",\n \"@types/node\": \"^22.10.1\",\n \"@types/react\": \"^19.0.4\",\n \"@types/react-dom\": \"^19.0.3\",\n \"autoprefixer\": \"^10.4.20\",\n \"postcss\": \"^8.4.49\",\n \"react\": \"19.0.0\",\n \"react-dom\": \"19.0.0\",\n \"rimraf\": \"^6.0.1\",\n \"size-limit\": \"^12.0.0\",\n \"tailwindcss\": \"^3.4.17\",\n \"tslib\": \"^2.7.0\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.19.2\",\n \"typescript\": \"^5.6.3\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"packageManager\": \"npm@10.9.0\",\n \"size-limit\": [\n {\n \"name\": \"core entry\",\n \"path\": \"dist/esm/index.js\",\n \"import\": \"{ Login }\",\n \"limit\": \"35 KB\",\n \"gzip\": true\n }\n ]\n}\n","type DeepPartial<T> = {\n [Key in keyof T]?: T[Key] extends Record<string, unknown>\n ? DeepPartial<T[Key]>\n : T[Key];\n};\n\nexport interface PortalThemeTokens {\n colors: {\n background: string;\n foreground: string;\n surfaceMuted: string;\n primary: string;\n onPrimary: string;\n secondary: string;\n onSecondary: string;\n success: string;\n warning: string;\n danger: string;\n };\n radii: {\n lg: string;\n md: string;\n sm: string;\n };\n spacing: Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", string>;\n typography: {\n fontFamily: string;\n monoFamily: string;\n lineHeight: Record<\"tight\" | \"normal\" | \"relaxed\", string>;\n };\n shadows: {\n focus: string;\n overlay: string;\n };\n}\n\nconst baseTokens: PortalThemeTokens = {\n colors: {\n background: \"#0b0d12\",\n foreground: \"#f4f6fb\",\n surfaceMuted: \"#1b1f2a\",\n primary: \"#0d6efd\",\n onPrimary: \"#ffffff\",\n secondary: \"#6c757d\",\n onSecondary: \"#ffffff\",\n success: \"#22c55e\",\n warning: \"#fbbf24\",\n danger: \"#ef4444\"\n },\n radii: {\n lg: \"16px\",\n md: \"10px\",\n sm: \"6px\"\n },\n spacing: {\n xs: \"0.25rem\",\n sm: \"0.5rem\",\n md: \"0.75rem\",\n lg: \"1rem\",\n xl: \"1.5rem\"\n },\n typography: {\n fontFamily:\n \"Inter, 'SF Pro Display', 'Segoe UI', system-ui, -apple-system, sans-serif\",\n monoFamily: \"'JetBrains Mono', 'SFMono-Regular', Consolas, monospace\",\n lineHeight: {\n tight: \"1.2\",\n normal: \"1.5\",\n relaxed: \"1.75\"\n }\n },\n shadows: {\n focus: \"0 0 0 3px color-mix(in srgb, #0d6efd 35%, transparent)\",\n overlay: \"0px 20px 55px rgba(5, 7, 11, 0.5)\"\n }\n};\n\nconst mergeTokens = (\n base: PortalThemeTokens,\n overrides?: DeepPartial<PortalThemeTokens>\n): PortalThemeTokens => {\n if (!overrides) {\n return base;\n }\n\n const clone = structuredClone(base);\n\n const apply = (target: Record<string, any>, source: Record<string, any>) => {\n Object.entries(source).forEach(([key, value]) => {\n if (\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof target[key] === \"object\"\n ) {\n apply(target[key], value);\n return;\n }\n\n target[key] = value;\n });\n };\n\n apply(clone as Record<string, any>, overrides as Record<string, any>);\n return clone;\n};\n\nexport const portalThemeTokens: PortalThemeTokens =\n mergeTokens(baseTokens);\n\nexport const createPortalTheme = (\n overrides?: DeepPartial<PortalThemeTokens>\n) => mergeTokens(baseTokens, overrides);\n\nexport type { DeepPartial as PortalThemeOverrides };\n","import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ReactNode\n} from \"react\";\n\nconst buttonVariants = [\"primary\", \"secondary\", \"ghost\", \"destructive\"] as const;\nconst buttonSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary:\n \"bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-primary\",\n secondary:\n \"bg-secondary/20 text-secondary-foreground hover:bg-secondary/30 focus-visible:ring-secondary\",\n ghost:\n \"bg-transparent text-primary hover:bg-primary/10 focus-visible:ring-primary/60\",\n destructive:\n \"bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger\"\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n sm: \"h-8 px-3 text-sm\",\n md: \"h-10 px-4 text-sm\",\n lg: \"h-12 px-6 text-base\"\n};\n\nconst inlineFlexBase =\n \"inline-flex items-center justify-center gap-2 rounded-md font-medium tracking-tight transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-60\";\n\nconst Spinner = () => (\n <span className=\"inline-flex h-3.5 w-3.5 animate-spin items-center justify-center\">\n <span className=\"h-3 w-3 rounded-full border-2 border-transparent border-t-current\" />\n </span>\n);\n\nexport type ButtonVariant = (typeof buttonVariants)[number];\nexport type ButtonSize = (typeof buttonSizes)[number];\n\nexport interface ButtonProps extends ComponentPropsWithoutRef<\"button\"> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n isLoading?: boolean;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n}\n\nconst composeClassName = (\n ...values: Array<string | undefined | false>\n): string => values.filter(Boolean).join(\" \");\n\n/**\n * Button is the primary interactive primitive for triggering portal actions.\n * It is theme aware via CSS variables generated from portal tokens.\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = \"primary\",\n size = \"md\",\n type = \"button\",\n isLoading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const computedLeading = isLoading ? <Spinner /> : leadingIcon;\n const computedDisabled = disabled ?? isLoading;\n\n return (\n <button\n ref={ref}\n type={type}\n className={composeClassName(\n inlineFlexBase,\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n aria-busy={isLoading || undefined}\n disabled={computedDisabled}\n {...props}\n >\n {computedLeading ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {computedLeading}\n </span>\n ) : null}\n <span className=\"flex-1 whitespace-nowrap\">{children}</span>\n {trailingIcon ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {trailingIcon}\n </span>\n ) : null}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n","/**\n * Centralized API client utility for handling authenticated requests\n * with automatic 401 detection, cookie deletion, and redirect.\n */\n\nexport interface ApiFetchOptions extends RequestInit {\n token?: string;\n}\n\nexport class UnauthorizedError extends Error {\n constructor(message = \"Unauthorized\") {\n super(message);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/**\n * Helper to check if an error is a Next.js redirect error.\n * These errors should NOT be caught as they control navigation flow.\n */\nexport function isRedirectError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"digest\" in error &&\n typeof (error as { digest?: unknown }).digest === \"string\" &&\n (error as { digest: string }).digest.startsWith(\"NEXT_REDIRECT\")\n );\n}\n\n/**\n * Fetch wrapper that automatically handles error responses by:\n * - 401: Redirecting to \"/\" with expired parameter\n * - 502, 503, 504: Redirecting to \"/error\" with status code\n * \n * This function should be used for all authenticated API calls in server actions.\n * \n * IMPORTANT: This must be called from a Server Action context, not directly from\n * a Server Component, because it modifies cookies.\n */\nexport async function authenticatedFetch(\n url: string,\n options: ApiFetchOptions = {}\n): Promise<Response> {\n const { token, ...fetchOptions } = options;\n\n // Add authorization header if token is provided\n const headers = new Headers(fetchOptions.headers);\n if (token) {\n headers.set(\"authorization\", `Bearer ${token}`);\n }\n\n const response = await fetch(url, {\n ...fetchOptions,\n headers\n });\n\n // Handle 401 Unauthorized\n if (response.status === 401) {\n await handle401();\n }\n\n // Handle server errors (502, 503, 504) by redirecting to error page\n if (response.status === 502 || response.status === 503 || response.status === 504) {\n await handleServerError(response.status);\n }\n\n return response;\n}\n\n/**\n * Handles 401 unauthorized responses by redirecting to the root path with a logout parameter.\n * \n * Note: We cannot delete cookies here because this is called during Server Component\n * render, not from a true Server Action invocation.\n * \n * The home page MUST check for the `?expired=1` parameter and delete the portal_session\n * cookie when present to avoid infinite loops. Example:\n * \n * ```typescript\n * // In your home page (app/page.tsx)\n * import { cookies } from \"next/headers\";\n * \n * export default async function Home({ searchParams }: { searchParams: { expired?: string } }) {\n * if (searchParams.expired === \"1\") {\n * const cookieStore = await cookies();\n * cookieStore.delete(\"portal_session\");\n * }\n * \n * const sessionStore = await cookies();\n * const session = sessionStore.get(\"portal_session\");\n * // ... rest of your logic\n * }\n * ```\n */\nasync function handle401(): Promise<never> {\n const { redirect } = await import(\"next/navigation\");\n \n // Redirect with expired parameter so the home page can delete the cookie\n return redirect(\"/?expired=1\");\n}\n\n/**\n * Helper to check if a URL is the error page itself.\n * Only matches the exact error page route, not URLs containing \"error\" elsewhere.\n * \n * @param url - The URL to check\n * @returns true if the URL is the error page (e.g., /error or /error?code=500)\n */\nfunction isErrorPage(url: string): boolean {\n try {\n // Try parsing as full URL (e.g., https://example.com/error)\n const urlObj = new URL(url);\n return urlObj.pathname === \"/error\";\n } catch {\n // If not a full URL, check as path string (e.g., /error or /error?code=500)\n return url === \"/error\" || url.startsWith(\"/error?\");\n }\n}\n\n/**\n * Handles server errors (502, 503, 504) by redirecting to the error page.\n * \n * The error page route should be created at `app/error/page.tsx` in the consuming\n * application and use the ErrorPage component. Example:\n * \n * ```typescript\n * // In your error page (app/error/page.tsx)\n * import { ErrorPage } from \"@replicated/portal-components/error-page\";\n * \n * export default function Error({ \n * searchParams \n * }: { \n * searchParams: { code?: string; source?: string } \n * }) {\n * const statusCode = searchParams.code ? parseInt(searchParams.code, 10) : undefined;\n * const sourceUrl = searchParams.source;\n * return <ErrorPage statusCode={statusCode} sourceUrl={sourceUrl} />;\n * }\n * ```\n */\nasync function handleServerError(statusCode: number): Promise<never> {\n const { redirect } = await import(\"next/navigation\");\n const { cookies } = await import(\"next/headers\");\n \n // Try to get the current URL from Next.js headers\n let sourceUrl: string | undefined;\n try {\n const { headers } = await import(\"next/headers\");\n const headersList = await headers();\n const referer = headersList.get(\"referer\");\n const host = headersList.get(\"host\");\n const pathname = headersList.get(\"x-invoke-path\") || headersList.get(\"x-forwarded-path\");\n \n // Don't use referer if it's the error page itself\n if (referer && !isErrorPage(referer)) {\n sourceUrl = referer;\n } else if (host && pathname) {\n const protocol = headersList.get(\"x-forwarded-proto\") || \"https\";\n sourceUrl = `${protocol}://${host}${pathname}`;\n }\n \n // If we couldn't determine source from headers, check for preserved source in cookie\n if (!sourceUrl || isErrorPage(sourceUrl)) {\n const cookieStore = await cookies();\n const preservedSource = cookieStore.get(\"portal_error_source\");\n if (preservedSource?.value) {\n sourceUrl = decodeURIComponent(preservedSource.value);\n // Clear the cookie after reading it\n cookieStore.delete(\"portal_error_source\");\n }\n }\n } catch (error) {\n // If we can't get headers, continue without source URL\n console.debug(\"[portal-components] Could not determine source URL\", error);\n }\n \n // Redirect to error page with status code and source URL parameters\n const params = new URLSearchParams({ code: String(statusCode) });\n if (sourceUrl) {\n params.set(\"source\", sourceUrl);\n }\n \n return redirect(`/error?${params.toString()}`);\n}\n","import type { Span, Tracer } from 'dd-trace';\n\n// Type for a function that has been wrapped with tracing (always returns a Promise)\ntype TracedFunction<T extends (...args: any[]) => any> = (\n ...args: Parameters<T>\n) => Promise<Awaited<ReturnType<T>>>;\n\n// Lazy-load tracer only when tracing is enabled\n// Using undefined to distinguish between \"not loaded yet\" and \"loaded but null\"\nlet tracerCache: Tracer | null | undefined = undefined;\n\nfunction getTracer(): Tracer | null {\n // Return cached result if already loaded (prevents race conditions and multiple initializations)\n if (tracerCache !== undefined) {\n return tracerCache;\n }\n\n // Check if tracing is enabled at runtime (consistent with datadog/tracer.ts and instrumentation.ts)\n const rawFlag = String(process.env.USE_DATADOG_APM || '').toLowerCase();\n const isEnabled = rawFlag === 'true';\n\n if (!isEnabled) {\n tracerCache = null;\n return null;\n }\n\n // Lazy load the tracer module only when needed\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const tracerModule = require('../../../datadog/tracer');\n const tracer = tracerModule.default || tracerModule;\n\n if (tracer && typeof (tracer as any).trace === 'function') {\n tracerCache = tracer as Tracer;\n return tracerCache;\n }\n } catch (err) {\n console.warn('Failed to load tracer:', err);\n }\n\n tracerCache = null;\n return null;\n}\n\n/**\n * Get the currently active span from the tracer's scope.\n * This can be used to pass span context to database calls.\n */\nexport function getActiveSpan(): Span | undefined {\n const activeTracer = getTracer();\n if (!activeTracer || !activeTracer.scope) {\n return undefined;\n }\n const active = activeTracer.scope().active();\n return active || undefined;\n}\n\nexport async function withTrace<T>(\n name: string,\n fn: (span?: Span) => Promise<T> | T,\n): Promise<T> {\n const activeTracer = getTracer();\n if (!activeTracer) {\n return fn(undefined);\n }\n\n return activeTracer.trace(name, async (span?: Span) => {\n if (span) {\n span.setTag('component', 'application');\n }\n try {\n const result = await fn(span);\n return result;\n } catch (error) {\n if (span) {\n span.setTag('error', error as any);\n }\n throw error;\n }\n });\n}\n\nexport function traceServerAction<T extends (...args: any[]) => any>(\n name: string,\n fn: T,\n): TracedFunction<T> {\n const spanName = name.startsWith('server.action.') ? name : `server.action.${name}`;\n\n const traced: TracedFunction<T> = async (...args: Parameters<T>) => {\n return withTrace(spanName, async (span) => {\n if (span) {\n span.setTag('component', 'server-action');\n }\n const result = await fn(...args);\n return result;\n });\n };\n\n return traced;\n}\n\nexport function traceFunction<T extends (...args: any[]) => any>(\n name: string,\n fn: T,\n): TracedFunction<T> {\n const traced: TracedFunction<T> = async (...args: Parameters<T>) => {\n return withTrace(name, async () => {\n const result = await fn(...args);\n return result;\n });\n };\n\n return traced;\n}\n","\"use server\";\n\nimport { cache } from \"react\";\nimport { cookies } from \"next/headers\";\nimport { getApiOrigin } from \"./index\";\nimport { authenticatedFetch } from \"../utils/api-client\";\n\nexport interface CustomHostnameOverrides {\n registry?: string;\n proxyRegistry?: string;\n replicatedApp?: string;\n}\n\nexport interface LicenseChannel {\n appId: string;\n licenseId: string;\n channelId: string;\n channelName: string;\n channelSlug: string;\n isSemverRequired: number;\n isDefault: number;\n pinnedChannelSequence?: number | null;\n customHostnameOverrides?: CustomHostnameOverrides;\n hasKurlInstaller: boolean;\n}\n\nexport interface EntitlementField {\n name: string;\n title: string;\n type: string;\n required: number;\n hidden: number;\n defaultVal: string;\n}\n\nexport interface EntitlementValue {\n name: string;\n value: string;\n}\n\nexport interface PortalLicenseField {\n key: string;\n label: string;\n value: string | null;\n isSecret?: boolean;\n}\n\nexport interface License {\n // API response fields (exact match with Go struct)\n id: string;\n appId: string;\n appName?: string | null;\n appIcon?: string | null;\n channels: LicenseChannel[];\n customerId: string;\n customerName: string;\n customerEmail?: string | null;\n createdAt: string;\n updatedAt: string;\n expireAt?: string | null;\n isExpired: boolean;\n isArchived: boolean;\n licenseType: string;\n sequence: number;\n isAirgapSupported: boolean;\n isGitopsSupported: boolean;\n isIdentityServiceSupported: boolean;\n isGeoaxisSupported: boolean;\n isSnapshotSupported: boolean;\n isDisasterRecoverySupported: boolean;\n isSupportBundleUploadSupported: boolean;\n isEmbeddedClusterDownloadEnabled: boolean;\n isEmbeddedClusterMultiNodeEnabled: boolean;\n isKotsInstallEnabled: boolean;\n isHelmInstallEnabled: boolean;\n isKurlInstallEnabled: boolean;\n isHelmAirgapEnabled: boolean;\n entitlementFields: EntitlementField[];\n entitlementValues: EntitlementValue[];\n\n // Backward compatibility (computed)\n expiresAt?: string | null;\n environment?: string;\n releaseChannels?: string[];\n installMethods?: string[];\n fields?: PortalLicenseField[];\n}\n\n// Helper function to derive install methods from license feature flags\nconst deriveInstallMethods = (licenseData: any): string[] => {\n const methods: string[] = [];\n \n if (licenseData.isKotsInstallEnabled) {\n methods.push(\"Replicated KOTS\");\n }\n if (licenseData.isHelmInstallEnabled) {\n methods.push(\"Helm\");\n }\n if (licenseData.isHelmAirgapEnabled) {\n methods.push(\"Helm Airgap\");\n }\n if (licenseData.isEmbeddedClusterDownloadEnabled || licenseData.isEmbeddedClusterMultiNodeEnabled) {\n methods.push(\"Embedded Cluster\");\n }\n if (licenseData.isKurlInstallEnabled) {\n methods.push(\"kURL\");\n }\n if (licenseData.isGitopsSupported) {\n methods.push(\"GitOps\");\n }\n \n return Array.from(new Set(methods));\n};\n\n// Helper function to convert entitlements to fields format for backward compatibility\nconst convertEntitlementsToFields = (\n entitlementFields: EntitlementField[],\n entitlementValues: EntitlementValue[]\n): PortalLicenseField[] => {\n const valuesMap = new Map<string, string>();\n entitlementValues.forEach(ev => {\n valuesMap.set(ev.name, ev.value);\n });\n \n return entitlementFields\n .filter(field => field.hidden === 0)\n .map(field => ({\n key: field.name,\n label: field.title || field.name,\n value: valuesMap.get(field.name) || field.defaultVal || null,\n isSecret: field.type === \"Password\"\n }));\n};\n\n/**\n * Internal implementation of fetching license data.\n *\n * Reads from /enterprise-portal/license API response.\n */\nasync function fetchLicenseCore(): Promise<License> {\n const sessionStore = await cookies();\n const session = sessionStore.get(\"portal_session\");\n const token = session?.value;\n\n if (!token) {\n throw new Error(\"No session found - user must be authenticated\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/license`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching license via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n Accept: \"application/json\"\n }\n });\n\n if (!response.ok) {\n throw new Error(\n `License request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n const licenseData = envelope.data;\n\n // Add computed properties for backward compatibility\n const license: License = {\n ...licenseData,\n // Alias fields for backward compatibility\n expiresAt: licenseData.expireAt,\n environment: licenseData.licenseType,\n // Extract channel names from channels array\n releaseChannels: (licenseData.channels || []).map((ch: LicenseChannel) => ch.channelName),\n // Derive install methods from feature flags\n installMethods: deriveInstallMethods(licenseData),\n // Convert entitlements to fields format\n fields: convertEntitlementsToFields(licenseData.entitlementFields || [], licenseData.entitlementValues || [])\n };\n\n return license;\n}\n\n/**\n * Fetches license data including entitlements and feature flags.\n *\n * This function is cached per-request to avoid duplicate API calls.\n */\nconst fetchLicenseImpl = cache(fetchLicenseCore);\nexport const fetchLicense = fetchLicenseImpl;\n","/**\n * Default globe favicon matching the CiGlobe icon (Circum Icons)\n * Used as fallback when custom branding doesn't provide a favicon\n */\nexport const 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\";\n\n/**\n * Default primary brand color\n */\nexport const DEFAULT_PRIMARY_COLOR = \"#4f46e5\";\n\n/**\n * Default secondary brand color\n */\nexport const DEFAULT_SECONDARY_COLOR = \"#6366f1\";\n\n/**\n * Check if the API origin is HTTP (used for repldev environments)\n * This determines cookie security settings for cross-origin iframes\n * @returns true if the API origin starts with http:// (not https://)\n */\nexport const isHttpApiOrigin = (): boolean => {\n return process.env.REPLICATED_APP_ORIGIN?.startsWith('http://') || false;\n};\n","import { Buffer } from \"node:buffer\";\nimport { DEFAULT_PRIMARY_COLOR, DEFAULT_SECONDARY_COLOR } from \"./constants\";\n\ninterface RawBranding {\n brandingData?: string;\n}\n\nexport type BackgroundType = \"minimal\" | \"custom\" | \"image\";\n\ninterface BrandingResult {\n logo?: string;\n title?: string;\n favicon?: string;\n primaryColor: string;\n secondaryColor: string;\n supportPortalLink?: string;\n background?: BackgroundType;\n backgroundImage?: string;\n backgroundGradientStart?: string;\n backgroundGradientEnd?: string;\n}\n\n/**\n * Normalizes and validates CSS color values to prevent CSS injection attacks.\n * Only supports hex color format (#rgb or #rrggbb) as that's what the API sends.\n * \n * @param color - The color value to normalize\n * @returns The normalized hex color or undefined if invalid\n */\nexport const normalizeColor = (color?: string) => {\n if (!color || typeof color !== \"string\") {\n return undefined;\n }\n\n const trimmed = color.trim();\n \n // Validate hex colors only (#rgb or #rrggbb)\n if (/^#?[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/.test(trimmed)) {\n return trimmed.startsWith(\"#\") ? trimmed : `#${trimmed}`;\n }\n\n // Invalid color format - reject to prevent CSS injection\n console.debug(\"[portal-components] Invalid color format rejected (only hex supported):\", trimmed);\n return undefined;\n};\n\n/**\n * Validates and sanitizes a URL for safe use in CSS url() functions.\n * This prevents CSS injection attacks by validating the URL format and\n * escaping characters that could break out of the url() context.\n * \n * @param url - The URL to validate and sanitize\n * @returns The sanitized URL or undefined if invalid\n */\nexport const sanitizeUrlForCss = (url?: string): string | undefined => {\n if (!url || typeof url !== \"string\") {\n return undefined;\n }\n\n const trimmed = url.trim();\n \n // Validate URL format: must be http(s) or data URL\n try {\n const urlObj = new URL(trimmed);\n if (![\"http:\", \"https:\", \"data:\"].includes(urlObj.protocol)) {\n console.debug(\"[portal-components] Invalid URL protocol for background image:\", urlObj.protocol);\n return undefined;\n }\n } catch {\n console.debug(\"[portal-components] Invalid URL format for background image:\", trimmed);\n return undefined;\n }\n\n // Escape characters that could break out of CSS url() context\n // These include: ), \", ', \\, and control characters\n const escaped = trimmed\n .replace(/\\\\/g, \"\\\\\\\\\") // Escape backslashes first\n .replace(/\\)/g, \"\\\\)\") // Escape closing parenthesis\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/[\\x00-\\x1F\\x7F]/g, \"\"); // Remove control characters\n\n return escaped;\n};\n\nexport const decodeBranding = ({ brandingData }: RawBranding): BrandingResult => {\n if (!brandingData || typeof brandingData !== \"string\") {\n return {\n primaryColor: DEFAULT_PRIMARY_COLOR,\n secondaryColor: DEFAULT_SECONDARY_COLOR\n };\n }\n\n try {\n const decoded = Buffer.from(brandingData, \"base64\").toString(\"utf-8\");\n const parsed = JSON.parse(decoded) as Record<string, unknown>;\n\n const logo = typeof parsed.logo === \"string\" ? parsed.logo : undefined;\n const titleRaw = typeof parsed.title === \"string\" ? parsed.title.trim() : \"\";\n const title = titleRaw ? titleRaw : undefined;\n const favicon = typeof parsed.favicon === \"string\" ? parsed.favicon : undefined;\n\n // Support both camelCase and snake_case field names for primary/secondary colors\n const primaryColorRaw = (parsed.primaryColor ?? parsed.primary_color) as string | undefined;\n const secondaryColorRaw = (parsed.secondaryColor ?? parsed.secondary_color) as string | undefined;\n const primaryColor = normalizeColor(primaryColorRaw);\n const secondaryColor = normalizeColor(secondaryColorRaw);\n\n // Support portal link\n const supportPortalLink = typeof parsed.supportPortalLink === \"string\" ? parsed.supportPortalLink : undefined;\n\n // Background customization\n const backgroundRaw = parsed.background as string | undefined;\n const background = (backgroundRaw === \"minimal\" || backgroundRaw === \"custom\" || backgroundRaw === \"image\")\n ? backgroundRaw\n : undefined;\n // Validate and sanitize background image URL to prevent CSS injection\n const backgroundImage = sanitizeUrlForCss(parsed.backgroundImage as string | undefined);\n // customColor1/customColor2 are for the background gradient\n const backgroundGradientStart = normalizeColor(parsed.customColor1 as string | undefined);\n const backgroundGradientEnd = normalizeColor(parsed.customColor2 as string | undefined);\n\n return {\n logo,\n title,\n favicon,\n primaryColor: primaryColor || DEFAULT_PRIMARY_COLOR,\n secondaryColor: secondaryColor || DEFAULT_SECONDARY_COLOR,\n supportPortalLink,\n background,\n backgroundImage,\n backgroundGradientStart,\n backgroundGradientEnd\n };\n } catch (error) {\n console.debug(\"[portal-components] unable to parse branding JSON\", error);\n return {\n primaryColor: DEFAULT_PRIMARY_COLOR,\n secondaryColor: DEFAULT_SECONDARY_COLOR\n };\n }\n};\n","/**\n * Session validation utilities for handling authentication tokens.\n */\n\nimport { getApiOrigin } from \"../actions/index\";\n\n/**\n * Validates a session token by making a lightweight authenticated request.\n * Returns true if valid, false if invalid (401).\n * \n * This should be called from Server Components (like the home page) to validate\n * the session cookie before rendering authenticated content.\n */\nexport async function validateSession(token: string): Promise<boolean> {\n if (!token || typeof token !== \"string\" || !token.trim()) {\n return false;\n }\n\n try {\n // Make a lightweight request to check token validity\n // NEW: Using Enterprise Portal API user endpoint (fast and no customer_id needed)\n const endpoint = `${getApiOrigin()}/enterprise-portal/user`;\n\n const response = await fetch(endpoint, {\n method: \"GET\",\n headers: {\n authorization: `Bearer ${token}`\n },\n // Short timeout for validation\n signal: AbortSignal.timeout(5000)\n });\n\n // 200 = valid, 401 = invalid, anything else we'll treat as temporarily valid\n if (response.status === 401) {\n return false;\n }\n\n return response.ok;\n } catch (error) {\n // On error, assume valid to avoid blocking users during transient failures\n console.warn(\"[portal-components] session validation error:\", error);\n return true;\n }\n}\n\n/**\n * Deletes the portal_session cookie.\n * This MUST be called from a Server Action or Route Handler, not from Server Component render.\n * \n * Usage example in a Server Action:\n * ```typescript\n * \"use server\";\n * import { deleteSessionCookie } from \"@replicated/portal-components/utils\";\n * export async function logout() {\n * await deleteSessionCookie();\n * redirect(\"/\");\n * }\n * ```\n */\nexport async function deleteSessionCookie(): Promise<void> {\n const { cookies } = await import(\"next/headers\");\n const cookieStore = await cookies();\n cookieStore.delete(\"portal_session\");\n}\n","/**\n * Format bytes to human-readable string\n * @param bytes - Number of bytes\n * @param decimals - Number of decimal places (default: 1)\n * @returns Formatted string (e.g., \"1.5 MB\")\n */\nexport function formatBytes(bytes: number, decimals = 1): string {\n if (bytes === 0) return \"0 Bytes\";\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\"];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\n/**\n * Format date string to short numeric date (no time)\n * @param dateString - ISO date string or null/undefined\n * @returns Formatted string (e.g., \"01/27/2026\") or \"Never\" if no date\n */\nexport function formatDateShort(dateString?: string | null): string {\n if (!dateString) return \"Never\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\"\n });\n}\n\n/**\n * Format date string to human-readable local timestamp\n * @param dateString - ISO date string or null/undefined\n * @returns Formatted string (e.g., \"Jan 27, 2026, 10:32 PM\") or \"Never\" if no date\n */\nexport function formatDate(dateString?: string | null): string {\n if (!dateString) return \"Never\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true\n });\n}\n\n/**\n * Format date string to human-readable UTC timestamp\n * @param dateString - ISO date string\n * @returns Formatted string (e.g., \"01/27/2026, 22:32:39 UTC\")\n */\nexport function formatDateTime(dateString: string): string {\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleString(\"en-US\", {\n timeZone: \"UTC\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false\n }) + \" UTC\";\n}\n\n/**\n * Format date string to user-friendly local timestamp with 12-hour time\n * @param dateString - ISO date string or null/undefined\n * @returns Formatted string (e.g., \"1/27/2026, 10:32 PM\") or \"N/A\" if not provided\n */\nexport function formatDateTimeLocal(dateString?: string | null): string {\n if (!dateString) return \"N/A\";\n\n try {\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleDateString(\"en-US\", {\n month: \"numeric\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true\n });\n } catch {\n return \"N/A\";\n }\n}\n","import type { DownloadPortalRelease } from \"../actions\";\nimport type { ReleaseEntry } from \"../components/release-history-panel\";\n\nexport type ReleaseNotesMode = \"markdown\" | \"items\";\n\nexport interface ConvertToReleaseEntryOptions {\n releaseNotesMode: ReleaseNotesMode;\n}\n\n/**\n * Converts a DownloadPortalRelease to a ReleaseEntry for display\n * @param release - The release data from the API\n * @param channelName - The channel name for display\n * @param options - Options for how to format the release entry\n * @returns A ReleaseEntry ready for display\n */\nexport function convertToReleaseEntry(\n release: DownloadPortalRelease,\n channelName: string,\n options: ConvertToReleaseEntryOptions\n): ReleaseEntry {\n const sections: ReleaseEntry[\"sections\"] = [];\n\n // Add release notes section\n if (release.release_notes && release.release_notes.trim().length > 0) {\n if (options.releaseNotesMode === \"markdown\") {\n // Markdown mode: use raw markdown as description\n sections.push({\n title: \"Release Notes\",\n description: release.release_notes\n });\n } else {\n // Items mode: split into individual items\n const releaseNotesItems = release.release_notes\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n\n sections.push({\n title: \"Release Notes\",\n description: releaseNotesItems.length === 0 ? release.release_notes : undefined,\n items: releaseNotesItems.length > 0 ? releaseNotesItems : undefined\n });\n }\n }\n\n // Add helm charts section\n const charts = release.helm_charts\n ? release.helm_charts\n .filter((chart) => !chart.is_kots_installer_only)\n .map((chart) => `${chart.name} v${chart.version}`)\n : [];\n\n if (charts.length > 0) {\n sections.push({\n title: \"Helm Charts\",\n items: charts,\n description: \"Latest chart versions included in this release.\"\n });\n }\n\n return {\n version: release.label || `Release ${release.release_sequence}`,\n channel: channelName || `Channel ${release.channel_sequence}`,\n releasedAt: release.release_date,\n sections\n };\n}\n","/**\n * Light-weight type helpers for defining Server Actions that align with the\n * enterprise portal guardrails. The component library does not implement\n * specific actions, but it exports helpers so downstream portals can describe\n * their actions with consistent metadata.\n */\n\nimport { Buffer } from \"node:buffer\";\nimport { cache } from \"react\";\nimport { authenticatedFetch } from \"../utils/api-client\";\nimport { traceServerAction } from \"../utils/observability\";\nimport type { License, PortalLicenseField } from \"./fetch-license\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Gets the base API origin from environment, with trailing slashes removed.\n */\nexport const getApiOrigin = (): string => {\n return (process.env.REPLICATED_APP_ORIGIN || \"https://replicated.app\").replace(/\\/+$/, \"\");\n};\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type PortalActionVisibility = \"vendor\" | \"customer\";\n\nexport interface PortalActionContext {\n vendorId: string;\n licenseId: string;\n userId: string;\n signal?: AbortSignal;\n}\n\nexport interface PortalServerActionDefinition<Input, Output> {\n id: string;\n description: string;\n visibility: PortalActionVisibility;\n tags: string[];\n run: (input: Input, context?: PortalActionContext) => Promise<Output>;\n}\n\nexport const defineServerAction = <Input, Output>(\n definition: PortalServerActionDefinition<Input, Output>\n) => definition;\n\nexport interface CreateServiceAccountInput {\n token: string;\n name: string;\n}\n\nexport interface ServiceAccountData {\n id: string;\n customerId: string;\n token: string;\n accountName: string;\n isRevoked: boolean;\n createdAt: string;\n emailAddress: string;\n}\n\nexport interface CreateServiceAccountResult {\n service_account: ServiceAccountData;\n token: string;\n}\n\nexport const createServiceAccount = defineServerAction<\n CreateServiceAccountInput,\n CreateServiceAccountResult\n>({\n id: \"service-account/create\",\n description: \"Creates a service account for installing applications\",\n visibility: \"customer\",\n tags: [\"service-account\", \"install\"],\n async run({ token, name }) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Service account creation requires a session token\");\n }\n\n if (!name || typeof name !== \"string\" || !name.trim()) {\n throw new Error(\"Service account name is required\");\n }\n\n // NEW: Use Enterprise Portal API endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\n \"[portal-components] creating service account via %s (Enterprise Portal API)\",\n endpoint\n );\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ account_name: name.trim() })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Service account creation failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data: CreateServiceAccountResult = await response.json();\n return data;\n }\n});\n\nexport interface InitiateLoginInput {\n email: string;\n}\n\nexport interface InitiateLoginResult {\n status: \"ok\" | \"saml_redirect\";\n requestedAt: string;\n message: string;\n /** If SAML redirect is required, this contains the info needed to redirect */\n saml?: {\n redirectRequired: true;\n customerId: string;\n email: string;\n appSlug: string;\n };\n}\n\n/**\n * Reference server action for initiating the passwordless login flow.\n * Real portals should replace the simulated delay with a call to their auth API.\n */\nexport const initiateLogin = defineServerAction<\n InitiateLoginInput,\n InitiateLoginResult\n>({\n id: \"auth/initiate-login\",\n description:\n \"Begins the passwordless login flow by dispatching a magic link email.\",\n visibility: \"customer\",\n tags: [\"auth\", \"login\", \"session\"],\n async run(input) {\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/magic-link`;\n const appSlug = process.env.PORTAL_APP_SLUG;\n if (!appSlug) {\n throw new Error(\"PORTAL_APP_SLUG is not configured\");\n }\n const portalOrigin =\n process.env.PORTAL_ORIGIN ?? \"https://enterprise.replicated.com\";\n const redirectUri = `${portalOrigin.replace(/\\/+$/, \"\")}/${appSlug}/login`;\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({\n app_slug: appSlug,\n email_address: input.email,\n redirect_uri: redirectUri\n })\n });\n\n if (!response.ok) {\n throw new Error(\n `Magic link request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n\n // Check if SAML redirect is required\n if (data.saml_redirect_required && data.saml_customer_id) {\n return {\n status: \"saml_redirect\",\n requestedAt: new Date().toISOString(),\n message: \"SAML authentication required\",\n saml: {\n redirectRequired: true,\n customerId: data.saml_customer_id,\n email: input.email,\n appSlug\n }\n };\n }\n\n return {\n status: \"ok\",\n requestedAt: new Date().toISOString(),\n message: `Magic link requested for ${input.email}`\n };\n }\n});\n\nexport interface VerifyMagicLinkInput {\n nonce: string;\n}\n\nexport interface VerifyMagicLinkResult {\n token: string;\n raw: unknown;\n}\n\nexport interface VerifyMagicLinkError {\n code: \"invalid_code\" | \"expired\" | \"unknown\";\n message: string;\n isExpired?: boolean;\n}\n\nexport const verifyMagicLink = defineServerAction<\n VerifyMagicLinkInput,\n VerifyMagicLinkResult\n>({\n id: \"auth/verify-magic-link\",\n description: \"Verifies the 12-digit code provided via email and returns a JWT.\",\n visibility: \"customer\",\n tags: [\"auth\", \"login\", \"verify\"],\n async run({ nonce }) {\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/magic-link/verify`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\n \"[portal-components] verifying magic link via %s\",\n endpoint\n );\n }\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ nonce })\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n // Check if the response indicates an expired link\n try {\n const errorBody = await response.json();\n if (errorBody?.is_expired === true) {\n const error: VerifyMagicLinkError = {\n code: \"expired\",\n message: \"Magic link has expired. A new link has been sent to your email.\",\n isExpired: true\n };\n throw error;\n }\n } catch (parseError) {\n // If we already threw an error, re-throw it\n if ((parseError as VerifyMagicLinkError)?.code === \"expired\") {\n throw parseError;\n }\n // Otherwise fall through to invalid_code\n }\n\n const error: VerifyMagicLinkError = {\n code: \"invalid_code\",\n message: \"Incorrect code, check your email and try again.\"\n };\n throw error;\n }\n const error: VerifyMagicLinkError = {\n code: \"unknown\",\n message: `Magic link verification failed (${response.status} ${response.statusText})`\n };\n throw error;\n }\n\n const payload = await response.json();\n const token = payload?.token ?? payload?.jwt ?? payload?.access_token;\n if (typeof token !== \"string\") {\n throw new Error(\"Magic link verification succeeded but no token returned\");\n }\n\n return { token, raw: payload };\n }\n});\n\nexport interface CustomBrandingResponse {\n brandingData: string;\n documentation: unknown;\n}\n\n// License types are now defined in ./fetch-license.ts\n\nexport interface ListSupportBundlesInput {\n token: string;\n}\n\nexport interface SupportBundleInsight {\n level: string;\n primary: string;\n key?: string;\n detail?: string;\n}\n\nexport interface SupportBundleSummary {\n id: string;\n createdAt?: string;\n status?: string;\n size?: number;\n instanceId?: string;\n insights?: SupportBundleInsight[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface ListSupportBundlesResult {\n bundles: SupportBundleSummary[];\n totalCount: number;\n raw: unknown;\n}\n\nexport interface DownloadSupportBundleInput {\n token: string;\n bundleId: string;\n}\n\nexport interface DownloadSupportBundleResult {\n signedUrl: string;\n}\n\nexport interface DeleteSupportBundleInput {\n token: string;\n bundleId: string;\n}\n\nexport interface DeleteSupportBundleResult {\n success: boolean;\n}\n\nexport interface UploadSupportBundleInput {\n token: string;\n appId: string;\n}\n\nexport interface UploadSupportBundleResult {\n uploadUrl: string;\n appId: string;\n}\n\nexport interface UploadSupportBundleCompleteInput {\n token: string;\n appId: string;\n fileContent: ArrayBuffer;\n contentLength: number;\n}\n\nexport interface UploadSupportBundleCompleteResult {\n bundleId: string;\n slug: string;\n}\n\n// Re-export fetchLicense and types from separate file to avoid server-only imports in client bundles\nexport type { License, LicenseChannel, EntitlementField, EntitlementValue, CustomHostnameOverrides, PortalLicenseField } from \"./fetch-license\";\nexport { fetchLicense } from \"./fetch-license\";\n\n// FetchLicense types - kept for backward compatibility\nexport interface FetchLicenseInput {\n // No input needed - gets session internally\n}\n\nexport type FetchLicenseResult = License;\n\n\nexport interface FetchCustomersInput {\n token: string;\n}\n\nexport interface Customer {\n id: string;\n name: string;\n licenseId: string;\n licenseType: string;\n expiresAt: string;\n isEnterprisePortalEnabled: boolean;\n}\n\nexport interface FetchCustomersResult {\n customers: Customer[];\n}\n\nexport interface SwitchCustomerInput {\n token: string;\n customerId: string;\n}\n\nexport interface SwitchCustomerResult {\n token: string;\n}\n\nexport interface ReleaseHelmChart {\n name: string;\n version: string;\n error?: string;\n is_kots_installer_only?: boolean;\n}\n\nexport interface DownloadPortalRelease {\n channel_sequence: number;\n release_sequence: number;\n is_required: boolean;\n has_kurl_installer: boolean;\n release_date: string;\n label: string;\n release_notes: string;\n download_link: string;\n build_status: string;\n last_update_time: string;\n checksum: string;\n airgap_bundle_images: string[];\n helm_images: string[];\n helm_charts: ReleaseHelmChart[];\n target_kots_version: string;\n embedded_cluster_airgap_bundle_url: string;\n has_ec_installer: boolean;\n ec_version: string;\n ec_replicated_app_domain: string;\n ec_proxy_registry_domain: string;\n}\n\nexport interface ListReleasesResult {\n releases: DownloadPortalRelease[];\n totalCount: number;\n}\n\n/**\n * Internal implementation of fetchCustomBranding.\n * Wrapped with React's cache() to deduplicate calls within a single request.\n *\n * Updated to use the new Enterprise Portal API /enterprise-portal/public/branding endpoint\n * which returns clean, non-base64 encoded data.\n */\nconst fetchCustomBrandingImpl = async (): Promise<CustomBrandingResponse> => {\n const appSlug = process.env.PORTAL_APP_SLUG;\n\n if (!appSlug) {\n throw new Error(\"PORTAL_APP_SLUG is not configured\");\n }\n\n const url = `${getApiOrigin()}/enterprise-portal/public/branding?app_slug=${encodeURIComponent(\n appSlug\n )}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\n \"[portal-components] fetching custom branding via %s (Enterprise Portal API)\",\n url\n );\n }\n\n const response = await fetch(url, {\n headers: {\n accept: \"application/json\"\n }\n });\n\n if (!response.ok) {\n throw new Error(\n `Custom branding request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n\n // New Enterprise Portal API returns clean data, not base64 encoded\n // Map the new field names to the old structure for compatibility\n const brandingObject = {\n logo: payload.logoUrl,\n title: payload.title,\n primaryColor: payload.primaryColor,\n secondaryColor: payload.secondaryColor,\n favicon: payload.faviconUrl,\n supportPortalLink: payload.supportPortalLink || \"\",\n background: payload.background,\n backgroundImage: payload.backgroundImage,\n customColor1: payload.customColor1,\n customColor2: payload.customColor2,\n };\n\n // Encode to base64 to maintain compatibility with existing decodeBranding function\n const brandingData = Buffer.from(JSON.stringify(brandingObject)).toString(\"base64\");\n\n return {\n brandingData,\n documentation: null // Documentation not included in new API's public endpoint\n };\n};\n\n/**\n * Fetches custom branding for the portal.\n * This function is cached per-request to avoid duplicate API calls when called\n * from multiple components (e.g., TopNav and page components).\n */\nexport const fetchCustomBranding = cache(fetchCustomBrandingImpl);\n\nexport const decodeJwtPayload = (token: string): Record<string, unknown> => {\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n throw new Error(\"Invalid JWT received\");\n }\n\n const payloadSegment = parts[1];\n if (!payloadSegment) {\n throw new Error(\"JWT payload segment missing\");\n }\n\n const padded = payloadSegment.padEnd(\n payloadSegment.length + ((4 - (payloadSegment.length % 4)) % 4),\n \"=\"\n );\n const decoded = Buffer.from(padded, \"base64\").toString(\"utf-8\");\n return JSON.parse(decoded) as Record<string, unknown>;\n};\n\n/**\n * Extracts customer ID from JWT token. Throws if extraction fails.\n */\nexport const getCustomerIdFromToken = (token: string): string => {\n const payload = decodeJwtPayload(token);\n const customerId = payload?.customer_id || payload?.customerId;\n if (typeof customerId !== \"string\" || !customerId.trim()) {\n throw new Error(\"Unable to determine customer_id from session token\");\n }\n return customerId.trim();\n};\n\nconst resolveSupportBundlesEndpoint = () => {\n const fallback = `${getApiOrigin()}/v3/supportbundles`;\n const explicit = process.env.SUPPORT_BUNDLES_ENDPOINT;\n\n if (!explicit) {\n return new URL(fallback);\n }\n\n try {\n return new URL(explicit);\n } catch (error) {\n console.warn(\n `[portal-components] invalid SUPPORT_BUNDLES_ENDPOINT, using fallback`,\n error\n );\n return new URL(fallback);\n }\n};\n\nexport const listSupportBundles = defineServerAction<\n ListSupportBundlesInput,\n ListSupportBundlesResult\n>({\n id: \"support/list-bundles\",\n description:\n \"Fetches support bundles associated with the customer found in the portal session JWT.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle listing requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const url = `${getApiOrigin()}/enterprise-portal/support-bundles`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching support bundles via %s (Enterprise Portal API)\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (context?.signal?.aborted) {\n throw new Error(\"Support bundles request was aborted\");\n }\n\n if (!response.ok) {\n throw new Error(\n `Support bundles request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n // Extract from Enterprise Portal API envelope\n const raw = payload.data;\n\n const rawRecord =\n raw && typeof raw === \"object\" ? (raw as Record<string, unknown>) : undefined;\n\n const parseInsights = (raw: unknown): SupportBundleInsight[] | undefined => {\n if (!Array.isArray(raw)) return undefined;\n return raw\n .filter((i): i is Record<string, unknown> => i && typeof i === \"object\")\n .map((i) => ({\n level: String(i.level ?? \"\"),\n primary: String(i.primary ?? \"\"),\n key: typeof i.key === \"string\" ? i.key : undefined,\n detail: typeof i.detail === \"string\" ? i.detail : undefined\n }));\n };\n\n const bundles: SupportBundleSummary[] = Array.isArray(\n rawRecord?.supportBundles\n )\n ? (rawRecord?.supportBundles as unknown[]).map((item) => {\n if (!item || typeof item !== \"object\") {\n return {\n id: \"\",\n createdAt: undefined,\n status: undefined,\n size: undefined,\n instanceId: undefined,\n insights: undefined,\n metadata: undefined\n };\n }\n\n const record = item as Record<string, unknown>;\n return {\n id: String(record.id ?? \"\"),\n createdAt:\n typeof record.createdAt === \"string\"\n ? (record.createdAt as string)\n : undefined,\n status:\n typeof record.status === \"string\"\n ? (record.status as string)\n : undefined,\n size:\n typeof record.size === \"number\"\n ? record.size\n : undefined,\n instanceId:\n typeof record.instanceId === \"string\"\n ? record.instanceId\n : undefined,\n insights: parseInsights(record.insights),\n metadata: record\n };\n })\n : Array.isArray(raw)\n ? (raw as unknown[]).map((item) => {\n if (!item || typeof item !== \"object\") {\n return {\n id: \"\",\n createdAt: undefined,\n status: undefined,\n size: undefined,\n instanceId: undefined,\n insights: undefined,\n metadata: undefined\n };\n }\n const record = item as Record<string, unknown>;\n return {\n id: String(record.id ?? \"\"),\n createdAt:\n typeof record.createdAt === \"string\"\n ? (record.createdAt as string)\n : undefined,\n status:\n typeof record.status === \"string\"\n ? (record.status as string)\n : undefined,\n size:\n typeof record.size === \"number\"\n ? record.size\n : undefined,\n instanceId:\n typeof record.instanceId === \"string\"\n ? record.instanceId\n : undefined,\n insights: parseInsights(record.insights),\n metadata: record\n };\n })\n : [];\n\n const totalCount = (() => {\n if (rawRecord) {\n if (\n typeof rawRecord.totalCount === \"number\" &&\n Number.isFinite(rawRecord.totalCount)\n ) {\n return rawRecord.totalCount;\n }\n if (Array.isArray(rawRecord.supportBundles)) {\n return rawRecord.supportBundles.length;\n }\n }\n\n if (Array.isArray(raw)) {\n return raw.length;\n }\n\n return bundles.length;\n })();\n\n return {\n bundles,\n totalCount,\n raw\n };\n }\n});\n\nexport const downloadSupportBundle = defineServerAction<\n DownloadSupportBundleInput,\n DownloadSupportBundleResult\n>({\n id: \"support/download-bundle\",\n description: \"Gets a signed URL for downloading a support bundle.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\", \"download\"],\n async run({ token, bundleId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle download requires a session token\");\n }\n\n if (!bundleId || typeof bundleId !== \"string\") {\n throw new Error(\"Support bundle download requires a bundle ID\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/${encodeURIComponent(bundleId)}/download?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] getting support bundle download URL via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Support bundle download URL request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data = await response.json();\n const signedUrl = data?.signedUrl;\n\n if (typeof signedUrl !== \"string\" || !signedUrl) {\n throw new Error(\"Support bundle download response missing signedUrl\");\n }\n\n return { signedUrl };\n }\n});\n\nexport const deleteSupportBundle = defineServerAction<\n DeleteSupportBundleInput,\n DeleteSupportBundleResult\n>({\n id: \"support/delete-bundle\",\n description: \"Deletes a support bundle.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\", \"delete\"],\n async run({ token, bundleId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle deletion requires a session token\");\n }\n\n if (!bundleId || typeof bundleId !== \"string\") {\n throw new Error(\"Support bundle deletion requires a bundle ID\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/${encodeURIComponent(bundleId)}?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] deleting support bundle via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n if (response.status === 404) {\n throw new Error(\"Support bundle not found\");\n }\n throw new Error(\n `Support bundle deletion failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n return { success: true };\n }\n});\n\nexport const uploadSupportBundle = defineServerAction<\n UploadSupportBundleCompleteInput,\n UploadSupportBundleCompleteResult\n>({\n id: \"support/upload-bundle\",\n description: \"Uploads a support bundle to the server.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\", \"upload\"],\n async run({ token, appId, fileContent, contentLength }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle upload requires a session token\");\n }\n\n if (!appId || typeof appId !== \"string\") {\n throw new Error(\"Support bundle upload requires an app ID\");\n }\n\n if (!fileContent || !(fileContent instanceof ArrayBuffer)) {\n throw new Error(\"Support bundle upload requires file content\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] uploading support bundle via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: {\n \"content-type\": \"application/gzip\",\n \"content-length\": String(contentLength)\n },\n body: fileContent,\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Support bundle upload failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data = await response.json();\n\n return {\n bundleId: data?.bundleId ?? data?.bundle_id ?? \"\",\n slug: data?.slug ?? \"\"\n };\n }\n});\n\n/**\n * Helper to get the upload endpoint URL for client-side uploads with progress tracking.\n * Use this when you need progress indication - call this to get the URL, then upload directly from client.\n */\nexport const getSupportBundleUploadUrl = (appId: string): string => {\n return `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;\n};\n\nasync function listReleasesImpl(): Promise<ListReleasesResult> {\n const { cookies } = await import(\"next/headers\");\n const sessionStore = await cookies();\n const session = sessionStore.get(\"portal_session\");\n const token = session?.value;\n\n if (!token) {\n throw new Error(\"List releases requires a session token\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/releases`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching releases via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n }\n });\n\n if (!response.ok) {\n throw new Error(\n `List releases request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n const data = envelope.data;\n\n return {\n releases: Array.isArray(data?.releases) ? data.releases : [],\n totalCount: data?.totalCount || 0\n };\n}\n\nexport const listReleases = traceServerAction(\"listReleases\", listReleasesImpl);\n\nconst asRecord = (value: unknown): Record<string, unknown> | undefined => {\n if (value && typeof value === \"object\") {\n return value as Record<string, unknown>;\n }\n return undefined;\n};\n\nconst getValue = (\n record: Record<string, unknown> | undefined,\n key: string\n) => (record ? record[key] : undefined);\n\nconst getString = (\n record: Record<string, unknown> | undefined,\n key: string\n): string | undefined => {\n const value = getValue(record, key);\n return typeof value === \"string\" ? value : undefined;\n};\n\nconst getBoolean = (\n record: Record<string, unknown> | undefined,\n key: string\n): boolean | undefined => {\n const value = getValue(record, key);\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value === 1;\n }\n if (typeof value === \"string\") {\n const normalized = value.trim().toLowerCase();\n if ([\"true\", \"1\", \"yes\"].includes(normalized)) {\n return true;\n }\n if ([\"false\", \"0\", \"no\"].includes(normalized)) {\n return false;\n }\n }\n return undefined;\n};\n\nconst toDisplayValue = (value: unknown): string | null => {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\nconst normalizeStringArray = (value: unknown): string[] | undefined => {\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) =>\n typeof item === \"string\" ? item.trim() : \"\"\n )\n .filter((item) => item.length > 0);\n return normalized.length ? normalized : undefined;\n }\n\n if (typeof value === \"string\") {\n const normalized = value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n return normalized.length ? normalized : undefined;\n }\n\n return undefined;\n};\n\nconst normalizeLicenseFields = (input: unknown): PortalLicenseField[] => {\n if (!input) {\n return [];\n }\n\n if (Array.isArray(input)) {\n return input\n .map((field, index) => {\n if (!field || typeof field !== \"object\") {\n return null;\n }\n const candidate = field as Record<string, unknown>;\n const key =\n typeof candidate.key === \"string\" && candidate.key.trim().length\n ? candidate.key.trim()\n : typeof candidate.name === \"string\" && candidate.name.trim().length\n ? candidate.name.trim()\n : typeof candidate.label === \"string\" && candidate.label.trim().length\n ? candidate.label.trim()\n : `field-${index}`;\n const label =\n typeof candidate.label === \"string\" && candidate.label.trim().length\n ? candidate.label.trim()\n : typeof candidate.name === \"string\" && candidate.name.trim().length\n ? candidate.name.trim()\n : key;\n let value: unknown =\n candidate.value ?? candidate.data ?? candidate.content;\n if (\n (value === undefined || value === null) &&\n typeof candidate.text === \"string\"\n ) {\n value = candidate.text;\n }\n if (\n (value === undefined || value === null) &&\n typeof candidate.defaultValue === \"string\"\n ) {\n value = candidate.defaultValue;\n }\n const isSecret = Boolean(\n candidate.isSecret ?? candidate.secret ?? candidate.masked\n );\n const resolved = toDisplayValue(value);\n return {\n key,\n label,\n value: resolved,\n isSecret\n } as PortalLicenseField;\n })\n .filter((field): field is PortalLicenseField => Boolean(field));\n }\n\n if (typeof input === \"object\") {\n return Object.entries(input as Record<string, unknown>).map(\n ([key, value]) => {\n let resolvedValue: unknown = value;\n let isSecret = false;\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n if (\"value\" in obj) {\n resolvedValue = obj.value;\n }\n isSecret = Boolean(obj.isSecret ?? obj.secret ?? obj.masked);\n }\n const normalized = toDisplayValue(resolvedValue);\n return {\n key,\n label: key,\n value: normalized,\n isSecret\n };\n }\n );\n }\n\n return [];\n};\n\nconst extractChannelNames = (input: unknown): string[] | undefined => {\n if (!Array.isArray(input)) {\n return undefined;\n }\n const names = input\n .map((item) => {\n if (typeof item === \"string\") {\n return item.trim();\n }\n const record = asRecord(item);\n if (!record) {\n return null;\n }\n return (\n getString(record, \"name\") ??\n getString(record, \"channelName\") ??\n getString(record, \"channel\") ??\n getString(record, \"channelSlug\") ??\n getString(record, \"slug\") ??\n undefined\n );\n })\n .filter((name): name is string => Boolean(name && name.length));\n return names.length ? names : undefined;\n};\n\n// fetchLicense and helper functions are now defined in ./fetch-license.ts to avoid server-only imports in client bundles\n\nexport const fetchCustomers = defineServerAction<\n FetchCustomersInput,\n FetchCustomersResult\n>({\n id: \"auth/fetch-customers\",\n description: \"Fetches the list of customers/teams for the authenticated user.\",\n visibility: \"customer\",\n tags: [\"auth\", \"customers\"],\n async run({ token }, context) {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"fetchCustomers requires a non-empty token\");\n }\n\n // NEW: Use Enterprise Portal API /user endpoint (returns customers + user profile)\n const endpoint = `${getApiOrigin()}/enterprise-portal/user`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching customers via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch customers request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n const userData = envelope.data;\n\n return {\n customers: userData?.customers || []\n };\n }\n});\n\nexport const switchCustomer = defineServerAction<\n SwitchCustomerInput,\n SwitchCustomerResult\n>({\n id: \"auth/switch-customer\",\n description: \"Switches the JWT to a different customer/team.\",\n visibility: \"customer\",\n tags: [\"auth\", \"customers\"],\n async run({ token, customerId }, context) {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"switchCustomer requires a non-empty token\");\n }\n \n if (typeof customerId !== \"string\" || customerId.trim().length === 0) {\n throw new Error(\"switchCustomer requires a non-empty customerId\");\n }\n\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/switch-team`;\n\n const requestBody = { customer_id: customerId };\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify(requestBody),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error('[portal-components] switchCustomer error response:', errorText);\n throw new Error(\n `Switch customer request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const payload = await response.json();\n\n // API returns 'jwt' field, not 'token'\n const newToken = payload.jwt || payload.token || token;\n \n return {\n token: newToken\n };\n }\n});\n\n// =============================================================================\n// Security Types\n// =============================================================================\n\nexport type SecurityInstallType = \"linux\" | \"helm\";\n\nexport interface SecurityScanSummary {\n critical: Record<string, string>;\n high: Record<string, string>;\n medium: Record<string, string>;\n low: Record<string, string>;\n}\n\nexport interface SecurityScanWrapper {\n input: string;\n digest?: string;\n last_scanned_at?: string;\n result: SecurityScanSummary;\n not_found?: boolean;\n}\n\nexport interface SecurityReleaseImage {\n image: string;\n sha: string;\n size: number;\n platforms: { os: string; architecture: string }[];\n security?: SecurityScanWrapper;\n}\n\nexport interface GetSecurityInfoInput {\n token: string;\n installType: SecurityInstallType;\n channelSequence: number;\n isAirgap?: boolean;\n}\n\nexport interface GetSecurityInfoResult {\n images: SecurityReleaseImage[];\n activeInstancesByVersion?: Record<string, number>;\n}\n\nexport interface SecurityInfoDiff {\n oldTags: string[];\n newTags: string[];\n oldVulns?: SecurityScanSummary;\n newVulns?: SecurityScanSummary;\n added?: SecurityScanSummary;\n removed?: SecurityScanSummary;\n}\n\nexport interface GetSecurityInfoDiffInput {\n token: string;\n installType: SecurityInstallType;\n fromChannelSequence: number;\n toChannelSequence: number;\n isAirgap?: boolean;\n}\n\nexport interface GetSecurityInfoDiffResult {\n from_channel_sequence: number;\n to_channel_sequence: number;\n images: Record<string, SecurityInfoDiff>;\n}\n\nexport interface SBOMMetadata {\n name: string;\n spdxVersion: string;\n packageCount: number;\n fileCount: number;\n created?: string;\n creator?: string;\n source?: string;\n}\n\nexport interface GetSecurityInfoSBOMInput {\n token: string;\n installType: SecurityInstallType;\n channelSequence: number;\n isAirgap?: boolean;\n unifiedSbom?: boolean;\n}\n\nexport interface GetSecurityInfoSBOMResult {\n sboms: {\n unified?: SBOMMetadata;\n };\n}\n\nexport interface DownloadSBOMInput {\n token: string;\n installType: SecurityInstallType;\n channelSequence: number;\n isAirgap?: boolean;\n}\n\n// =============================================================================\n// Security Actions\n// =============================================================================\n\n/**\n * Fetches security scan (CVE) information for a specific release.\n */\nexport const getSecurityInfo = defineServerAction<\n GetSecurityInfoInput,\n GetSecurityInfoResult\n>({\n id: \"security/get-info\",\n description: \"Fetches CVE security scan results for a specific release\",\n visibility: \"customer\",\n tags: [\"security\", \"cve\"],\n async run({ token, installType, channelSequence, isAirgap = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security info request requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n install_type: installType,\n channel_sequence: channelSequence.toString(),\n is_airgap: isAirgap.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching security info via %s (Enterprise Portal API)\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Security info request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n // Extract from Enterprise Portal API envelope\n return payload.data as GetSecurityInfoResult;\n }\n});\n\n/**\n * Fetches security diff between two releases (fixed/added CVEs).\n */\nexport const getSecurityInfoDiff = defineServerAction<\n GetSecurityInfoDiffInput,\n GetSecurityInfoDiffResult\n>({\n id: \"security/get-info-diff\",\n description: \"Fetches CVE diff between two releases showing fixed and added vulnerabilities\",\n visibility: \"customer\",\n tags: [\"security\", \"cve\", \"diff\"],\n async run({ token, installType, fromChannelSequence, toChannelSequence, isAirgap = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security info diff request requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n install_type: installType,\n from_channel_sequence: fromChannelSequence.toString(),\n to_channel_sequence: toChannelSequence.toString(),\n is_airgap: isAirgap.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security-diff?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching security info diff via %s\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Security info diff request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n // Extract from Enterprise Portal API envelope\n return envelope.data as GetSecurityInfoDiffResult;\n }\n});\n\n/**\n * Fetches SBOM (Software Bill of Materials) for a specific release.\n */\nexport const getSecurityInfoSBOM = defineServerAction<\n GetSecurityInfoSBOMInput,\n GetSecurityInfoSBOMResult\n>({\n id: \"security/get-sbom\",\n description: \"Fetches Software Bill of Materials (SBOM) for a specific release\",\n visibility: \"customer\",\n tags: [\"security\", \"sbom\"],\n async run({ token, installType, channelSequence, isAirgap = false, unifiedSbom = true }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security SBOM request requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n install_type: installType,\n channel_sequence: channelSequence.toString(),\n is_airgap: isAirgap.toString(),\n unified_sbom: unifiedSbom.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security-sbom?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching security SBOM via %s\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n // Handle 204 No Content response\n if (response.status === 204) {\n return { sboms: {} };\n }\n\n if (!response.ok) {\n throw new Error(\n `Security SBOM request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n // Extract from Enterprise Portal API envelope\n return envelope.data as GetSecurityInfoSBOMResult;\n }\n});\n\n/**\n * Downloads the full SBOM file for a specific release.\n * Returns a download URL that can be used to fetch the SBOM.\n */\nexport const downloadSecuritySBOM = defineServerAction<\n DownloadSBOMInput,\n string\n>({\n id: \"security/download-sbom\",\n description: \"Downloads the full SBOM file for a specific release\",\n visibility: \"customer\",\n tags: [\"security\", \"sbom\", \"download\"],\n async run({ token, installType, channelSequence, isAirgap = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security SBOM download requires a session token\");\n }\n\n const params = new URLSearchParams({\n install_type: installType,\n channel_sequence: channelSequence.toString(),\n is_airgap: isAirgap.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security-sbom/download?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] downloading security SBOM via %s\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Security SBOM download failed (${response.status} ${response.statusText})`\n );\n }\n\n // Return the SBOM content directly as a string\n // The client will create the blob URL in the browser context\n return await response.text();\n }\n});\n\n// =============================================================================\n// Dashboard Types\n// =============================================================================\n\nexport interface FetchTeamStatsInput {\n token: string;\n}\n\nexport interface TeamUser {\n id: string;\n email: string;\n name?: string;\n createdAt?: string;\n}\n\nexport interface ServiceAccountSummary {\n id: string;\n accountName: string;\n customerId: string;\n isRevoked: boolean;\n createdAt: string;\n}\n\nexport interface FetchTeamStatsResult {\n userCount: number;\n serviceAccountCount: number;\n}\n\nexport interface FetchDashboardInstancesInput {\n token: string;\n}\n\nexport interface FetchDashboardInstancesResult {\n onlineActiveCount: number;\n airgapCount: number;\n onlineUpdates: number;\n airgapUpdates: number;\n // NEW: Additional data from composite endpoint\n license?: {\n type: string;\n expiresAt: string | null;\n isEmbeddedClusterDownloadEnabled: boolean;\n isHelmInstallEnabled: boolean;\n };\n teamStats?: {\n userCount: number;\n serviceAccountCount: number;\n supportBundleCount: number;\n };\n}\n\n// =============================================================================\n// Dashboard Actions\n// =============================================================================\n\n/**\n * NEW: Fetches all dashboard data using the composite Enterprise Portal API endpoint.\n * This replaces multiple v3 calls with a single call that returns:\n * - Instances\n * - Channel releases (for calculating updates)\n * - Notifications\n * - User/app/branding context\n */\nexport const fetchDashboardComposite = defineServerAction<\n FetchDashboardInstancesInput,\n FetchDashboardInstancesResult\n>({\n id: \"dashboard/fetch-composite\",\n description: \"Fetches all dashboard data from the composite Enterprise Portal API endpoint\",\n visibility: \"customer\",\n tags: [\"dashboard\", \"enterprise-portal-api\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Dashboard request requires a session token\");\n }\n\n const origin = getApiOrigin();\n const url = `${origin}/enterprise-portal/dashboard`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching dashboard via %s (Enterprise Portal API)\", url);\n }\n\n const response = await authenticatedFetch(url, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Dashboard request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n\n // Extract data from the Enterprise Portal API envelope\n const data = payload.data;\n const allInstances = data?.instances || [];\n const channelReleases = data?.channelReleases || [];\n const licenseData = data?.license || {};\n const teamStats = data?.teamStats || {};\n\n // Split into online and airgap\n const onlineInstances = allInstances.filter((i: { isAirgap?: boolean }) => !i.isAirgap);\n const airgapInstances = allInstances.filter((i: { isAirgap?: boolean }) => i.isAirgap);\n\n // Filter to active online instances (checked in within 24 hours)\n const twentyFourHoursAgo = Date.now() - 24 * 60 * 60 * 1000;\n const activeOnlineInstances = onlineInstances.filter((instance: { lastCheckin?: string }) => {\n const lastCheckin = instance.lastCheckin\n ? new Date(instance.lastCheckin).getTime()\n : 0;\n return lastCheckin > twentyFourHoursAgo;\n });\n\n const onlineActiveCount = activeOnlineInstances.length;\n const airgapCount = airgapInstances.length;\n\n // Calculate updates for active online instances\n const calculateUpdates = (instances: Array<{ channelId?: string; channelSequence?: number }>) => {\n if (!channelReleases.length) return 0;\n\n let numUpdates = 0;\n for (const instance of instances) {\n const instanceSequence = instance.channelSequence ?? 0;\n const matchingReleases = channelReleases.filter(\n (release: { channelId?: string; channelSequence?: number }) => release.channelId === instance.channelId\n );\n for (const release of matchingReleases) {\n if ((release.channelSequence ?? 0) > instanceSequence) {\n numUpdates++;\n }\n }\n }\n return numUpdates;\n };\n\n const onlineUpdates = calculateUpdates(activeOnlineInstances);\n const airgapUpdates = calculateUpdates(airgapInstances);\n\n // Store the composite data for other dashboard components to use\n // This allows us to eliminate the separate fetchTeamStats, fetchLicenseSummary, and fetchInstallOptions calls\n return {\n onlineActiveCount,\n airgapCount,\n onlineUpdates,\n airgapUpdates,\n // Additional data available from the composite endpoint\n license: licenseData,\n teamStats: teamStats\n };\n }\n});\n\n/**\n * Fetches team statistics including user count and service account count.\n * Used by the Team Settings dashboard card.\n */\nexport const fetchTeamStats = defineServerAction<\n FetchTeamStatsInput,\n FetchTeamStatsResult\n>({\n id: \"dashboard/fetch-team-stats\",\n description: \"Fetches user and service account counts for the dashboard\",\n visibility: \"customer\",\n tags: [\"dashboard\", \"team\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Team stats request requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n // Fetch users count\n let userCount = 0;\n try {\n const usersUrl = `${origin}/v3/users?exclude_invites=false&customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching team users via %s\", usersUrl);\n }\n\n const usersResponse = await authenticatedFetch(usersUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (usersResponse.ok) {\n const usersData = await usersResponse.json();\n userCount = Array.isArray(usersData.users) ? usersData.users.length : 0;\n }\n } catch (error) {\n console.error(\"[portal-components] Error fetching users:\", error);\n }\n\n // Fetch service accounts count\n let serviceAccountCount = 0;\n try {\n const saUrl = `${origin}/v3/service-accounts?customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching service accounts via %s\", saUrl);\n }\n\n const saResponse = await authenticatedFetch(saUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (saResponse.ok) {\n const saData = await saResponse.json();\n serviceAccountCount = Array.isArray(saData.serviceAccounts) \n ? saData.serviceAccounts.length \n : 0;\n }\n } catch (error) {\n console.error(\"[portal-components] Error fetching service accounts:\", error);\n }\n\n return {\n userCount,\n serviceAccountCount\n };\n }\n});\n\n/**\n * Fetches instance counts and available updates for the dashboard.\n * Used by the Updates dashboard card.\n */\nexport const fetchDashboardInstances = defineServerAction<\n FetchDashboardInstancesInput,\n FetchDashboardInstancesResult\n>({\n id: \"dashboard/fetch-instances\",\n description: \"Fetches instance counts and update availability for the dashboard\",\n visibility: \"customer\",\n tags: [\"dashboard\", \"instances\", \"updates\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Dashboard instances request requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n // Fetch instances\n const instancesUrl = `${origin}/v3/instances?customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching instances via %s\", instancesUrl);\n }\n\n const instancesResponse = await authenticatedFetch(instancesUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!instancesResponse.ok) {\n throw new Error(\n `Instances request failed (${instancesResponse.status} ${instancesResponse.statusText})`\n );\n }\n\n const instancesData = await instancesResponse.json();\n const allInstances = instancesData.instances || [];\n\n // Split into online and airgap\n const onlineInstances = allInstances.filter((i: { isAirgap?: boolean }) => !i.isAirgap);\n const airgapInstances = allInstances.filter((i: { isAirgap?: boolean }) => i.isAirgap);\n\n // Filter to active online instances (checked in within 24 hours)\n const twentyFourHoursAgo = Date.now() - 24 * 60 * 60 * 1000;\n const activeOnlineInstances = onlineInstances.filter((instance: { lastCheckin?: string }) => {\n const lastCheckin = instance.lastCheckin \n ? new Date(instance.lastCheckin).getTime() \n : 0;\n return lastCheckin > twentyFourHoursAgo;\n });\n\n const onlineActiveCount = activeOnlineInstances.length;\n const airgapCount = airgapInstances.length;\n\n // Fetch channel releases to calculate updates\n let channelReleases: Array<{ channelId: string; channelSequence: number }> = [];\n try {\n const releasesUrl = `${origin}/v3/channel-releases?customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching channel releases via %s\", releasesUrl);\n }\n\n const releasesResponse = await authenticatedFetch(releasesUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (releasesResponse.ok) {\n const releasesData = await releasesResponse.json();\n channelReleases = releasesData.channelReleases || [];\n }\n } catch (error) {\n console.error(\"[portal-components] Error fetching channel releases:\", error);\n }\n\n // Calculate updates for active online instances\n const calculateUpdates = (instances: Array<{ channelId?: string; channelSequence?: number }>) => {\n if (!channelReleases.length) return 0;\n \n let numUpdates = 0;\n for (const instance of instances) {\n const instanceSequence = instance.channelSequence ?? 0;\n const matchingReleases = channelReleases.filter(\n (release) => release.channelId === instance.channelId\n );\n for (const release of matchingReleases) {\n if (release.channelSequence > instanceSequence) {\n numUpdates++;\n }\n }\n }\n return numUpdates;\n };\n\n const onlineUpdates = calculateUpdates(activeOnlineInstances);\n const airgapUpdates = calculateUpdates(airgapInstances);\n\n return {\n onlineActiveCount,\n airgapCount,\n onlineUpdates,\n airgapUpdates\n };\n }\n});\n\n// =============================================================================\n// User Settings Types\n// =============================================================================\n\nexport interface FetchCurrentUserInput {\n token: string;\n}\n\nexport interface UserProfile {\n emailAddress: string;\n firstName: string;\n lastName: string;\n}\n\nexport interface FetchCurrentUserResult {\n user: UserProfile;\n}\n\nexport interface UpdateUserInput {\n token: string;\n firstName?: string;\n lastName?: string;\n}\n\nexport interface UpdateUserResult {\n success: boolean;\n}\n\nexport interface NotificationSetting {\n type: string;\n enabled: boolean;\n}\n\nexport interface FetchNotificationsInput {\n token: string;\n customerId: string;\n}\n\nexport interface FetchNotificationsResult {\n notifications: NotificationSetting[];\n}\n\nexport interface UpdateNotificationsInput {\n token: string;\n customerId: string;\n notifications: NotificationSetting[];\n}\n\nexport interface UpdateNotificationsResult {\n notifications: NotificationSetting[];\n}\n\n// =============================================================================\n// User Settings Actions\n// =============================================================================\n\n/**\n * Fetches the current user's profile information.\n */\nexport const fetchCurrentUser = defineServerAction<\n FetchCurrentUserInput,\n FetchCurrentUserResult\n>({\n id: \"user/fetch-current\",\n description: \"Fetches the current user's profile information\",\n visibility: \"customer\",\n tags: [\"user\", \"profile\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch current user requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/profile`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching current user via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch current user request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n user: {\n emailAddress: data.emailAddress || \"\",\n firstName: data.firstName || \"\",\n lastName: data.lastName || \"\"\n }\n };\n }\n});\n\n/**\n * Updates the current user's profile information.\n */\nexport const updateUser = defineServerAction<\n UpdateUserInput,\n UpdateUserResult\n>({\n id: \"user/update\",\n description: \"Updates the current user's first and/or last name\",\n visibility: \"customer\",\n tags: [\"user\", \"profile\"],\n async run({ token, firstName, lastName }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Update user requires a session token\");\n }\n\n if (!firstName && !lastName) {\n throw new Error(\"At least one of firstName or lastName must be provided\");\n }\n\n // NEW: Use Enterprise Portal API endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/profile`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] updating user via %s\", endpoint);\n }\n\n const body: { firstName?: string; lastName?: string } = {};\n if (firstName !== undefined) body.firstName = firstName;\n if (lastName !== undefined) body.lastName = lastName;\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify(body),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Update user request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n return { success: true };\n }\n});\n\n/**\n * Fetches notification preferences for a specific customer/team.\n */\nexport const fetchNotifications = defineServerAction<\n FetchNotificationsInput,\n FetchNotificationsResult\n>({\n id: \"notifications/fetch\",\n description: \"Fetches notification preferences for a specific team\",\n visibility: \"customer\",\n tags: [\"notifications\", \"user\"],\n async run({ token, customerId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch notifications requires a session token\");\n }\n\n if (!customerId || typeof customerId !== \"string\") {\n throw new Error(\"Fetch notifications requires a valid customerId\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/notifications?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching notifications via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch notifications request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n notifications: data.notifications || []\n };\n }\n});\n\n/**\n * Updates notification preferences for a specific customer/team.\n */\nexport const updateNotifications = defineServerAction<\n UpdateNotificationsInput,\n UpdateNotificationsResult\n>({\n id: \"notifications/update\",\n description: \"Updates notification preferences for a specific team\",\n visibility: \"customer\",\n tags: [\"notifications\", \"user\"],\n async run({ token, customerId, notifications }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Update notifications requires a session token\");\n }\n\n if (!customerId || typeof customerId !== \"string\") {\n throw new Error(\"Update notifications requires a valid customerId\");\n }\n\n if (!Array.isArray(notifications)) {\n throw new Error(\"Update notifications requires a notifications array\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/notifications?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] updating notifications via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ notifications }),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Update notifications request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data = await response.json();\n \n return {\n notifications: data.notifications || []\n };\n }\n});\n\n// =============================================================================\n// Team Settings Types\n// =============================================================================\n\nexport interface TeamUser {\n id: string;\n emailAddress: string;\n firstAccessedAt?: string;\n lastAccessedAt?: string;\n viewCount?: number;\n pendingInvite: boolean;\n}\n\nexport interface FetchTeamUsersInput {\n token: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface FetchTeamUsersResult {\n users: TeamUser[];\n total: number;\n}\n\nexport interface InviteUserInput {\n token: string;\n email: string;\n}\n\nexport interface InviteUserResult {\n success: boolean;\n}\n\nexport interface DeleteUserInput {\n token: string;\n id: string;\n isPendingInvite: boolean; // If true, delete invite; if false, delete user\n}\n\nexport interface DeleteUserResult {\n success: boolean;\n}\n\nexport interface ServiceAccount {\n id: string;\n customerId: string;\n accountName: string;\n emailAddress?: string;\n token: string;\n isRevoked: boolean;\n createdAt: string;\n lastUsedAt?: string;\n tokenRegeneratedAt?: string;\n}\n\nexport interface FetchServiceAccountsInput {\n token: string;\n limit?: number;\n offset?: number;\n includeRevoked?: boolean;\n}\n\nexport interface FetchServiceAccountsResult {\n serviceAccounts: ServiceAccount[];\n total: number;\n}\n\nexport interface RevokeServiceAccountInput {\n token: string;\n accountId: string;\n}\n\nexport interface RevokeServiceAccountResult {\n success: boolean;\n}\n\nexport interface RotateServiceAccountTokenInput {\n token: string;\n accountId: string;\n}\n\nexport interface RotateServiceAccountTokenResult {\n serviceAccount: ServiceAccount;\n helmLoginCommand: string;\n redeployHelm: string[];\n}\n\nexport interface Instance {\n id: string;\n serviceAccountId?: string;\n versionLabel?: string;\n channelId?: string;\n channelSequence?: number;\n lastCheckin?: string;\n isAirgap?: boolean;\n embeddedClusterVersion?: string;\n tags?: Array<{ key: string; value: string }>;\n}\n\nexport interface FetchInstancesInput {\n token: string;\n}\n\nexport interface FetchInstancesResult {\n instances: Instance[];\n}\n\nexport interface SAMLConfig {\n samlAllowed: boolean;\n samlEnabled: boolean;\n entityId: string;\n acsUrl: string;\n hasIdpMetadata: boolean;\n hasIdpCert: boolean;\n}\n\nexport interface FetchSamlConfigInput {\n token: string;\n}\n\nexport interface FetchSamlConfigResult {\n config: SAMLConfig;\n}\n\nexport interface UpdateSamlConfigInput {\n token: string;\n idpMetadataXml: string;\n idpPublicCert: string;\n}\n\nexport interface UpdateSamlConfigResult {\n success: boolean;\n}\n\nexport interface ToggleSamlEnabledInput {\n token: string;\n enabled: boolean;\n}\n\nexport interface ToggleSamlEnabledResult {\n success: boolean;\n samlEnabled: boolean;\n}\n\nexport interface DeprovisionSamlInput {\n token: string;\n}\n\nexport interface DeprovisionSamlResult {\n success: boolean;\n}\n\n// =============================================================================\n// Team Settings Actions\n// =============================================================================\n\n/**\n * Fetches the list of users for a team.\n */\nexport const fetchTeamUsers = defineServerAction<\n FetchTeamUsersInput,\n FetchTeamUsersResult\n>({\n id: \"team/fetch-users\",\n description: \"Fetches paginated list of team users and pending invites\",\n visibility: \"customer\",\n tags: [\"team\", \"users\"],\n async run({ token, limit = 25, offset = 0 }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch team users requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n // NEW: Use Enterprise Portal API endpoint\n // Note: v3 handler still requires customer_id in query params for validation\n const params = new URLSearchParams({\n customer_id: customerId,\n limit: limit.toString(),\n offset: offset.toString()\n });\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/users?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching team users via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch team users request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n users: data.users || [],\n total: data.total || 0\n };\n }\n});\n\n/**\n * Invites a user to the team.\n */\nexport const inviteUser = defineServerAction<\n InviteUserInput,\n InviteUserResult\n>({\n id: \"team/invite-user\",\n description: \"Sends an invitation email to join the team\",\n visibility: \"customer\",\n tags: [\"team\", \"users\", \"invite\"],\n async run({ token, email }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Invite user requires a session token\");\n }\n\n if (!email || typeof email !== \"string\") {\n throw new Error(\"Invite user requires an email address\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n email_address: email\n });\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/invite?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] inviting user via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to invite user\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Removes a user or pending invite from the team by ID.\n */\nexport const deleteUser = defineServerAction<\n DeleteUserInput,\n DeleteUserResult\n>({\n id: \"team/delete-user\",\n description: \"Removes a user or pending invite from the team by ID\",\n visibility: \"customer\",\n tags: [\"team\", \"users\", \"delete\"],\n async run({ token, id, isPendingInvite }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Delete user requires a session token\");\n }\n\n if (!id || typeof id !== \"string\") {\n throw new Error(\"Delete user requires an ID\");\n }\n\n // Use different endpoints for users vs invites\n const resource = isPendingInvite ? \"invites\" : \"users\";\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/${resource}/${encodeURIComponent(id)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] deleting %s %s via %s\", resource, id, endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = isPendingInvite ? \"Failed to delete invite\" : \"Failed to delete user\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Fetches the list of service accounts for a team.\n */\nexport const fetchServiceAccounts = defineServerAction<\n FetchServiceAccountsInput,\n FetchServiceAccountsResult\n>({\n id: \"team/fetch-service-accounts\",\n description: \"Fetches paginated list of service accounts\",\n visibility: \"customer\",\n tags: [\"team\", \"service-accounts\"],\n async run({ token, limit = 50, offset = 0, includeRevoked = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch service accounts requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const params = new URLSearchParams({\n customer_id: customerId,\n limit: limit.toString(),\n offset: offset.toString()\n });\n\n // Add filterRevoked parameter - API filters revoked when this param is present\n if (!includeRevoked) {\n params.set(\"filterRevoked\", \"false\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching service accounts via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch service accounts request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n serviceAccounts: data.serviceAccounts || [],\n total: data.total || 0\n };\n }\n});\n\n/**\n * Revokes a service account.\n */\nexport const revokeServiceAccount = defineServerAction<\n RevokeServiceAccountInput,\n RevokeServiceAccountResult\n>({\n id: \"team/revoke-service-account\",\n description: \"Revokes a service account (soft delete)\",\n visibility: \"customer\",\n tags: [\"team\", \"service-accounts\", \"revoke\"],\n async run({ token, accountId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Revoke service account requires a session token\");\n }\n\n if (!accountId || typeof accountId !== \"string\") {\n throw new Error(\"Revoke service account requires an account ID\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts/${encodeURIComponent(accountId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] revoking service account via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to revoke service account\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Rotates a service account token.\n */\nexport const rotateServiceAccountToken = defineServerAction<\n RotateServiceAccountTokenInput,\n RotateServiceAccountTokenResult\n>({\n id: \"team/rotate-service-account-token\",\n description: \"Generates a new token for a service account\",\n visibility: \"customer\",\n tags: [\"team\", \"service-accounts\", \"rotate\"],\n async run({ token, accountId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Rotate service account token requires a session token\");\n }\n\n if (!accountId || typeof accountId !== \"string\") {\n throw new Error(\"Rotate service account token requires an account ID\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts/${encodeURIComponent(accountId)}/rotate-token`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] rotating service account token via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to rotate service account token\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n \n return {\n serviceAccount: data.service_account,\n helmLoginCommand: data.helm_login_cmd || \"\",\n redeployHelm: data.redeploy_helm || []\n };\n }\n});\n\n/**\n * Fetches instances for the customer.\n */\nexport const fetchInstances = defineServerAction<\n FetchInstancesInput,\n FetchInstancesResult\n>({\n id: \"team/fetch-instances\",\n description: \"Fetches instances to determine service account usage\",\n visibility: \"customer\",\n tags: [\"team\", \"instances\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch instances requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/instances?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching instances via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch instances request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n instances: data.instances || []\n };\n }\n});\n\n/**\n * Fetches SAML configuration for the customer.\n */\nexport const fetchSamlConfig = defineServerAction<\n FetchSamlConfigInput,\n FetchSamlConfigResult\n>({\n id: \"team/fetch-saml-config\",\n description: \"Fetches SAML SSO configuration for the team\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch SAML config requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/config?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching SAML config via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch SAML config request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n config: {\n samlAllowed: data.samlAllowed || false,\n samlEnabled: data.samlEnabled || false,\n entityId: data.entityId || \"\",\n acsUrl: data.acsUrl || \"\",\n hasIdpMetadata: data.hasIdpMetadata || false,\n hasIdpCert: data.hasIdpCert || false\n }\n };\n }\n});\n\n/**\n * Updates SAML configuration (uploads IdP metadata and certificate).\n */\nexport const updateSamlConfig = defineServerAction<\n UpdateSamlConfigInput,\n UpdateSamlConfigResult\n>({\n id: \"team/update-saml-config\",\n description: \"Uploads IdP metadata and certificate for SAML SSO\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\", \"update\"],\n async run({ token, idpMetadataXml, idpPublicCert }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Update SAML config requires a session token\");\n }\n\n if (!idpMetadataXml || !idpPublicCert) {\n throw new Error(\"Both IdP metadata and certificate are required\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/config?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] updating SAML config via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({\n idpMetadataXml,\n idpPublicCert\n }),\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to update SAML configuration\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Toggles SAML authentication enabled/disabled.\n */\nexport const toggleSamlEnabled = defineServerAction<\n ToggleSamlEnabledInput,\n ToggleSamlEnabledResult\n>({\n id: \"team/toggle-saml-enabled\",\n description: \"Enables or disables SAML authentication\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\", \"toggle\"],\n async run({ token, enabled }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Toggle SAML enabled requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/enable?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] toggling SAML enabled via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ enabled }),\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to toggle SAML\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n \n return {\n success: true,\n samlEnabled: data.samlEnabled || enabled\n };\n }\n});\n\n/**\n * Removes SAML configuration (deprovisions SAML).\n */\nexport const deprovisionSaml = defineServerAction<\n DeprovisionSamlInput,\n DeprovisionSamlResult\n>({\n id: \"team/deprovision-saml\",\n description: \"Removes all SAML configuration\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\", \"delete\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Deprovision SAML requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/config?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] deprovisioning SAML via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to remove SAML configuration\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n// =============================================================================\n// Invite Accept/Refresh Actions\n// =============================================================================\n\nexport interface AcceptInviteInput {\n code: string;\n}\n\nexport interface AcceptInviteResult {\n token: string;\n}\n\nexport interface AcceptInviteError {\n code: \"invalid_code\" | \"expired\" | \"unknown\";\n message: string;\n}\n\n/**\n * Accepts a team invitation using the invite code from email.\n * Returns a JWT token on success that can be used to establish a session.\n */\nexport const acceptInvite = defineServerAction<\n AcceptInviteInput,\n AcceptInviteResult\n>({\n id: \"auth/accept-invite\",\n description: \"Accepts a team invitation and returns a session token\",\n visibility: \"customer\",\n tags: [\"auth\", \"invite\", \"join\"],\n async run({ code }) {\n if (!code || typeof code !== \"string\") {\n const error: AcceptInviteError = {\n code: \"invalid_code\",\n message: \"Invite code is required\"\n };\n throw error;\n }\n\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/invite/accept`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] accepting invite via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ code })\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n const error: AcceptInviteError = {\n code: \"invalid_code\",\n message: \"Invalid or expired invite code. Please check your code and try again.\"\n };\n throw error;\n }\n\n let errorMessage = \"Failed to accept invitation\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n\n const error: AcceptInviteError = {\n code: \"unknown\",\n message: errorMessage\n };\n throw error;\n }\n\n const payload = await response.json();\n const token = payload?.jwt ?? payload?.token;\n\n if (typeof token !== \"string\") {\n throw new Error(\"Invite accepted but no token returned\");\n }\n\n return { token };\n }\n});\n\nexport interface RefreshInviteInput {\n code: string;\n}\n\nexport interface RefreshInviteResult {\n success: boolean;\n}\n\n/**\n * Refreshes an expired invite by generating a new code and resending the email.\n * The original code is used to identify the invite to refresh.\n */\nexport const refreshInvite = defineServerAction<\n RefreshInviteInput,\n RefreshInviteResult\n>({\n id: \"auth/refresh-invite\",\n description: \"Refreshes an expired invite and resends the invitation email\",\n visibility: \"customer\",\n tags: [\"auth\", \"invite\", \"refresh\"],\n async run({ code }) {\n if (!code || typeof code !== \"string\") {\n throw new Error(\"Invite code is required\");\n }\n\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/invite/refresh`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] refreshing invite via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ code })\n });\n\n // The API returns 200 even for non-existent codes to prevent code enumeration\n if (!response.ok) {\n let errorMessage = \"Failed to refresh invitation\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n// Re-export install types for template usage\nexport type {\n ChannelRelease,\n FetchChannelReleasesResult,\n NetworkAvailability,\n InstallType,\n RegistryAvailability,\n KubernetesDistribution,\n InstallOptions,\n InstallInstructions,\n InstallStep\n} from \"./install\";\n\n// Re-export install-actions for template usage\nexport {\n fetchPendingInstallationsAction,\n fetchChannelReleasesAction,\n createInstallOptionsAction,\n getInstallOptionsAction,\n updateInstallOptionsAction,\n discardInstallationAction\n} from \"./install-actions\";\n\n// Re-export service-account actions for template usage\nexport {\n createServiceAccountAction\n} from \"./service-account\";\n\n// Re-export fetch-app-info for template usage\nexport { fetchAppInfo } from \"./fetch-app-info\";\n\n\n// Re-export team-settings for template usage\nexport {\n fetchTeamUsersAction,\n inviteUserAction,\n deleteUserAction,\n fetchServiceAccountsAction,\n revokeServiceAccountAction,\n rotateServiceAccountTokenAction,\n fetchInstancesAction,\n fetchSamlConfigAction,\n updateSamlConfigAction,\n toggleSamlEnabledAction,\n deprovisionSamlAction,\n fetchAppFeatures,\n type AppFeatures\n} from \"./team-settings\";\n\n// Re-export user-settings for template usage\nexport {\n fetchCurrentUserAction,\n updateUserAction,\n fetchTeamsForUserSettings,\n fetchNotificationsAction,\n updateNotificationsAction\n} from \"./user-settings\";\nexport type {\n TeamForUserSettings\n} from \"./user-settings\";\n\n// Re-export change-team for template usage\nexport {\n changeTeamAction,\n fetchCustomersForMenu\n} from \"./change-team\";\n\n// Re-export support-bundles for template usage\nexport {\n downloadSupportBundleAction,\n deleteSupportBundleAction,\n uploadSupportBundleAction,\n listSupportBundlesAction\n} from \"./support-bundles\";\nexport type {\n ActionResult as SupportBundleActionResult,\n UploadSupportBundleResult as UploadSupportBundleActionResult,\n ListBundlesResult\n} from \"./support-bundles\";\nexport { fetchUser } from './fetch-user';\nexport type { UserResult, UserContext, UserPermissions } from './fetch-user';\n\n// Trial signup actions are exported separately to avoid bundling server-only code\n// Import from '@replicated/portal-components/actions/trial-signup' instead\nexport type {\n TrialSignupPayload,\n TrialSignupResult,\n TrialSignupVerifyResult\n} from \"./trial-signup\";\n","import type { ReactNode, SVGProps } from \"react\";\nimport { fetchLicense } from \"../actions\";\nimport type {\n License,\n PortalLicenseField\n} from \"../actions\";\n\nexport interface LicenseDetailsProps {\n token: string;\n title?: string;\n description?: string;\n}\n\nconst ShieldIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n </svg>\n);\n\nconst CalendarIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M8 2v4\" />\n <path d=\"M16 2v4\" />\n <rect width={18} height={18} x={3} y={4} rx={2} />\n <path d=\"M3 10h18\" />\n </svg>\n);\n\nconst DownloadIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M12 17V3\" />\n <path d=\"m6 11 6 6 6-6\" />\n <path d=\"M19 21H5\" />\n </svg>\n);\n\nconst BuildingIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <rect width={16} height={20} x={4} y={2} rx={2} ry={2} />\n <path d=\"M9 22v-4h6v4\" />\n <path d=\"M8 6h.01\" />\n <path d=\"M16 6h.01\" />\n <path d=\"M12 6h.01\" />\n <path d=\"M12 10h.01\" />\n <path d=\"M12 14h.01\" />\n <path d=\"M16 10h.01\" />\n <path d=\"M16 14h.01\" />\n <path d=\"M8 10h.01\" />\n <path d=\"M8 14h.01\" />\n </svg>\n);\n\nconst CheckIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M21.8 10A10 10 0 1 1 17 3.33\" />\n <path d=\"m9 11 3 3L22 4\" />\n </svg>\n);\n\nconst formatExpiration = (value?: string | null) => {\n if (!value || value === \"never\") {\n return \"Does not expire\";\n }\n\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return value;\n }\n\n return date.toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\"\n });\n};\n\nconst maskValue = (value?: string | null, isSecret?: boolean) => {\n if (isSecret) {\n return \"••••••••••••\";\n }\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n return \"No value set\";\n};\n\nconst getFieldTextClass = (value?: string | null) => {\n if (value === \"does-not-expire\") {\n return \"text-gray-500\";\n }\n return value && value.trim().length > 0 ? \"text-gray-500\" : \"text-gray-300\";\n};\n\nconst InfoRow = ({\n icon,\n title,\n children\n}: {\n icon: ReactNode;\n title: string;\n children: ReactNode;\n}) => (\n <div>\n <div className=\"flex items-baseline gap-2\">\n <div className=\"flex h-4 w-4 flex-shrink-0 items-center justify-center text-gray-900\">{icon}</div>\n <h3 className=\"text-sm font-medium leading-4 text-gray-900\">{title}</h3>\n </div>\n <div className=\"pl-6\">{children}</div>\n </div>\n);\n\nconst renderInstallOrChannel = (values?: string[]) => {\n if (!values || values.length === 0) {\n return <p className=\"mt-1 text-sm text-gray-500\">Not specified</p>;\n }\n return (\n <p className=\"mt-1 text-sm text-gray-500\">\n {values.join(\", \")}\n </p>\n );\n};\n\nconst buildPrimaryRows = (license: License) => {\n const rows: Array<{ key: string; node: ReactNode }> = [];\n\n rows.push({\n key: \"status\",\n node: (\n <InfoRow\n icon={<ShieldIcon className=\"h-4 w-4\" />}\n title=\"License Status\"\n >\n <div className=\"mt-1 flex items-center text-sm text-gray-600\">\n <CheckIcon className=\"mr-1.5 h-4 w-4 text-green-500\" />\n <span>{license.isExpired ? \"Expired\" : \"Active\"}</span>\n </div>\n {license.environment ? (\n <p className=\"mt-1 text-sm text-gray-500\">\n {license.environment}\n </p>\n ) : null}\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"expiration\",\n node: (\n <InfoRow\n icon={<CalendarIcon className=\"h-4 w-4\" />}\n title=\"Expiration Date\"\n >\n <p className=\"mt-1 text-sm text-gray-500\">\n {formatExpiration(license.expiresAt)}\n </p>\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"channels\",\n node: (\n <InfoRow\n icon={<ShieldIcon className=\"h-4 w-4\" />}\n title=\"Release Channel(s)\"\n >\n {renderInstallOrChannel(license.releaseChannels)}\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"installs\",\n node: (\n <InfoRow\n icon={<DownloadIcon className=\"h-4 w-4\" />}\n title=\"Install Options\"\n >\n {renderInstallOrChannel(license.installMethods)}\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"customer\",\n node: (\n <InfoRow\n icon={<BuildingIcon className=\"h-4 w-4\" />}\n title=\"Customer Name\"\n >\n <p className=\"mt-1 text-sm text-gray-500\">\n {license.customerName ?? \"Unknown customer\"}\n </p>\n {license.customerId ? (\n <p className=\"text-xs text-gray-400\">\n Customer ID: {license.customerId}\n </p>\n ) : null}\n </InfoRow>\n )\n });\n\n return rows;\n};\n\nconst renderFields = (fields: PortalLicenseField[]) => {\n if (!fields.length) {\n return (\n <p className=\"text-sm text-gray-500\">\n No additional fields available.\n </p>\n );\n }\n\n return (\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\">\n {fields.map((field) => (\n <div key={field.key} className=\"flex flex-col\">\n <p className=\"text-sm font-medium text-gray-900\">\n {field.label}\n </p>\n <p\n className={`mt-1 break-words text-sm ${getFieldTextClass(\n field.value\n )}`}\n >\n {maskValue(field.value, field.isSecret)}\n </p>\n </div>\n ))}\n </div>\n );\n};\n\nexport const LicenseDetails = async ({\n token,\n title = \"License Details\",\n description = \"View your enterprise license details\"\n}: LicenseDetailsProps) => {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"LicenseDetails component requires a non-empty token\");\n }\n\n const license = await fetchLicense();\n const rows = buildPrimaryRows(license);\n\n return (\n <div className=\"rounded border border-gray-100 bg-white p-8 shadow-[0_18px_45px_rgba(17,24,39,0.08)]\">\n <header className=\"flex flex-col border-b border-gray-100 pb-6\">\n <h1 className=\"text-3xl font-bold text-gray-900\">\n {title}\n </h1>\n {description ? (\n <p className=\"mt-2 text-sm text-gray-600\">\n {description}\n </p>\n ) : null}\n </header>\n\n <div className=\"mt-6 space-y-6\">\n <div className=\"rounded-lg border border-gray-100 bg-white p-6 sm:p-8\">\n <div className=\"grid grid-cols-1 items-start gap-6 md:grid-cols-2 xl:grid-cols-3\">\n {rows.map((row) => (\n <div key={row.key}>{row.node}</div>\n ))}\n </div>\n </div>\n\n <div className=\"rounded-lg border border-gray-100 bg-white p-6 sm:p-8\">\n <h2 className=\"mb-4 text-lg font-medium text-gray-900\">\n Additional License Fields\n </h2>\n <div className=\"overflow-x-auto\">\n {renderFields(license.fields ?? [])}\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import type { ReactNode } from \"react\";\nimport Link from \"next/link\";\nimport { fetchCustomBranding } from \"../actions\";\nimport { decodeBranding, normalizeColor, type BackgroundType } from \"../utils/branding\";\n\nexport interface Customer {\n id: string;\n name: string;\n}\n\nexport interface TopNavLink {\n label: string;\n href?: string;\n icon: ReactNode;\n}\n\nexport interface TopNavBranding {\n logo?: string | null;\n title?: string;\n primaryColor?: string;\n secondaryColor?: string;\n background?: BackgroundType;\n backgroundImage?: string;\n backgroundGradientStart?: string;\n backgroundGradientEnd?: string;\n}\n\nexport interface TopNavProps {\n links?: TopNavLink[];\n hiddenLabels?: string[];\n additionalLinks?: TopNavLink[];\n order?: string[];\n userMenuLabel?: string;\n activeLabel?: string;\n customerName?: string;\n customers?: Customer[];\n currentCustomerId?: string;\n onChangeTeam?: (customerId: string) => Promise<void>;\n userMenuChildren?: ReactNode;\n logoutButton?: ReactNode;\n branding?: TopNavBranding;\n}\n\nconst defaultTopNavLinks: TopNavLink[] = [\n {\n label: \"Dashboard\",\n href: \"/\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"7\" height=\"9\" x=\"3\" y=\"3\" rx=\"1\" />\n <rect width=\"7\" height=\"5\" x=\"14\" y=\"3\" rx=\"1\" />\n <rect width=\"7\" height=\"9\" x=\"14\" y=\"12\" rx=\"1\" />\n <rect width=\"7\" height=\"5\" x=\"3\" y=\"16\" rx=\"1\" />\n </svg>\n )\n },\n {\n label: \"Install\",\n href: \"/install\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\" />\n </svg>\n )\n },\n {\n label: \"Update\",\n href: \"/update\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\" />\n <path d=\"M21 3v5h-5\" />\n </svg>\n )\n },\n {\n label: \"Security\",\n href: \"/security\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n </svg>\n )\n },\n {\n label: \"Release History\",\n href: \"/release-history\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n <path d=\"M10 9H8\" />\n <path d=\"M16 13H8\" />\n <path d=\"M16 17H8\" />\n </svg>\n )\n },\n {\n label: \"License\",\n href: \"/license\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4\" />\n <path d=\"m21 2-9.6 9.6\" />\n <circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\" />\n </svg>\n )\n },\n {\n label: \"Support\",\n href: \"/support\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.93 4.93 4.24 4.24\" />\n <path d=\"m14.83 9.17 4.24-4.24\" />\n <path d=\"m14.83 14.83 4.24 4.24\" />\n <path d=\"m9.17 14.83-4.24 4.24\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n </svg>\n )\n }\n];\n\nconst orderLinks = (links: TopNavLink[], order?: string[]) => {\n if (!order || order.length === 0) {\n return links;\n }\n\n const orderMap = new Map(order.map((label, index) => [label, index]));\n return links\n .map((link, index) => ({\n link,\n originalIndex: index,\n orderIndex: orderMap.has(link.label)\n ? (orderMap.get(link.label) as number)\n : order.length + index\n }))\n .sort((a, b) => {\n if (a.orderIndex === b.orderIndex) {\n return a.originalIndex - b.originalIndex;\n }\n return a.orderIndex - b.orderIndex;\n })\n .map((item) => item.link);\n};\n\n/**\n * TopNav renders the hero navigation bar shown on authenticated dashboards.\n */\nexport const TopNav = async ({\n links,\n hiddenLabels,\n additionalLinks,\n order,\n userMenuLabel,\n activeLabel,\n customerName,\n customers,\n currentCustomerId,\n onChangeTeam,\n userMenuChildren,\n logoutButton,\n branding: brandingProp\n}: TopNavProps) => {\n const displayLabel = userMenuLabel || (customerName ? `Team: ${customerName}` : \"Team: Example\");\n let logo: string | undefined;\n let brandTitle: string | undefined;\n let primaryColor: string | undefined;\n let secondaryColor: string | undefined;\n let background: BackgroundType | undefined;\n let backgroundImageUrl: string | undefined;\n let backgroundGradientStart: string | undefined;\n let backgroundGradientEnd: string | undefined;\n\n // Use branding prop if provided, otherwise fetch it\n if (brandingProp) {\n if (brandingProp.logo && typeof brandingProp.logo === \"string\") {\n logo = brandingProp.logo;\n }\n if (brandingProp.title && typeof brandingProp.title === \"string\") {\n const normalizedTitle = brandingProp.title.trim();\n if (normalizedTitle) {\n brandTitle = normalizedTitle;\n }\n }\n primaryColor = normalizeColor(brandingProp.primaryColor);\n secondaryColor = normalizeColor(brandingProp.secondaryColor);\n background = brandingProp.background;\n backgroundImageUrl = brandingProp.backgroundImage;\n backgroundGradientStart = normalizeColor(brandingProp.backgroundGradientStart);\n backgroundGradientEnd = normalizeColor(brandingProp.backgroundGradientEnd);\n } else {\n try {\n const brandingResponse = await fetchCustomBranding();\n const branding = decodeBranding({ brandingData: brandingResponse.brandingData });\n logo = branding.logo;\n brandTitle = branding.title;\n primaryColor = branding.primaryColor;\n secondaryColor = branding.secondaryColor;\n background = branding.background;\n backgroundImageUrl = branding.backgroundImage;\n backgroundGradientStart = branding.backgroundGradientStart;\n backgroundGradientEnd = branding.backgroundGradientEnd;\n } catch (error) {\n console.debug(\"[portal-components] branding fetch failed\", error);\n }\n }\n\n const baseLinks = links ?? defaultTopNavLinks;\n const hiddenSet = hiddenLabels ? new Set(hiddenLabels) : null;\n let resolvedLinks = baseLinks.filter(\n (link) => !hiddenSet?.has(link.label)\n );\n\n if (additionalLinks?.length) {\n resolvedLinks = [...resolvedLinks, ...additionalLinks];\n }\n\n resolvedLinks = orderLinks(resolvedLinks, order);\n\n // Determine header background style based on background type:\n // - \"custom\": use background gradient colors (customColor1/customColor2)\n // - \"image\": use the background image URL with overlay gradient\n // - \"minimal\" or undefined: use primary/secondary colors\n const getHeaderBackgroundStyle = (): React.CSSProperties => {\n if (background === \"image\" && backgroundImageUrl) {\n return {\n background: `url(${backgroundImageUrl})`,\n backgroundImage: `linear-gradient(to top, rgba(255, 255, 255, 0.3) 30%, rgba(255, 255, 255, 0)), url(${backgroundImageUrl})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\"\n };\n }\n\n const gradientStart = (background === \"custom\" && backgroundGradientStart)\n ? backgroundGradientStart\n : primaryColor;\n const gradientEnd = (background === \"custom\" && backgroundGradientEnd)\n ? backgroundGradientEnd\n : secondaryColor;\n\n return {\n backgroundImage: `linear-gradient(to top, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0) 33%), linear-gradient(${gradientStart}, ${gradientEnd})`,\n backgroundRepeat: \"no-repeat\",\n backgroundSize: \"100% 100%\"\n };\n };\n\n return (\n <div\n className=\"relative flex h-[280px] w-full items-start justify-center\"\n style={getHeaderBackgroundStyle()}\n >\n <div className=\"mx-auto mt-[30px] w-full max-w-[1248px] px-6\">\n <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)]\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {logo ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={logo}\n alt=\"Portal logo\"\n className=\"object-contain\"\n style={{\n maxWidth: \"240px\",\n maxHeight: \"48px\"\n }}\n />\n ) : (\n <svg\n className=\"h-8 w-8 text-gray-400\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <ellipse cx=\"12\" cy=\"12\" rx=\"4\" ry=\"10\" />\n <path d=\"M2 12h20\" />\n </svg>\n )}\n <span className=\"text-xl font-bold text-gray-900\">\n {brandTitle || \"Enterprise Portal\"}\n </span>\n </div>\n <details className=\"group relative\">\n <summary className=\"flex cursor-pointer items-center gap-2 text-sm font-medium text-gray-600 hover:text-gray-900 list-none\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-gray-500\"\n >\n <path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\"></path>\n <circle cx=\"12\" cy=\"7\" r=\"4\"></circle>\n </svg>\n <span>{displayLabel}</span>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-gray-500\"\n >\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n </summary>\n <div className=\"absolute right-0 mt-2 w-48 rounded-md border border-gray-200 bg-white py-2 text-sm text-gray-700 shadow-lg z-50\">\n <Link\n href=\"/user-settings\"\n className=\"block w-full px-4 py-2 text-left hover:bg-gray-100\"\n >\n User settings\n </Link>\n <Link\n href=\"/team-settings\"\n className=\"block w-full px-4 py-2 text-left hover:bg-gray-100\"\n >\n Team settings\n </Link>\n {userMenuChildren}\n {logoutButton}\n </div>\n </details>\n </div>\n <div className=\"mt-3 flex flex-wrap gap-3 pb-2 text-sm font-medium text-gray-500\">\n {resolvedLinks.map(({ label, icon, href }) => {\n const isActive = activeLabel === label;\n const className = `flex items-center gap-2 px-4 py-1 transition text-gray-500 ${\n isActive ? \"underline underline-offset-8 decoration-2\" : \"\"\n }`;\n\n if (href) {\n return (\n <Link key={label} href={href} className={className}>\n <span className={isActive ? \"text-gray-900\" : \"text-gray-500\"}>\n {icon}\n </span>\n <span>{label}</span>\n </Link>\n );\n }\n\n return (\n <button key={label} className={className} type=\"button\">\n <span className={isActive ? \"text-gray-900\" : \"text-gray-500\"}>\n {icon}\n </span>\n <span>{label}</span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport { defaultTopNavLinks };\n","import type { SVGProps } from \"react\";\nimport Link from \"next/link\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\nconst GlobeIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418\" />\n </svg>\n);\n\nconst AirGapIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M13.181 8.68a4.503 4.503 0 0 1 1.903 6.405m-9.768-2.782L3.56 14.06a4.5 4.5 0 0 0 6.364 6.365l3.129-3.129m5.614-5.615 1.757-1.757a4.5 4.5 0 0 0-6.364-6.365l-4.5 4.5c-.258.26-.479.541-.661.84m1.903 6.405a4.495 4.495 0 0 1-1.242-.88 4.483 4.483 0 0 1-1.062-1.683m6.587 2.345 5.907 5.907m-5.907-5.907L8.898 8.898M2.991 2.99 8.898 8.9\" />\n </svg>\n);\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst contentClass = \"mt-4 flex-1 space-y-3\";\nconst itemClass = \"flex items-center gap-3 text-sm text-gray-600\";\nconst iconClass = \"h-5 w-5 text-gray-500\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold hover:opacity-80\";\nconst badgeClass =\n \"ml-2 inline-flex h-5 min-w-[20px] items-center justify-center rounded-full px-1.5 text-xs font-medium text-white\";\n\nexport interface UpdatesCardProps {\n /** Number of active online instances (checked in within 24 hours) */\n onlineActiveCount?: number;\n /** Number of air gap instances */\n airgapCount?: number;\n /** Number of updates available for online instances */\n onlineUpdates?: number;\n /** Number of updates available for airgap instances */\n airgapUpdates?: number;\n}\n\nconst Badge = ({ count }: { count: number }) => (\n <span\n className={badgeClass}\n style={{ backgroundColor: `var(--portal-branding-primary, ${DEFAULT_SECONDARY_COLOR})` }}\n aria-label={`${count} updates available`}\n >\n {count}\n </span>\n);\n\nexport const UpdatesCard = ({\n onlineActiveCount = 0,\n airgapCount = 0,\n onlineUpdates = 0,\n airgapUpdates = 0\n}: UpdatesCardProps) => (\n <section className={baseCardClass} aria-labelledby=\"updates-card-heading\">\n <header>\n <h2 id=\"updates-card-heading\" className={headingClass}>\n Updates\n </h2>\n </header>\n <div className={contentClass}>\n <div className={itemClass}>\n <GlobeIcon className={iconClass} />\n <span>\n {onlineActiveCount} Active Online {onlineActiveCount === 1 ? \"instance\" : \"instances\"}\n </span>\n {onlineUpdates > 0 && <Badge count={onlineUpdates} />}\n </div>\n <div className={itemClass}>\n <AirGapIcon className={iconClass} />\n <span>\n {airgapCount} Air gap {airgapCount === 1 ? \"instance\" : \"instances\"}\n </span>\n {airgapUpdates > 0 && <Badge count={airgapUpdates} />}\n </div>\n </div>\n <footer className={footerClass}>\n <Link href=\"/update\" style={{ color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }}>View updates →</Link>\n </footer>\n </section>\n);\n\nUpdatesCard.displayName = \"UpdatesCard\";\n","import type { SVGProps } from \"react\";\nimport Link from \"next/link\";\nimport { listSupportBundles } from \"../actions\";\nimport { isRedirectError } from \"../utils/api-client\";\n\nconst UploadIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5\" />\n </svg>\n);\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst contentClass = \"mt-4 flex-1 space-y-3\";\nconst itemClass = \"flex items-center gap-3 text-sm text-gray-600\";\nconst iconClass = \"h-5 w-5 text-gray-500\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold text-primary hover:text-primary/80\";\n\nexport const SupportCard = async () => {\n let totalCount: number | null = null;\n try {\n const headersModule = await import(\"next/headers\");\n const store = await headersModule.cookies();\n const session = store.get(\"portal_session\");\n const token = session?.value;\n if (token) {\n const result = await listSupportBundles.run({ token });\n totalCount = result.totalCount;\n } else {\n console.debug(\"[portal-components] no portal_session token for support bundles\");\n }\n } catch (error) {\n // Re-throw redirect errors so Next.js can handle navigation\n if (isRedirectError(error)) {\n throw error;\n }\n console.error(\"[portal-components] support bundles fetch failed\", error);\n }\n\n return (\n <section className={baseCardClass} aria-labelledby=\"support-card-heading\">\n <header>\n <h2 id=\"support-card-heading\" className={headingClass}>\n Support\n </h2>\n </header>\n <div className={contentClass}>\n <div className={itemClass}>\n <UploadIcon className={iconClass} />\n <span>\n Support bundles uploaded ({totalCount ?? 0})\n </span>\n </div>\n </div>\n <footer className={footerClass}>\n <Link href=\"/support\" className=\"inline-flex items-center gap-1\">\n View support guide →\n </Link>\n </footer>\n </section>\n );\n};\n\nSupportCard.displayName = \"SupportCard\";\n","\"use client\";\n\nimport { useState, useMemo } from \"react\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UserSettingsUser {\n emailAddress: string;\n firstName?: string;\n lastName?: string;\n}\n\nexport interface UserSettingsTeam {\n id: string;\n name: string;\n appId: string;\n appName: string;\n appSlug: string;\n}\n\nexport interface UserSettingsCustomer {\n id: string;\n name: string;\n}\n\nexport interface UserSettingsNotification {\n type: string;\n enabled: boolean;\n}\n\nexport interface UserSettingsProps {\n // User profile\n user?: UserSettingsUser;\n isUserLoading?: boolean;\n userError?: Error | null;\n \n // Profile editing\n isUpdating?: boolean;\n updateError?: Error | null;\n onUpdateUser?: (data: { firstName?: string; lastName?: string }) => Promise<void>;\n \n // Teams\n teams?: UserSettingsTeam[];\n currentCustomer?: UserSettingsCustomer;\n isTeamsLoading?: boolean;\n onTeamSwitch?: (team: UserSettingsTeam) => Promise<void>;\n \n // Notifications\n notifications?: UserSettingsNotification[];\n isNotificationsLoading?: boolean;\n onToggleNotification?: (notificationType: string, enabled: boolean) => Promise<void>;\n \n // Optional branding\n primaryColor?: string;\n}\n\n// =============================================================================\n// Notification descriptions\n// =============================================================================\n\nconst NOTIFICATION_DESCRIPTIONS: Record<string, string> = {\n \"new-version\": \"New version available\",\n};\n\n// =============================================================================\n// Email Notifications Section\n// =============================================================================\n\ninterface EmailNotificationsSectionProps {\n teamName: string;\n notifications: UserSettingsNotification[];\n isLoading: boolean;\n onToggle?: (type: string, enabled: boolean) => Promise<void>;\n}\n\nconst EmailNotificationsSection = ({\n teamName,\n notifications,\n isLoading,\n onToggle,\n}: EmailNotificationsSectionProps) => {\n // Merge API data with all notification types to ensure all options are always shown\n const allNotificationTypes = Object.keys(NOTIFICATION_DESCRIPTIONS);\n const mergedNotifications = allNotificationTypes.map((type) => {\n const existing = notifications.find((n) => n.type === type);\n return {\n type,\n enabled: existing ? existing.enabled : type === \"new-version\", // Default new-version to true\n };\n });\n\n if (isLoading) {\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">\n Email Notifications for {teamName}\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Choose which email notifications you want to receive for this team.\n </p>\n <div className=\"mt-6 flex justify-center py-8\">\n <p className=\"text-sm text-gray-500\">Loading notifications...</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">\n Email Notifications for {teamName}\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Choose which email notifications you want to receive for this team.\n </p>\n\n <div className=\"mt-6 overflow-hidden rounded-lg border border-gray-200\">\n <div className=\"flex items-center justify-between bg-gray-50 px-4 py-2\">\n <span className=\"text-xs font-medium uppercase text-gray-600\">\n Description\n </span>\n <span className=\"text-xs font-medium uppercase text-gray-600\">\n Enabled\n </span>\n </div>\n {mergedNotifications.map((notification) => (\n <div\n key={notification.type}\n className=\"flex items-center justify-between border-t border-gray-200 px-4 py-3\"\n >\n <span className=\"text-sm text-gray-900\">\n {NOTIFICATION_DESCRIPTIONS[notification.type]}\n </span>\n <input\n type=\"checkbox\"\n checked={notification.enabled}\n onChange={() => onToggle?.(notification.type, !notification.enabled)}\n className=\"portal-checkbox\"\n />\n </div>\n ))}\n </div>\n <p className=\"mt-3 text-xs text-gray-500\">\n These notification preferences are specific to the {teamName} team.\n Switch teams to manage notifications for other teams.\n </p>\n </div>\n );\n};\n\n// =============================================================================\n// Teams Section\n// =============================================================================\n\ninterface TeamsSectionProps {\n teams: UserSettingsTeam[];\n currentCustomer?: UserSettingsCustomer;\n isLoading: boolean;\n onTeamSwitch?: (team: UserSettingsTeam) => Promise<void>;\n primaryColor?: string;\n}\n\nconst TeamsSection = ({\n teams,\n currentCustomer,\n isLoading,\n onTeamSwitch,\n primaryColor,\n}: TeamsSectionProps) => {\n // Group teams by app\n const groupedTeams = useMemo(() => {\n const groups = new Map<string, { appName: string; teams: UserSettingsTeam[] }>();\n \n for (const team of teams) {\n const existing = groups.get(team.appId);\n if (existing) {\n existing.teams.push(team);\n } else {\n groups.set(team.appId, {\n appName: team.appName,\n teams: [team],\n });\n }\n }\n \n return groups;\n }, [teams]);\n\n if (isLoading) {\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">Teams</h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Teams associate your email address with any additional licenses your\n account has access to.\n </p>\n <div className=\"mt-6\">\n <p className=\"text-sm text-gray-500\">Loading teams...</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">Teams</h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Teams associate your email address with any additional licenses your\n account has access to.\n </p>\n\n <div className=\"mt-6 space-y-6\">\n {Array.from(groupedTeams.values()).map((appGroup) => (\n <div key={appGroup.appName} className=\"space-y-3\">\n <h3 className=\"text-base font-medium text-gray-900\">\n {appGroup.appName}\n </h3>\n <div className=\"space-y-2\">\n {appGroup.teams.map((team) => {\n const isCurrentTeam = currentCustomer?.id === team.id;\n return (\n <button\n key={team.id}\n type=\"button\"\n onClick={() => !isCurrentTeam && onTeamSwitch?.(team)}\n disabled={isCurrentTeam}\n className={`flex w-full items-center justify-between rounded-lg border p-4 text-left transition ${\n isCurrentTeam\n ? \"cursor-default border-gray-300 bg-gray-50\"\n : \"cursor-pointer border-gray-200 hover:border-gray-400\"\n }`}\n style={\n !isCurrentTeam && primaryColor\n ? { \"--hover-border\": primaryColor } as React.CSSProperties\n : undefined\n }\n >\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"h-4 w-4\"\n style={{ color: primaryColor || DEFAULT_SECONDARY_COLOR }}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z\"\n />\n </svg>\n <div>\n <p className=\"text-sm font-medium text-gray-900\">\n {team.name}\n </p>\n {isCurrentTeam && (\n <p className=\"text-xs text-gray-500\">Current Team</p>\n )}\n </div>\n </div>\n {!isCurrentTeam && (\n <svg\n className=\"h-4 w-4\"\n style={{ color: primaryColor || DEFAULT_SECONDARY_COLOR }}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n )}\n </button>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\n// =============================================================================\n// Profile Section\n// =============================================================================\n\ninterface ProfileSectionProps {\n user?: UserSettingsUser;\n isLoading: boolean;\n isUpdating: boolean;\n error?: Error | null;\n updateError?: Error | null;\n onSave?: (data: { firstName?: string; lastName?: string }) => Promise<void>;\n primaryColor?: string;\n}\n\nconst ProfileSection = ({\n user,\n isLoading,\n isUpdating,\n error,\n updateError,\n onSave,\n primaryColor,\n}: ProfileSectionProps) => {\n const [isEditing, setIsEditing] = useState(false);\n const [firstName, setFirstName] = useState(user?.firstName || \"\");\n const [lastName, setLastName] = useState(user?.lastName || \"\");\n const [inputError, setInputError] = useState<string | null>(null);\n\n // Reset form when user changes\n const resetForm = () => {\n setFirstName(user?.firstName || \"\");\n setLastName(user?.lastName || \"\");\n setInputError(null);\n };\n\n const handleSave = async () => {\n if (!firstName && !lastName) {\n setInputError(\"Please enter a first name or last name\");\n return;\n }\n\n if (firstName === user?.firstName && lastName === user?.lastName) {\n setIsEditing(false);\n return;\n }\n\n try {\n await onSave?.({ firstName, lastName });\n setIsEditing(false);\n } catch (err) {\n console.error(\"Error updating user information:\", err);\n }\n };\n\n const handleCancel = () => {\n setIsEditing(false);\n resetForm();\n };\n\n const handleEdit = () => {\n resetForm();\n setIsEditing(true);\n };\n\n const buttonStyle = {\n backgroundColor: primaryColor || DEFAULT_SECONDARY_COLOR,\n borderColor: primaryColor || DEFAULT_SECONDARY_COLOR\n };\n\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900\">\n Profile Information\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">Your account information.</p>\n {(error || updateError) && (\n <p className=\"mt-2 text-sm text-red-600\">\n {error?.message || updateError?.message || \"Failed to update profile\"}\n </p>\n )}\n {inputError && (\n <p className=\"mt-2 text-sm text-red-600\">{inputError}</p>\n )}\n </div>\n {isEditing ? (\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={isUpdating}\n className=\"inline-flex items-center rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 shadow-sm transition hover:bg-gray-50 disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={isUpdating}\n style={buttonStyle}\n 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]\"\n >\n {isUpdating ? \"Saving...\" : \"Save\"}\n </button>\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={handleEdit}\n style={buttonStyle}\n 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]\"\n >\n Edit\n </button>\n )}\n </div>\n\n <div className=\"mt-6 flex gap-8\">\n {isEditing ? (\n <div className=\"flex gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-gray-600\">\n First Name\n </label>\n <input\n type=\"text\"\n value={firstName}\n onChange={(e) => {\n setInputError(null);\n setFirstName(e.target.value);\n }}\n disabled={isUpdating}\n placeholder=\"First Name\"\n className=\"portal-input mt-1 block w-48\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-600\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={lastName}\n onChange={(e) => {\n setInputError(null);\n setLastName(e.target.value);\n }}\n disabled={isUpdating}\n placeholder=\"Last Name\"\n className=\"portal-input mt-1 block w-48\"\n />\n </div>\n </div>\n ) : (\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium text-gray-600\">\n Full Name (optional)\n </label>\n <p className=\"mt-1 text-sm text-gray-900\">\n {user?.firstName || user?.lastName\n ? `${user.firstName || \"\"} ${user.lastName || \"\"}`.trim()\n : \"—\"}\n </p>\n </div>\n )}\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium text-gray-600\">Email</label>\n <p className=\"mt-1 text-sm text-gray-500\">\n {isLoading ? \"Loading...\" : user?.emailAddress || \"\"}\n </p>\n </div>\n </div>\n </div>\n );\n};\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\nexport const UserSettings = ({\n user,\n isUserLoading = false,\n userError,\n isUpdating = false,\n updateError,\n onUpdateUser,\n teams = [],\n currentCustomer,\n isTeamsLoading = false,\n onTeamSwitch,\n notifications = [],\n isNotificationsLoading = false,\n onToggleNotification,\n primaryColor,\n}: UserSettingsProps) => {\n if (userError) {\n return (\n <div className=\"p-8\">\n <div className=\"text-red-600\">\n Failed to load user settings. {userError?.message} Please try again later.\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"w-full space-y-6\">\n <header>\n <h1 className=\"text-2xl font-semibold text-gray-900\">User Settings</h1>\n </header>\n\n <div className=\"space-y-6\">\n <ProfileSection\n user={user}\n isLoading={isUserLoading}\n isUpdating={isUpdating}\n error={userError}\n updateError={updateError}\n onSave={onUpdateUser}\n primaryColor={primaryColor}\n />\n\n <TeamsSection\n teams={teams}\n currentCustomer={currentCustomer}\n isLoading={isTeamsLoading}\n onTeamSwitch={onTeamSwitch}\n primaryColor={primaryColor}\n />\n\n {currentCustomer && (\n <EmailNotificationsSection\n teamName={currentCustomer.name}\n notifications={notifications}\n isLoading={isNotificationsLoading}\n onToggle={onToggleNotification}\n />\n )}\n </div>\n </div>\n );\n};\n\nUserSettings.displayName = \"UserSettings\";\n","import Link from \"next/link\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst bodySpacerClass = \"mt-4 flex-1\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold hover:opacity-80\";\n\nexport const UserSettingsCard = () => (\n <section className={baseCardClass} aria-labelledby=\"user-settings-card-heading\">\n <header>\n <h2 id=\"user-settings-card-heading\" className={headingClass}>\n User Settings\n </h2>\n </header>\n <div className={bodySpacerClass} />\n <footer className={footerClass}>\n <Link href=\"/user-settings\" style={{ color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }}>View user settings →</Link>\n </footer>\n </section>\n);\n\nUserSettingsCard.displayName = \"UserSettingsCard\";\n","import type { SVGProps } from \"react\";\nimport Link from \"next/link\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\nconst UsersIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z\" />\n </svg>\n);\n\nconst KeyIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z\" />\n </svg>\n);\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst contentClass = \"mt-4 flex-1 space-y-3\";\nconst itemClass = \"flex items-center gap-3 text-sm text-gray-600\";\nconst iconClass = \"h-5 w-5 text-gray-500\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold hover:opacity-80\";\n\nexport interface TeamSettingsCardProps {\n /** Number of team members */\n userCount?: number;\n /** Number of service accounts */\n serviceAccountCount?: number;\n}\n\nexport const TeamSettingsCard = ({\n userCount = 0,\n serviceAccountCount = 0\n}: TeamSettingsCardProps) => (\n <section className={baseCardClass} aria-labelledby=\"team-settings-card-heading\">\n <header>\n <h2 id=\"team-settings-card-heading\" className={headingClass}>\n Team Settings\n </h2>\n </header>\n <div className={contentClass}>\n <div className={itemClass}>\n <UsersIcon className={iconClass} />\n <span>\n {userCount} Team {userCount === 1 ? \"Member\" : \"Members\"}\n </span>\n </div>\n <div className={itemClass}>\n <KeyIcon className={iconClass} />\n <span>\n {serviceAccountCount} Service {serviceAccountCount === 1 ? \"Account\" : \"Accounts\"}\n </span>\n </div>\n </div>\n <footer className={footerClass}>\n <Link href=\"/team-settings\" style={{ color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }}>View team settings →</Link>\n </footer>\n </section>\n);\n\nTeamSettingsCard.displayName = \"TeamSettingsCard\";\n","import { ReactNode } from \"react\";\nimport { TopNav } from \"./top-nav\";\n\ninterface UpdateLayoutProps {\n children: ReactNode;\n}\n\nexport const UpdateLayout = ({ children }: UpdateLayoutProps) => {\n return (\n <div className=\"min-h-screen bg-white\">\n <TopNav activeLabel=\"Updates\" />\n <div className=\"px-6 py-8\">\n <div className=\"mx-auto w-full max-w-[1248px]\">\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nUpdateLayout.displayName = \"UpdateLayout\";\n","import { getApiOrigin } from \"./actions\";\n\n/**\n * Result of setting a SAML session.\n */\nexport interface SetSamlSessionResult {\n success: boolean;\n message?: string;\n}\n\n/**\n * Implementation for setting the SAML session cookie after successful authentication.\n * This must be wrapped in a server action with 'use server' in your Next.js app.\n * \n * @param token - The JWT token from SAML authentication (with or without \"Bearer \" prefix)\n * @returns Result indicating success or failure with optional error message\n * \n * Usage in template actions.ts:\n * ```typescript\n * 'use server';\n * import { setSamlSessionImpl } from \"@replicated/portal-components/saml-handlers\";\n * import { traceServerAction } from \"@replicated/portal-components/observability\";\n * \n * async function setSamlSessionActionImpl(token: string) {\n * return setSamlSessionImpl(token);\n * }\n * \n * export const setSamlSessionAction = traceServerAction(\"setSamlSessionAction\", setSamlSessionActionImpl);\n * ```\n */\nexport async function setSamlSessionImpl(token: string): Promise<SetSamlSessionResult> {\n try {\n if (!token) {\n return { success: false, message: \"No token provided\" };\n }\n\n // Remove \"Bearer \" prefix if present\n const cleanToken = token.startsWith(\"Bearer \") ? token.slice(7) : token;\n\n // Dynamic import to ensure this only runs in server context\n const { cookies } = await import(\"next/headers\");\n const cookieStore = await cookies();\n\n // For cross-origin iframes over HTTP (repldev), we need sameSite: \"none\" + secure: true\n // Chrome allows this for localhost even over HTTP\n const isHttpOrigin = process.env.REPLICATED_APP_ORIGIN?.startsWith('http://');\n \n // Force secure: true and sameSite: \"none\" for repldev cross-origin iframe\n const secure = true;\n const sameSiteValue = isHttpOrigin ? \"none\" : \"lax\";\n\n // Use the string-based API which is compatible across Next.js versions\n cookieStore.set(\"portal_session\", cleanToken, {\n httpOnly: true,\n secure: secure,\n sameSite: sameSiteValue,\n path: \"/\"\n });\n\n return { success: true };\n } catch (error) {\n console.error(\"[saml-handlers] Error setting session:\", error);\n return { \n success: false, \n message: \"Failed to establish session\" \n };\n }\n}\n\n/**\n * Shared SAML ACS (Assertion Consumer Service) handler logic.\n * This proxies SAML responses from the IdP to the backend API.\n * \n * Flow:\n * 1. IdP POSTs SAMLResponse here\n * 2. Forward to backend /saml/acs\n * 3. Backend validates, creates JWT, returns 302 redirect\n * 4. Pass redirect through to browser to hit /saml/callback\n * \n * Usage in Next.js route handler:\n * ```typescript\n * import { handleSamlAcs } from \"@replicated/portal-components/saml-handlers\";\n * \n * export async function POST(request: NextRequest) {\n * return handleSamlAcs(request);\n * }\n * ```\n */\nexport async function handleSamlAcs(request: Request): Promise<Response> {\n try {\n const apiOrigin = getApiOrigin();\n \n // Get form data from IdP POST request\n const formData = await request.formData();\n \n // Forward to backend, don't follow redirects automatically\n const response = await fetch(`${apiOrigin}/saml/acs`, {\n method: 'POST',\n body: formData,\n redirect: 'manual',\n });\n \n // Backend should return 302 with Location header pointing to /saml/callback#token=...\n if (response.status === 302 || response.status === 301) {\n const location = response.headers.get('Location');\n if (location) {\n // Pass through the redirect to the browser\n return Response.redirect(location, response.status);\n }\n }\n \n // Handle error responses from backend\n console.error('[saml-acs] Error response from backend:', {\n status: response.status,\n statusText: response.statusText,\n });\n \n // Map status codes to user-friendly messages\n let errorMessage = 'SAML authentication failed';\n if (response.status === 401 || response.status === 403) {\n errorMessage = 'Authentication failed. Please check your credentials or contact your administrator.';\n } else if (response.status === 400) {\n errorMessage = 'Invalid SAML request. Please try again.';\n }\n \n // Redirect to error page with actual status code\n return Response.redirect(\n new URL(`/error?code=${response.status}&message=${encodeURIComponent(errorMessage)}`, request.url),\n 302\n );\n } catch (error) {\n console.error('[saml-acs] Error processing SAML response:', error);\n \n // Redirect to error page\n return Response.redirect(\n new URL(`/error?code=500&message=${encodeURIComponent('SAML authentication error')}`, request.url),\n 302\n );\n }\n}\n","import packageJson from \"../package.json\";\n\nexport const portalComponentsVersion = packageJson.version;\n\nexport type {\n ComponentAccessibilityMetadata,\n ComponentBehaviorMetadata,\n ComponentCategory,\n ComponentRegistryDocument,\n ComponentRegistryEntry,\n ComponentExampleMetadata,\n ComponentPerformanceMetadata,\n ComponentPropMetadata\n} from \"./types/metadata\";\n\nexport {\n createPortalTheme,\n portalThemeTokens\n} from \"./tokens\";\nexport type { PortalThemeTokens, PortalThemeOverrides } from \"./tokens\";\n\nexport * from \"./components\";\nexport * from \"./utils\";\nexport * from \"./saml-handlers\";\n\nexport {\n defineServerAction,\n fetchCustomBranding,\n fetchLicense,\n listReleases,\n initiateLogin,\n listSupportBundles,\n downloadSupportBundle,\n deleteSupportBundle,\n uploadSupportBundle,\n getSupportBundleUploadUrl,\n decodeJwtPayload,\n getCustomerIdFromToken,\n verifyMagicLink,\n // Dashboard actions\n fetchDashboardComposite,\n // Security actions\n getSecurityInfo,\n getSecurityInfoDiff,\n getSecurityInfoSBOM,\n downloadSecuritySBOM,\n // User settings actions\n fetchCurrentUser,\n updateUser,\n fetchNotifications,\n updateNotifications\n} from \"./actions\";\n\n// Client components have their own entry points - don't export from main index\n// See src/components/index.ts for the full list and import paths\nexport type {\n PortalActionContext,\n PortalActionVisibility,\n PortalServerActionDefinition,\n CustomBrandingResponse,\n FetchLicenseInput,\n FetchLicenseResult,\n ReleaseHelmChart,\n DownloadPortalRelease,\n ListReleasesResult,\n License,\n LicenseChannel,\n EntitlementField,\n EntitlementValue,\n CustomHostnameOverrides,\n PortalLicenseField,\n InitiateLoginInput,\n InitiateLoginResult,\n VerifyMagicLinkInput,\n VerifyMagicLinkResult,\n VerifyMagicLinkError,\n ListSupportBundlesInput,\n ListSupportBundlesResult,\n SupportBundleSummary,\n SupportBundleInsight,\n DownloadSupportBundleInput,\n DownloadSupportBundleResult,\n DeleteSupportBundleInput,\n DeleteSupportBundleResult,\n UploadSupportBundleCompleteInput,\n UploadSupportBundleCompleteResult,\n // Security types\n SecurityInstallType,\n SecurityScanSummary,\n SecurityScanWrapper,\n SecurityReleaseImage,\n GetSecurityInfoInput,\n GetSecurityInfoResult,\n SecurityInfoDiff,\n GetSecurityInfoDiffInput,\n GetSecurityInfoDiffResult,\n SBOMMetadata,\n GetSecurityInfoSBOMInput,\n GetSecurityInfoSBOMResult,\n DownloadSBOMInput,\n // Install types\n ChannelRelease,\n FetchChannelReleasesResult,\n // User settings types\n FetchCurrentUserInput,\n FetchCurrentUserResult,\n UserProfile,\n UpdateUserInput,\n UpdateUserResult,\n NotificationSetting,\n FetchNotificationsInput,\n FetchNotificationsResult,\n UpdateNotificationsInput,\n UpdateNotificationsResult\n} from \"./actions\";\n\nexport type { InitialSecurityData } from \"./components/security-card\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../../datadog/tracer.ts","../../package.json","../../src/tokens/index.ts","../../src/components/button.tsx","../../src/utils/api-client.ts","../../src/utils/observability/tracing.ts","../../src/actions/fetch-license.ts","../../src/utils/constants.ts","../../src/utils/branding.ts","../../src/utils/session.ts","../../src/utils/format.ts","../../src/utils/release-helpers.ts","../../src/actions/index.ts","../../src/components/license-details.tsx","../../src/components/top-nav.tsx","../../src/components/updates-card.tsx","../../src/components/support-card.tsx","../../src/components/user-settings.tsx","../../src/components/user-settings-card.tsx","../../src/components/team-settings-card.tsx","../../src/components/update-layout.tsx","../../src/saml-handlers.ts","../../src/index.ts"],"names":["cookies","rawFlag","isEnabled","tracer","Buffer","error","cache","raw","jsx","jsxs","Link","baseCardClass","headingClass","contentClass","itemClass","iconClass","footerClass"],"mappings":"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","file":"index.js","sourcesContent":["import type { Tracer, Span, init as ddTraceInit } from 'dd-trace';\nimport type { IncomingMessage } from 'http';\n\nconst rawFlag = String(process.env.USE_DATADOG_APM || '').toLowerCase();\nconst isEnabled = rawFlag === 'true';\n\nprocess.env.DD_TRACE_ENABLED = isEnabled ? '1' : '0';\n\nlet tracer: Tracer | null = null;\n\nif (isEnabled) {\n const serviceName = process.env.DD_SERVICE || 'enterprise-portal';\n const environment = process.env.DD_ENV || process.env.NODE_ENV || 'development';\n const version = process.env.DD_VERSION || process.env.NEXT_PUBLIC_VERSION || '0.0.0-dev';\n\n const agentHost = process.env.DD_AGENT_HOST || process.env.DATADOG_AGENT_HOST || '127.0.0.1';\n const agentPort = process.env.DD_TRACE_AGENT_PORT || '8126';\n\n process.env.DD_SERVICE = serviceName;\n process.env.DD_ENV = environment;\n if (version) {\n process.env.DD_VERSION = version;\n }\n process.env.DD_AGENT_HOST = agentHost;\n process.env.DD_TRACE_AGENT_PORT = agentPort;\n\n const dbmPropagationMode = (process.env.DD_DBM_PROPAGATION_MODE || 'full') as 'disabled' | 'service' | 'full';\n\n process.env.DD_DBM_PROPAGATION_MODE = dbmPropagationMode;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const ddTrace = require('dd-trace');\n tracer = (ddTrace.init as typeof ddTraceInit)({\n service: serviceName,\n env: environment,\n version,\n logInjection: true,\n runtimeMetrics: true,\n appsec: false,\n profiling: false,\n startupLogs: true, // Enable for debugging\n }) as Tracer;\n \n console.log(`[datadog] Tracer initialized: service=${serviceName}, env=${environment}, version=${version}, agent=${agentHost}:${agentPort}`);\n\n // Disable low-level network instrumentation for localhost connections\n tracer.use('dns', false);\n tracer.use('net', false);\n // Configure http plugin to normalize route patterns\n tracer.use('http', {\n server: {\n hooks: {\n request: (span?: Span, req?: IncomingMessage) => {\n if (!span) return;\n\n const url = req?.url || '';\n const method = req?.method || 'GET';\n const path = url.split('?')[0];\n\n // Drop Next.js internal requests\n if (path.startsWith('/_next/')) {\n // @ts-expect-error - using internal property to drop the trace\n span.context()._trace.isRecording = false;\n return;\n }\n\n const routePattern = getRoutePattern(path);\n\n span.setTag('resource.name', `${method} ${routePattern}`);\n span.setTag('http.route', routePattern);\n }\n }\n }\n });\n } catch (err) {\n // Do not crash the app if tracing fails to initialize\n console.error('[datadog] failed to initialize tracing', err);\n tracer = null;\n }\n}\n\n// Function to convert actual paths to route patterns\nconst getRoutePattern = (path: string): string => {\n // Define route patterns for dynamic routes in enterprise portal\n const routePatterns = [\n // Update instance routes - normalize dynamic segments (capture suffix to preserve sub-routes)\n { pattern: /^\\/update\\/instance\\/[^/]+(.*)$/, replacement: '/update/instance/[instanceId]$1' },\n ];\n\n for (const { pattern, replacement } of routePatterns) {\n if (pattern.test(path)) {\n return path.replace(pattern, replacement);\n }\n }\n\n // Return original path if no pattern matches\n return path;\n}\n\nexport default tracer;\n","{\n \"name\": \"@replicated/portal-components\",\n \"version\": \"0.0.21\",\n \"description\": \"Opinionated component library for Replicated enterprise portals\",\n \"license\": \"Apache-2.0\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/replicatedhq/enterprise-portal-components.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/replicatedhq/enterprise-portal-components/issues\"\n },\n \"homepage\": \"https://github.com/replicatedhq/enterprise-portal-components#readme\",\n \"main\": \"dist/index.js\",\n \"module\": \"dist/esm/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"style\": \"dist/styles.css\",\n \"files\": [\n \"dist\",\n \"components/metadata\",\n \"instrumentation.js\",\n \"instrumentation.d.ts\",\n \"datadog\"\n ],\n \"sideEffects\": [\n \"*.css\",\n \"*.scss\"\n ],\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/esm/index.js\",\n \"require\": \"./dist/index.js\"\n },\n \"./tokens\": {\n \"types\": \"./dist/tokens/index.d.ts\",\n \"import\": \"./dist/esm/tokens/index.js\",\n \"require\": \"./dist/tokens/index.js\"\n },\n \"./utils\": {\n \"types\": \"./dist/utils/index.d.ts\",\n \"import\": \"./dist/esm/utils/index.js\",\n \"require\": \"./dist/utils/index.js\"\n },\n \"./middleware\": {\n \"types\": \"./dist/middleware.d.ts\",\n \"edge-light\": \"./dist/esm/middleware.js\",\n \"worker\": \"./dist/esm/middleware.js\",\n \"import\": \"./dist/esm/middleware.js\",\n \"require\": \"./dist/middleware.js\",\n \"default\": \"./dist/esm/middleware.js\"\n },\n \"./actions\": {\n \"types\": \"./dist/actions/index.d.ts\",\n \"import\": \"./dist/esm/actions/index.js\",\n \"require\": \"./dist/actions/index.js\"\n },\n \"./actions/team-settings\": {\n \"types\": \"./dist/actions/team-settings.d.ts\",\n \"import\": \"./dist/esm/actions/team-settings.js\",\n \"require\": \"./dist/actions/team-settings.js\"\n },\n \"./actions/user-settings\": {\n \"types\": \"./dist/actions/user-settings.d.ts\",\n \"import\": \"./dist/esm/actions/user-settings.js\",\n \"require\": \"./dist/actions/user-settings.js\"\n },\n \"./actions/change-team\": {\n \"types\": \"./dist/actions/change-team.d.ts\",\n \"import\": \"./dist/esm/actions/change-team.js\",\n \"require\": \"./dist/actions/change-team.js\"\n },\n \"./actions/install-actions\": {\n \"types\": \"./dist/actions/install-actions.d.ts\",\n \"import\": \"./dist/esm/actions/install-actions.js\",\n \"require\": \"./dist/actions/install-actions.js\"\n },\n \"./actions/service-account\": {\n \"types\": \"./dist/actions/service-account.d.ts\",\n \"import\": \"./dist/esm/actions/service-account.js\",\n \"require\": \"./dist/actions/service-account.js\"\n },\n \"./actions/support-bundles\": {\n \"types\": \"./dist/actions/support-bundles.d.ts\",\n \"import\": \"./dist/esm/actions/support-bundles.js\",\n \"require\": \"./dist/actions/support-bundles.js\"\n },\n \"./actions/trial-signup\": {\n \"types\": \"./dist/actions/trial-signup.d.ts\",\n \"import\": \"./dist/esm/actions/trial-signup.js\",\n \"require\": \"./dist/actions/trial-signup.js\"\n },\n \"./install-actions\": {\n \"types\": \"./dist/install-actions.d.ts\",\n \"import\": \"./dist/esm/install-actions.js\",\n \"require\": \"./dist/install-actions.js\"\n },\n \"./license-details\": {\n \"types\": \"./dist/license-details.d.ts\",\n \"import\": \"./dist/esm/license-details.js\",\n \"require\": \"./dist/license-details.js\"\n },\n \"./support-bundle-collection-card\": {\n \"types\": \"./dist/support-bundle-collection-card.d.ts\",\n \"import\": \"./dist/esm/support-bundle-collection-card.js\",\n \"require\": \"./dist/support-bundle-collection-card.js\"\n },\n \"./support-bundles-card\": {\n \"types\": \"./dist/support-bundles-card.d.ts\",\n \"import\": \"./dist/esm/support-bundles-card.js\",\n \"require\": \"./dist/support-bundles-card.js\"\n },\n \"./upload-support-bundle-modal\": {\n \"types\": \"./dist/upload-support-bundle-modal.d.ts\",\n \"import\": \"./dist/esm/upload-support-bundle-modal.js\",\n \"require\": \"./dist/upload-support-bundle-modal.js\"\n },\n \"./top-nav\": {\n \"types\": \"./dist/top-nav.d.ts\",\n \"import\": \"./dist/esm/top-nav.js\",\n \"require\": \"./dist/top-nav.js\"\n },\n \"./install-card\": {\n \"types\": \"./dist/install-card.d.ts\",\n \"import\": \"./dist/esm/install-card.js\",\n \"require\": \"./dist/install-card.js\"\n },\n \"./license-card\": {\n \"types\": \"./dist/license-card.d.ts\",\n \"import\": \"./dist/esm/license-card.js\",\n \"require\": \"./dist/license-card.js\"\n },\n \"./updates-card\": {\n \"types\": \"./dist/updates-card.d.ts\",\n \"import\": \"./dist/esm/updates-card.js\",\n \"require\": \"./dist/updates-card.js\"\n },\n \"./support-card\": {\n \"types\": \"./dist/support-card.d.ts\",\n \"import\": \"./dist/esm/support-card.js\",\n \"require\": \"./dist/support-card.js\"\n },\n \"./install-targets\": {\n \"types\": \"./dist/install-targets.d.ts\",\n \"import\": \"./dist/esm/install-targets.js\",\n \"require\": \"./dist/install-targets.js\"\n },\n \"./linux-install-wizard\": {\n \"types\": \"./dist/linux-install-wizard.d.ts\",\n \"import\": \"./dist/esm/linux-install-wizard.js\",\n \"require\": \"./dist/linux-install-wizard.js\"\n },\n \"./helm-install-wizard\": {\n \"types\": \"./dist/helm-install-wizard.d.ts\",\n \"import\": \"./dist/esm/helm-install-wizard.js\",\n \"require\": \"./dist/helm-install-wizard.js\"\n },\n \"./online-instance-list\": {\n \"types\": \"./dist/online-instance-list.d.ts\",\n \"import\": \"./dist/esm/online-instance-list.js\",\n \"require\": \"./dist/online-instance-list.js\"\n },\n \"./instance-card\": {\n \"types\": \"./dist/instance-card.d.ts\",\n \"import\": \"./dist/esm/instance-card.js\",\n \"require\": \"./dist/instance-card.js\"\n },\n \"./airgap-instances\": {\n \"types\": \"./dist/airgap-instances.d.ts\",\n \"import\": \"./dist/esm/airgap-instances.js\",\n \"require\": \"./dist/airgap-instances.js\"\n },\n \"./update-layout\": {\n \"types\": \"./dist/update-layout.d.ts\",\n \"import\": \"./dist/esm/update-layout.js\",\n \"require\": \"./dist/update-layout.js\"\n },\n \"./user-settings-card\": {\n \"types\": \"./dist/user-settings-card.d.ts\",\n \"import\": \"./dist/esm/user-settings-card.js\",\n \"require\": \"./dist/user-settings-card.js\"\n },\n \"./user-settings\": {\n \"types\": \"./dist/user-settings.d.ts\",\n \"import\": \"./dist/esm/user-settings.js\",\n \"require\": \"./dist/user-settings.js\"\n },\n \"./team-settings-card\": {\n \"types\": \"./dist/team-settings-card.d.ts\",\n \"import\": \"./dist/esm/team-settings-card.js\",\n \"require\": \"./dist/team-settings-card.js\"\n },\n \"./team-settings\": {\n \"types\": \"./dist/team-settings.d.ts\",\n \"import\": \"./dist/esm/team-settings.js\",\n \"require\": \"./dist/team-settings.js\"\n },\n \"./release-history-panel\": {\n \"types\": \"./dist/release-history-panel.d.ts\",\n \"import\": \"./dist/esm/release-history-panel.js\",\n \"require\": \"./dist/release-history-panel.js\"\n },\n \"./release-notes-card\": {\n \"types\": \"./dist/release-notes-card.d.ts\",\n \"import\": \"./dist/esm/release-notes-card.js\",\n \"require\": \"./dist/release-notes-card.js\"\n },\n \"./error\": {\n \"types\": \"./dist/error.d.ts\",\n \"import\": \"./dist/esm/error.js\",\n \"require\": \"./dist/error.js\"\n },\n \"./error-page\": {\n \"types\": \"./dist/error-page.d.ts\",\n \"import\": \"./dist/esm/error-page.js\",\n \"require\": \"./dist/error-page.js\"\n },\n \"./pending-installations\": {\n \"types\": \"./dist/pending-installations.d.ts\",\n \"import\": \"./dist/esm/pending-installations.js\",\n \"require\": \"./dist/pending-installations.js\"\n },\n \"./team-selection\": {\n \"types\": \"./dist/team-selection.d.ts\",\n \"import\": \"./dist/esm/team-selection.js\",\n \"require\": \"./dist/team-selection.js\"\n },\n \"./top-nav-user-menu\": {\n \"types\": \"./dist/top-nav-user-menu.d.ts\",\n \"import\": \"./dist/esm/top-nav-user-menu.js\",\n \"require\": \"./dist/top-nav-user-menu.js\"\n },\n \"./login\": {\n \"types\": \"./dist/login.d.ts\",\n \"import\": \"./dist/esm/login.js\",\n \"require\": \"./dist/login.js\"\n },\n \"./security-card\": {\n \"types\": \"./dist/security-card.d.ts\",\n \"import\": \"./dist/esm/security-card.js\",\n \"require\": \"./dist/security-card.js\"\n },\n \"./join-team\": {\n \"types\": \"./dist/join-team.d.ts\",\n \"import\": \"./dist/esm/join-team.js\",\n \"require\": \"./dist/join-team.js\"\n },\n \"./trial-signup\": {\n \"types\": \"./dist/trial-signup.d.ts\",\n \"import\": \"./dist/esm/trial-signup.js\",\n \"require\": \"./dist/trial-signup.js\"\n },\n \"./service-accounts-tab\": {\n \"types\": \"./dist/service-accounts-tab.d.ts\",\n \"import\": \"./dist/esm/service-accounts-tab.js\",\n \"require\": \"./dist/service-accounts-tab.js\"\n },\n \"./observability\": {\n \"types\": \"./dist/utils/observability/index.d.ts\",\n \"import\": \"./dist/esm/utils/observability/index.js\",\n \"require\": \"./dist/utils/observability/index.js\"\n },\n \"./saml-handlers\": {\n \"types\": \"./dist/saml-handlers.d.ts\",\n \"import\": \"./dist/esm/saml-handlers.js\",\n \"require\": \"./dist/saml-handlers.js\"\n },\n \"./saml-callback-client\": {\n \"types\": \"./dist/saml-callback-client.d.ts\",\n \"import\": \"./dist/esm/saml-callback-client.js\",\n \"require\": \"./dist/saml-callback-client.js\"\n },\n \"./instrumentation\": \"./instrumentation.js\",\n \"./styles.css\": \"./dist/styles.css\",\n \"./metadata/registry.json\": \"./components/metadata/registry.json\"\n },\n \"scripts\": {\n \"clean\": \"rimraf dist\",\n \"build\": \"npm run clean && npm run registry:generate && npm run build:css && npm run build:instrumentation && tsup\",\n \"build:css\": \"tailwindcss -i ./src/styles.css -o ./dist/styles.css --config tailwind.config.ts\",\n \"build:instrumentation\": \"tsc instrumentation.ts --outDir . --declaration --module esnext --target es2022 --moduleResolution bundler --skipLibCheck && tsc datadog/tracer.ts --outDir datadog --declaration --module esnext --target es2022 --moduleResolution bundler --skipLibCheck\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"registry:generate\": \"tsx scripts/generate-registry.ts\",\n \"size\": \"size-limit\",\n \"release\": \"changeset\"\n },\n \"dependencies\": {\n \"classnames\": \"^2.5.1\",\n \"dd-trace\": \"^5.70.0\"\n },\n \"peerDependencies\": {\n \"lucide-react\": \">=0.400.0\",\n \"next\": \">=14.0.0\",\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\"\n },\n \"devDependencies\": {\n \"@changesets/cli\": \"^2.27.8\",\n \"lucide-react\": \"^0.468.0\",\n \"@size-limit/preset-big-lib\": \"^12.0.0\",\n \"@types/node\": \"^22.10.1\",\n \"@types/react\": \"^19.0.4\",\n \"@types/react-dom\": \"^19.0.3\",\n \"autoprefixer\": \"^10.4.20\",\n \"postcss\": \"^8.4.49\",\n \"react\": \"19.0.0\",\n \"react-dom\": \"19.0.0\",\n \"rimraf\": \"^6.0.1\",\n \"size-limit\": \"^12.0.0\",\n \"tailwindcss\": \"^3.4.17\",\n \"tslib\": \"^2.7.0\",\n \"tsup\": \"^8.3.5\",\n \"tsx\": \"^4.19.2\",\n \"typescript\": \"^5.6.3\"\n },\n \"engines\": {\n \"node\": \">=20\"\n },\n \"packageManager\": \"npm@10.9.0\",\n \"size-limit\": [\n {\n \"name\": \"core entry\",\n \"path\": \"dist/esm/index.js\",\n \"import\": \"{ Login }\",\n \"limit\": \"35 KB\",\n \"gzip\": true\n }\n ]\n}\n","type DeepPartial<T> = {\n [Key in keyof T]?: T[Key] extends Record<string, unknown>\n ? DeepPartial<T[Key]>\n : T[Key];\n};\n\nexport interface PortalThemeTokens {\n colors: {\n background: string;\n foreground: string;\n surfaceMuted: string;\n primary: string;\n onPrimary: string;\n secondary: string;\n onSecondary: string;\n success: string;\n warning: string;\n danger: string;\n };\n radii: {\n lg: string;\n md: string;\n sm: string;\n };\n spacing: Record<\"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\", string>;\n typography: {\n fontFamily: string;\n monoFamily: string;\n lineHeight: Record<\"tight\" | \"normal\" | \"relaxed\", string>;\n };\n shadows: {\n focus: string;\n overlay: string;\n };\n}\n\nconst baseTokens: PortalThemeTokens = {\n colors: {\n background: \"#0b0d12\",\n foreground: \"#f4f6fb\",\n surfaceMuted: \"#1b1f2a\",\n primary: \"#0d6efd\",\n onPrimary: \"#ffffff\",\n secondary: \"#6c757d\",\n onSecondary: \"#ffffff\",\n success: \"#22c55e\",\n warning: \"#fbbf24\",\n danger: \"#ef4444\"\n },\n radii: {\n lg: \"16px\",\n md: \"10px\",\n sm: \"6px\"\n },\n spacing: {\n xs: \"0.25rem\",\n sm: \"0.5rem\",\n md: \"0.75rem\",\n lg: \"1rem\",\n xl: \"1.5rem\"\n },\n typography: {\n fontFamily:\n \"Inter, 'SF Pro Display', 'Segoe UI', system-ui, -apple-system, sans-serif\",\n monoFamily: \"'JetBrains Mono', 'SFMono-Regular', Consolas, monospace\",\n lineHeight: {\n tight: \"1.2\",\n normal: \"1.5\",\n relaxed: \"1.75\"\n }\n },\n shadows: {\n focus: \"0 0 0 3px color-mix(in srgb, #0d6efd 35%, transparent)\",\n overlay: \"0px 20px 55px rgba(5, 7, 11, 0.5)\"\n }\n};\n\nconst mergeTokens = (\n base: PortalThemeTokens,\n overrides?: DeepPartial<PortalThemeTokens>\n): PortalThemeTokens => {\n if (!overrides) {\n return base;\n }\n\n const clone = structuredClone(base);\n\n const apply = (target: Record<string, any>, source: Record<string, any>) => {\n Object.entries(source).forEach(([key, value]) => {\n if (\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n typeof target[key] === \"object\"\n ) {\n apply(target[key], value);\n return;\n }\n\n target[key] = value;\n });\n };\n\n apply(clone as Record<string, any>, overrides as Record<string, any>);\n return clone;\n};\n\nexport const portalThemeTokens: PortalThemeTokens =\n mergeTokens(baseTokens);\n\nexport const createPortalTheme = (\n overrides?: DeepPartial<PortalThemeTokens>\n) => mergeTokens(baseTokens, overrides);\n\nexport type { DeepPartial as PortalThemeOverrides };\n","import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ReactNode\n} from \"react\";\n\nconst buttonVariants = [\"primary\", \"secondary\", \"ghost\", \"destructive\"] as const;\nconst buttonSizes = [\"sm\", \"md\", \"lg\"] as const;\n\nconst variantStyles: Record<ButtonVariant, string> = {\n primary:\n \"bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-primary\",\n secondary:\n \"bg-secondary/20 text-secondary-foreground hover:bg-secondary/30 focus-visible:ring-secondary\",\n ghost:\n \"bg-transparent text-primary hover:bg-primary/10 focus-visible:ring-primary/60\",\n destructive:\n \"bg-danger text-white hover:bg-danger/90 focus-visible:ring-danger\"\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n sm: \"h-8 px-3 text-sm\",\n md: \"h-10 px-4 text-sm\",\n lg: \"h-12 px-6 text-base\"\n};\n\nconst inlineFlexBase =\n \"inline-flex items-center justify-center gap-2 rounded-md font-medium tracking-tight transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-60\";\n\nconst Spinner = () => (\n <span className=\"inline-flex h-3.5 w-3.5 animate-spin items-center justify-center\">\n <span className=\"h-3 w-3 rounded-full border-2 border-transparent border-t-current\" />\n </span>\n);\n\nexport type ButtonVariant = (typeof buttonVariants)[number];\nexport type ButtonSize = (typeof buttonSizes)[number];\n\nexport interface ButtonProps extends ComponentPropsWithoutRef<\"button\"> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n isLoading?: boolean;\n leadingIcon?: ReactNode;\n trailingIcon?: ReactNode;\n}\n\nconst composeClassName = (\n ...values: Array<string | undefined | false>\n): string => values.filter(Boolean).join(\" \");\n\n/**\n * Button is the primary interactive primitive for triggering portal actions.\n * It is theme aware via CSS variables generated from portal tokens.\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = \"primary\",\n size = \"md\",\n type = \"button\",\n isLoading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n className,\n children,\n ...props\n },\n ref\n ) => {\n const computedLeading = isLoading ? <Spinner /> : leadingIcon;\n const computedDisabled = disabled ?? isLoading;\n\n return (\n <button\n ref={ref}\n type={type}\n className={composeClassName(\n inlineFlexBase,\n variantStyles[variant],\n sizeStyles[size],\n className\n )}\n aria-busy={isLoading || undefined}\n disabled={computedDisabled}\n {...props}\n >\n {computedLeading ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {computedLeading}\n </span>\n ) : null}\n <span className=\"flex-1 whitespace-nowrap\">{children}</span>\n {trailingIcon ? (\n <span aria-hidden=\"true\" className=\"inline-flex\">\n {trailingIcon}\n </span>\n ) : null}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n","/**\n * Centralized API client utility for handling authenticated requests\n * with automatic 401 detection, cookie deletion, and redirect.\n */\n\nexport interface ApiFetchOptions extends RequestInit {\n token?: string;\n}\n\nexport class UnauthorizedError extends Error {\n constructor(message = \"Unauthorized\") {\n super(message);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/**\n * Helper to check if an error is a Next.js redirect error.\n * These errors should NOT be caught as they control navigation flow.\n */\nexport function isRedirectError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"digest\" in error &&\n typeof (error as { digest?: unknown }).digest === \"string\" &&\n (error as { digest: string }).digest.startsWith(\"NEXT_REDIRECT\")\n );\n}\n\n/**\n * Fetch wrapper that automatically handles error responses by:\n * - 401: Redirecting to \"/\" with expired parameter\n * - 502, 503, 504: Redirecting to \"/error\" with status code\n * \n * This function should be used for all authenticated API calls in server actions.\n * \n * IMPORTANT: This must be called from a Server Action context, not directly from\n * a Server Component, because it modifies cookies.\n */\nexport async function authenticatedFetch(\n url: string,\n options: ApiFetchOptions = {}\n): Promise<Response> {\n const { token, ...fetchOptions } = options;\n\n // Add authorization header if token is provided\n const headers = new Headers(fetchOptions.headers);\n if (token) {\n headers.set(\"authorization\", `Bearer ${token}`);\n }\n\n const response = await fetch(url, {\n ...fetchOptions,\n headers\n });\n\n // Handle 401 Unauthorized\n if (response.status === 401) {\n await handle401();\n }\n\n // Handle server errors (502, 503, 504) by redirecting to error page\n if (response.status === 502 || response.status === 503 || response.status === 504) {\n await handleServerError(response.status);\n }\n\n return response;\n}\n\n/**\n * Handles 401 unauthorized responses by redirecting to the root path with a logout parameter.\n * \n * Note: We cannot delete cookies here because this is called during Server Component\n * render, not from a true Server Action invocation.\n * \n * The home page MUST check for the `?expired=1` parameter and delete the portal_session\n * cookie when present to avoid infinite loops. Example:\n * \n * ```typescript\n * // In your home page (app/page.tsx)\n * import { cookies } from \"next/headers\";\n * \n * export default async function Home({ searchParams }: { searchParams: { expired?: string } }) {\n * if (searchParams.expired === \"1\") {\n * const cookieStore = await cookies();\n * cookieStore.delete(\"portal_session\");\n * }\n * \n * const sessionStore = await cookies();\n * const session = sessionStore.get(\"portal_session\");\n * // ... rest of your logic\n * }\n * ```\n */\nasync function handle401(): Promise<never> {\n const { redirect } = await import(\"next/navigation\");\n \n // Redirect with expired parameter so the home page can delete the cookie\n return redirect(\"/?expired=1\");\n}\n\n/**\n * Helper to check if a URL is the error page itself.\n * Only matches the exact error page route, not URLs containing \"error\" elsewhere.\n * \n * @param url - The URL to check\n * @returns true if the URL is the error page (e.g., /error or /error?code=500)\n */\nfunction isErrorPage(url: string): boolean {\n try {\n // Try parsing as full URL (e.g., https://example.com/error)\n const urlObj = new URL(url);\n return urlObj.pathname === \"/error\";\n } catch {\n // If not a full URL, check as path string (e.g., /error or /error?code=500)\n return url === \"/error\" || url.startsWith(\"/error?\");\n }\n}\n\n/**\n * Handles server errors (502, 503, 504) by redirecting to the error page.\n * \n * The error page route should be created at `app/error/page.tsx` in the consuming\n * application and use the ErrorPage component. Example:\n * \n * ```typescript\n * // In your error page (app/error/page.tsx)\n * import { ErrorPage } from \"@replicated/portal-components/error-page\";\n * \n * export default function Error({ \n * searchParams \n * }: { \n * searchParams: { code?: string; source?: string } \n * }) {\n * const statusCode = searchParams.code ? parseInt(searchParams.code, 10) : undefined;\n * const sourceUrl = searchParams.source;\n * return <ErrorPage statusCode={statusCode} sourceUrl={sourceUrl} />;\n * }\n * ```\n */\nasync function handleServerError(statusCode: number): Promise<never> {\n const { redirect } = await import(\"next/navigation\");\n const { cookies } = await import(\"next/headers\");\n \n // Try to get the current URL from Next.js headers\n let sourceUrl: string | undefined;\n try {\n const { headers } = await import(\"next/headers\");\n const headersList = await headers();\n const referer = headersList.get(\"referer\");\n const host = headersList.get(\"host\");\n const pathname = headersList.get(\"x-invoke-path\") || headersList.get(\"x-forwarded-path\");\n \n // Don't use referer if it's the error page itself\n if (referer && !isErrorPage(referer)) {\n sourceUrl = referer;\n } else if (host && pathname) {\n const protocol = headersList.get(\"x-forwarded-proto\") || \"https\";\n sourceUrl = `${protocol}://${host}${pathname}`;\n }\n \n // If we couldn't determine source from headers, check for preserved source in cookie\n if (!sourceUrl || isErrorPage(sourceUrl)) {\n const cookieStore = await cookies();\n const preservedSource = cookieStore.get(\"portal_error_source\");\n if (preservedSource?.value) {\n sourceUrl = decodeURIComponent(preservedSource.value);\n // Clear the cookie after reading it\n cookieStore.delete(\"portal_error_source\");\n }\n }\n } catch (error) {\n // If we can't get headers, continue without source URL\n console.debug(\"[portal-components] Could not determine source URL\", error);\n }\n \n // Redirect to error page with status code and source URL parameters\n const params = new URLSearchParams({ code: String(statusCode) });\n if (sourceUrl) {\n params.set(\"source\", sourceUrl);\n }\n \n return redirect(`/error?${params.toString()}`);\n}\n","import type { Span, Tracer } from 'dd-trace';\n\n// Type for a function that has been wrapped with tracing (always returns a Promise)\ntype TracedFunction<T extends (...args: any[]) => any> = (\n ...args: Parameters<T>\n) => Promise<Awaited<ReturnType<T>>>;\n\n// Lazy-load tracer only when tracing is enabled\n// Using undefined to distinguish between \"not loaded yet\" and \"loaded but null\"\nlet tracerCache: Tracer | null | undefined = undefined;\n\nfunction getTracer(): Tracer | null {\n // Return cached result if already loaded (prevents race conditions and multiple initializations)\n if (tracerCache !== undefined) {\n return tracerCache;\n }\n\n // Check if tracing is enabled at runtime (consistent with datadog/tracer.ts and instrumentation.ts)\n const rawFlag = String(process.env.USE_DATADOG_APM || '').toLowerCase();\n const isEnabled = rawFlag === 'true';\n\n if (!isEnabled) {\n tracerCache = null;\n return null;\n }\n\n // Lazy load the tracer module only when needed\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const tracerModule = require('../../../datadog/tracer');\n const tracer = tracerModule.default || tracerModule;\n\n if (tracer && typeof (tracer as any).trace === 'function') {\n tracerCache = tracer as Tracer;\n return tracerCache;\n }\n } catch (err) {\n console.warn('Failed to load tracer:', err);\n }\n\n tracerCache = null;\n return null;\n}\n\n/**\n * Get the currently active span from the tracer's scope.\n * This can be used to pass span context to database calls.\n */\nexport function getActiveSpan(): Span | undefined {\n const activeTracer = getTracer();\n if (!activeTracer || !activeTracer.scope) {\n return undefined;\n }\n const active = activeTracer.scope().active();\n return active || undefined;\n}\n\nexport async function withTrace<T>(\n name: string,\n fn: (span?: Span) => Promise<T> | T,\n): Promise<T> {\n const activeTracer = getTracer();\n if (!activeTracer) {\n return fn(undefined);\n }\n\n return activeTracer.trace(name, async (span?: Span) => {\n if (span) {\n span.setTag('component', 'application');\n }\n try {\n const result = await fn(span);\n return result;\n } catch (error) {\n if (span) {\n span.setTag('error', error as any);\n }\n throw error;\n }\n });\n}\n\nexport function traceServerAction<T extends (...args: any[]) => any>(\n name: string,\n fn: T,\n): TracedFunction<T> {\n const spanName = name.startsWith('server.action.') ? name : `server.action.${name}`;\n\n const traced: TracedFunction<T> = async (...args: Parameters<T>) => {\n return withTrace(spanName, async (span) => {\n if (span) {\n span.setTag('component', 'server-action');\n }\n const result = await fn(...args);\n return result;\n });\n };\n\n return traced;\n}\n\nexport function traceFunction<T extends (...args: any[]) => any>(\n name: string,\n fn: T,\n): TracedFunction<T> {\n const traced: TracedFunction<T> = async (...args: Parameters<T>) => {\n return withTrace(name, async () => {\n const result = await fn(...args);\n return result;\n });\n };\n\n return traced;\n}\n","\"use server\";\n\nimport { cache } from \"react\";\nimport { cookies } from \"next/headers\";\nimport { getApiOrigin } from \"./index\";\nimport { authenticatedFetch } from \"../utils/api-client\";\n\nexport interface CustomHostnameOverrides {\n registry?: string;\n proxyRegistry?: string;\n replicatedApp?: string;\n}\n\nexport interface LicenseChannel {\n appId: string;\n licenseId: string;\n channelId: string;\n channelName: string;\n channelSlug: string;\n isSemverRequired: number;\n isDefault: number;\n pinnedChannelSequence?: number | null;\n customHostnameOverrides?: CustomHostnameOverrides;\n hasKurlInstaller: boolean;\n}\n\nexport interface EntitlementField {\n name: string;\n title: string;\n type: string;\n required: number;\n hidden: number;\n defaultVal: string;\n}\n\nexport interface EntitlementValue {\n name: string;\n value: string;\n}\n\nexport interface PortalLicenseField {\n key: string;\n label: string;\n value: string | null;\n isSecret?: boolean;\n}\n\nexport interface License {\n // API response fields (exact match with Go struct)\n id: string;\n appId: string;\n appName?: string | null;\n appIcon?: string | null;\n channels: LicenseChannel[];\n customerId: string;\n customerName: string;\n customerEmail?: string | null;\n createdAt: string;\n updatedAt: string;\n expireAt?: string | null;\n isExpired: boolean;\n isArchived: boolean;\n licenseType: string;\n sequence: number;\n isAirgapSupported: boolean;\n isGitopsSupported: boolean;\n isIdentityServiceSupported: boolean;\n isGeoaxisSupported: boolean;\n isSnapshotSupported: boolean;\n isDisasterRecoverySupported: boolean;\n isSupportBundleUploadSupported: boolean;\n isEmbeddedClusterDownloadEnabled: boolean;\n isEmbeddedClusterMultiNodeEnabled: boolean;\n isKotsInstallEnabled: boolean;\n isHelmInstallEnabled: boolean;\n isKurlInstallEnabled: boolean;\n isHelmAirgapEnabled: boolean;\n entitlementFields: EntitlementField[];\n entitlementValues: EntitlementValue[];\n\n // Backward compatibility (computed)\n expiresAt?: string | null;\n environment?: string;\n releaseChannels?: string[];\n installMethods?: string[];\n fields?: PortalLicenseField[];\n}\n\n// Helper function to derive install methods from license feature flags\nconst deriveInstallMethods = (licenseData: any): string[] => {\n const methods: string[] = [];\n \n if (licenseData.isKotsInstallEnabled) {\n methods.push(\"Replicated KOTS\");\n }\n if (licenseData.isHelmInstallEnabled) {\n methods.push(\"Helm\");\n }\n if (licenseData.isHelmAirgapEnabled) {\n methods.push(\"Helm Airgap\");\n }\n if (licenseData.isEmbeddedClusterDownloadEnabled || licenseData.isEmbeddedClusterMultiNodeEnabled) {\n methods.push(\"Embedded Cluster\");\n }\n if (licenseData.isKurlInstallEnabled) {\n methods.push(\"kURL\");\n }\n if (licenseData.isGitopsSupported) {\n methods.push(\"GitOps\");\n }\n \n return Array.from(new Set(methods));\n};\n\n// Helper function to convert entitlements to fields format for backward compatibility\nconst convertEntitlementsToFields = (\n entitlementFields: EntitlementField[],\n entitlementValues: EntitlementValue[]\n): PortalLicenseField[] => {\n const valuesMap = new Map<string, string>();\n entitlementValues.forEach(ev => {\n valuesMap.set(ev.name, ev.value);\n });\n \n return entitlementFields\n .filter(field => field.hidden === 0)\n .map(field => ({\n key: field.name,\n label: field.title || field.name,\n value: valuesMap.get(field.name) || field.defaultVal || null,\n isSecret: field.type === \"Password\"\n }));\n};\n\n/**\n * Internal implementation of fetching license data.\n *\n * Reads from /enterprise-portal/license API response.\n */\nasync function fetchLicenseCore(): Promise<License> {\n const sessionStore = await cookies();\n const session = sessionStore.get(\"portal_session\");\n const token = session?.value;\n\n if (!token) {\n throw new Error(\"No session found - user must be authenticated\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/license`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching license via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n Accept: \"application/json\"\n }\n });\n\n if (!response.ok) {\n throw new Error(\n `License request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n const licenseData = envelope.data;\n\n // Add computed properties for backward compatibility\n const license: License = {\n ...licenseData,\n // Alias fields for backward compatibility\n expiresAt: licenseData.expireAt,\n environment: licenseData.licenseType,\n // Extract channel names from channels array\n releaseChannels: (licenseData.channels || []).map((ch: LicenseChannel) => ch.channelName),\n // Derive install methods from feature flags\n installMethods: deriveInstallMethods(licenseData),\n // Convert entitlements to fields format\n fields: convertEntitlementsToFields(licenseData.entitlementFields || [], licenseData.entitlementValues || [])\n };\n\n return license;\n}\n\n/**\n * Fetches license data including entitlements and feature flags.\n *\n * This function is cached per-request to avoid duplicate API calls.\n */\nconst fetchLicenseImpl = cache(fetchLicenseCore);\nexport const fetchLicense = fetchLicenseImpl;\n","/**\n * Default globe favicon matching the CiGlobe icon (Circum Icons)\n * Used as fallback when custom branding doesn't provide a favicon\n */\nexport const 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\";\n\n/**\n * Default primary brand color\n */\nexport const DEFAULT_PRIMARY_COLOR = \"#4f46e5\";\n\n/**\n * Default secondary brand color\n */\nexport const DEFAULT_SECONDARY_COLOR = \"#6366f1\";\n\n/**\n * Check if the API origin is HTTP (used for repldev environments)\n * This determines cookie security settings for cross-origin iframes\n * @returns true if the API origin starts with http:// (not https://)\n */\nexport const isHttpApiOrigin = (): boolean => {\n return process.env.REPLICATED_APP_ORIGIN?.startsWith('http://') || false;\n};\n","import { Buffer } from \"node:buffer\";\nimport { DEFAULT_PRIMARY_COLOR, DEFAULT_SECONDARY_COLOR } from \"./constants\";\n\ninterface RawBranding {\n brandingData?: string;\n}\n\nexport type BackgroundType = \"minimal\" | \"custom\" | \"image\";\n\ninterface BrandingResult {\n logo?: string;\n title?: string;\n favicon?: string;\n primaryColor: string;\n secondaryColor: string;\n supportPortalLink?: string;\n background?: BackgroundType;\n backgroundImage?: string;\n backgroundGradientStart?: string;\n backgroundGradientEnd?: string;\n}\n\n/**\n * Normalizes and validates CSS color values to prevent CSS injection attacks.\n * Only supports hex color format (#rgb or #rrggbb) as that's what the API sends.\n * \n * @param color - The color value to normalize\n * @returns The normalized hex color or undefined if invalid\n */\nexport const normalizeColor = (color?: string) => {\n if (!color || typeof color !== \"string\") {\n return undefined;\n }\n\n const trimmed = color.trim();\n \n // Validate hex colors only (#rgb or #rrggbb)\n if (/^#?[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/.test(trimmed)) {\n return trimmed.startsWith(\"#\") ? trimmed : `#${trimmed}`;\n }\n\n // Invalid color format - reject to prevent CSS injection\n console.debug(\"[portal-components] Invalid color format rejected (only hex supported):\", trimmed);\n return undefined;\n};\n\n/**\n * Validates and sanitizes a URL for safe use in CSS url() functions.\n * This prevents CSS injection attacks by validating the URL format and\n * escaping characters that could break out of the url() context.\n * \n * @param url - The URL to validate and sanitize\n * @returns The sanitized URL or undefined if invalid\n */\nexport const sanitizeUrlForCss = (url?: string): string | undefined => {\n if (!url || typeof url !== \"string\") {\n return undefined;\n }\n\n const trimmed = url.trim();\n \n // Validate URL format: must be http(s) or data URL\n try {\n const urlObj = new URL(trimmed);\n if (![\"http:\", \"https:\", \"data:\"].includes(urlObj.protocol)) {\n console.debug(\"[portal-components] Invalid URL protocol for background image:\", urlObj.protocol);\n return undefined;\n }\n } catch {\n console.debug(\"[portal-components] Invalid URL format for background image:\", trimmed);\n return undefined;\n }\n\n // Escape characters that could break out of CSS url() context\n // These include: ), \", ', \\, and control characters\n const escaped = trimmed\n .replace(/\\\\/g, \"\\\\\\\\\") // Escape backslashes first\n .replace(/\\)/g, \"\\\\)\") // Escape closing parenthesis\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/[\\x00-\\x1F\\x7F]/g, \"\"); // Remove control characters\n\n return escaped;\n};\n\nexport const decodeBranding = ({ brandingData }: RawBranding): BrandingResult => {\n if (!brandingData || typeof brandingData !== \"string\") {\n return {\n primaryColor: DEFAULT_PRIMARY_COLOR,\n secondaryColor: DEFAULT_SECONDARY_COLOR\n };\n }\n\n try {\n const decoded = Buffer.from(brandingData, \"base64\").toString(\"utf-8\");\n const parsed = JSON.parse(decoded) as Record<string, unknown>;\n\n const logo = typeof parsed.logo === \"string\" ? parsed.logo : undefined;\n const titleRaw = typeof parsed.title === \"string\" ? parsed.title.trim() : \"\";\n const title = titleRaw ? titleRaw : undefined;\n const favicon = typeof parsed.favicon === \"string\" ? parsed.favicon : undefined;\n\n // Support both camelCase and snake_case field names for primary/secondary colors\n const primaryColorRaw = (parsed.primaryColor ?? parsed.primary_color) as string | undefined;\n const secondaryColorRaw = (parsed.secondaryColor ?? parsed.secondary_color) as string | undefined;\n const primaryColor = normalizeColor(primaryColorRaw);\n const secondaryColor = normalizeColor(secondaryColorRaw);\n\n // Support portal link\n const supportPortalLink = typeof parsed.supportPortalLink === \"string\" ? parsed.supportPortalLink : undefined;\n\n // Background customization\n const backgroundRaw = parsed.background as string | undefined;\n const background = (backgroundRaw === \"minimal\" || backgroundRaw === \"custom\" || backgroundRaw === \"image\")\n ? backgroundRaw\n : undefined;\n // Validate and sanitize background image URL to prevent CSS injection\n const backgroundImage = sanitizeUrlForCss(parsed.backgroundImage as string | undefined);\n // customColor1/customColor2 are for the background gradient\n const backgroundGradientStart = normalizeColor(parsed.customColor1 as string | undefined);\n const backgroundGradientEnd = normalizeColor(parsed.customColor2 as string | undefined);\n\n return {\n logo,\n title,\n favicon,\n primaryColor: primaryColor || DEFAULT_PRIMARY_COLOR,\n secondaryColor: secondaryColor || DEFAULT_SECONDARY_COLOR,\n supportPortalLink,\n background,\n backgroundImage,\n backgroundGradientStart,\n backgroundGradientEnd\n };\n } catch (error) {\n console.debug(\"[portal-components] unable to parse branding JSON\", error);\n return {\n primaryColor: DEFAULT_PRIMARY_COLOR,\n secondaryColor: DEFAULT_SECONDARY_COLOR\n };\n }\n};\n","/**\n * Session validation utilities for handling authentication tokens.\n */\n\nimport { getApiOrigin } from \"../actions/index\";\n\n/**\n * Validates a session token by making a lightweight authenticated request.\n * Returns true if valid, false if invalid (401).\n * \n * This should be called from Server Components (like the home page) to validate\n * the session cookie before rendering authenticated content.\n */\nexport async function validateSession(token: string): Promise<boolean> {\n if (!token || typeof token !== \"string\" || !token.trim()) {\n return false;\n }\n\n try {\n // Make a lightweight request to check token validity\n // NEW: Using Enterprise Portal API user endpoint (fast and no customer_id needed)\n const endpoint = `${getApiOrigin()}/enterprise-portal/user`;\n\n const response = await fetch(endpoint, {\n method: \"GET\",\n headers: {\n authorization: `Bearer ${token}`\n },\n // Short timeout for validation\n signal: AbortSignal.timeout(5000)\n });\n\n // 200 = valid, 401 = invalid, anything else we'll treat as temporarily valid\n if (response.status === 401) {\n return false;\n }\n\n return response.ok;\n } catch (error) {\n // On error, assume valid to avoid blocking users during transient failures\n console.warn(\"[portal-components] session validation error:\", error);\n return true;\n }\n}\n\n/**\n * Deletes the portal_session cookie.\n * This MUST be called from a Server Action or Route Handler, not from Server Component render.\n * \n * Usage example in a Server Action:\n * ```typescript\n * \"use server\";\n * import { deleteSessionCookie } from \"@replicated/portal-components/utils\";\n * export async function logout() {\n * await deleteSessionCookie();\n * redirect(\"/\");\n * }\n * ```\n */\nexport async function deleteSessionCookie(): Promise<void> {\n const { cookies } = await import(\"next/headers\");\n const cookieStore = await cookies();\n cookieStore.delete(\"portal_session\");\n}\n","/**\n * Format bytes to human-readable string\n * @param bytes - Number of bytes\n * @param decimals - Number of decimal places (default: 1)\n * @returns Formatted string (e.g., \"1.5 MB\")\n */\nexport function formatBytes(bytes: number, decimals = 1): string {\n if (bytes === 0) return \"0 Bytes\";\n\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\"];\n\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\n/**\n * Format date string to short numeric date (no time)\n * @param dateString - ISO date string or null/undefined\n * @returns Formatted string (e.g., \"01/27/2026\") or \"Never\" if no date\n */\nexport function formatDateShort(dateString?: string | null): string {\n if (!dateString) return \"Never\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleDateString(\"en-US\", {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\"\n });\n}\n\n/**\n * Format date string to human-readable local timestamp\n * @param dateString - ISO date string or null/undefined\n * @returns Formatted string (e.g., \"Jan 27, 2026, 10:32 PM\") or \"Never\" if no date\n */\nexport function formatDate(dateString?: string | null): string {\n if (!dateString) return \"Never\";\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true\n });\n}\n\n/**\n * Format date string to human-readable UTC timestamp\n * @param dateString - ISO date string\n * @returns Formatted string (e.g., \"01/27/2026, 22:32:39 UTC\")\n */\nexport function formatDateTime(dateString: string): string {\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleString(\"en-US\", {\n timeZone: \"UTC\",\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false\n }) + \" UTC\";\n}\n\n/**\n * Format date string to user-friendly local timestamp with 12-hour time\n * @param dateString - ISO date string or null/undefined\n * @returns Formatted string (e.g., \"1/27/2026, 10:32 PM\") or \"N/A\" if not provided\n */\nexport function formatDateTimeLocal(dateString?: string | null): string {\n if (!dateString) return \"N/A\";\n\n try {\n const date = new Date(dateString);\n if (isNaN(date.getTime())) {\n return dateString;\n }\n return date.toLocaleDateString(\"en-US\", {\n month: \"numeric\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n hour12: true\n });\n } catch {\n return \"N/A\";\n }\n}\n","import type { DownloadPortalRelease } from \"../actions\";\nimport type { ReleaseEntry } from \"../components/release-history-panel\";\n\nexport type ReleaseNotesMode = \"markdown\" | \"items\";\n\nexport interface ConvertToReleaseEntryOptions {\n releaseNotesMode: ReleaseNotesMode;\n}\n\n/**\n * Converts a DownloadPortalRelease to a ReleaseEntry for display\n * @param release - The release data from the API\n * @param channelName - The channel name for display\n * @param options - Options for how to format the release entry\n * @returns A ReleaseEntry ready for display\n */\nexport function convertToReleaseEntry(\n release: DownloadPortalRelease,\n channelName: string,\n options: ConvertToReleaseEntryOptions\n): ReleaseEntry {\n const sections: ReleaseEntry[\"sections\"] = [];\n\n // Add release notes section\n if (release.release_notes && release.release_notes.trim().length > 0) {\n if (options.releaseNotesMode === \"markdown\") {\n // Markdown mode: use raw markdown as description\n sections.push({\n title: \"Release Notes\",\n description: release.release_notes\n });\n } else {\n // Items mode: split into individual items\n const releaseNotesItems = release.release_notes\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n\n sections.push({\n title: \"Release Notes\",\n description: releaseNotesItems.length === 0 ? release.release_notes : undefined,\n items: releaseNotesItems.length > 0 ? releaseNotesItems : undefined\n });\n }\n }\n\n // Add helm charts section\n const charts = release.helm_charts\n ? release.helm_charts\n .filter((chart) => !chart.is_kots_installer_only)\n .map((chart) => `${chart.name} v${chart.version}`)\n : [];\n\n if (charts.length > 0) {\n sections.push({\n title: \"Helm Charts\",\n items: charts,\n description: \"Latest chart versions included in this release.\"\n });\n }\n\n return {\n version: release.label || `Release ${release.release_sequence}`,\n channel: channelName || `Channel ${release.channel_sequence}`,\n releasedAt: release.release_date,\n sections\n };\n}\n","/**\n * Light-weight type helpers for defining Server Actions that align with the\n * enterprise portal guardrails. The component library does not implement\n * specific actions, but it exports helpers so downstream portals can describe\n * their actions with consistent metadata.\n */\n\nimport { Buffer } from \"node:buffer\";\nimport { cache } from \"react\";\nimport { authenticatedFetch } from \"../utils/api-client\";\nimport { traceServerAction } from \"../utils/observability\";\nimport type { License, PortalLicenseField } from \"./fetch-license\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Gets the base API origin from environment, with trailing slashes removed.\n */\nexport const getApiOrigin = (): string => {\n return (process.env.REPLICATED_APP_ORIGIN || \"https://replicated.app\").replace(/\\/+$/, \"\");\n};\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type PortalActionVisibility = \"vendor\" | \"customer\";\n\nexport interface PortalActionContext {\n vendorId: string;\n licenseId: string;\n userId: string;\n signal?: AbortSignal;\n}\n\nexport interface PortalServerActionDefinition<Input, Output> {\n id: string;\n description: string;\n visibility: PortalActionVisibility;\n tags: string[];\n run: (input: Input, context?: PortalActionContext) => Promise<Output>;\n}\n\nexport const defineServerAction = <Input, Output>(\n definition: PortalServerActionDefinition<Input, Output>\n) => definition;\n\nexport interface CreateServiceAccountInput {\n token: string;\n name: string;\n}\n\nexport interface ServiceAccountData {\n id: string;\n customerId: string;\n token: string;\n accountName: string;\n isRevoked: boolean;\n createdAt: string;\n emailAddress: string;\n}\n\nexport interface CreateServiceAccountResult {\n service_account: ServiceAccountData;\n token: string;\n}\n\nexport const createServiceAccount = defineServerAction<\n CreateServiceAccountInput,\n CreateServiceAccountResult\n>({\n id: \"service-account/create\",\n description: \"Creates a service account for installing applications\",\n visibility: \"customer\",\n tags: [\"service-account\", \"install\"],\n async run({ token, name }) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Service account creation requires a session token\");\n }\n\n if (!name || typeof name !== \"string\" || !name.trim()) {\n throw new Error(\"Service account name is required\");\n }\n\n // NEW: Use Enterprise Portal API endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\n \"[portal-components] creating service account via %s (Enterprise Portal API)\",\n endpoint\n );\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ account_name: name.trim() })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(\n `Service account creation failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data: CreateServiceAccountResult = await response.json();\n return data;\n }\n});\n\nexport interface InitiateLoginInput {\n email: string;\n}\n\nexport interface InitiateLoginResult {\n status: \"ok\" | \"saml_redirect\";\n requestedAt: string;\n message: string;\n /** If SAML redirect is required, this contains the info needed to redirect */\n saml?: {\n redirectRequired: true;\n customerId: string;\n email: string;\n appSlug: string;\n };\n}\n\n/**\n * Reference server action for initiating the passwordless login flow.\n * Real portals should replace the simulated delay with a call to their auth API.\n */\nexport const initiateLogin = defineServerAction<\n InitiateLoginInput,\n InitiateLoginResult\n>({\n id: \"auth/initiate-login\",\n description:\n \"Begins the passwordless login flow by dispatching a magic link email.\",\n visibility: \"customer\",\n tags: [\"auth\", \"login\", \"session\"],\n async run(input) {\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/magic-link`;\n const appSlug = process.env.PORTAL_APP_SLUG;\n if (!appSlug) {\n throw new Error(\"PORTAL_APP_SLUG is not configured\");\n }\n const portalOrigin =\n process.env.PORTAL_ORIGIN ?? \"https://enterprise.replicated.com\";\n const redirectUri = `${portalOrigin.replace(/\\/+$/, \"\")}/${appSlug}/login`;\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({\n app_slug: appSlug,\n email_address: input.email,\n redirect_uri: redirectUri\n })\n });\n\n if (!response.ok) {\n throw new Error(\n `Magic link request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n\n // Check if SAML redirect is required\n if (data.saml_redirect_required && data.saml_customer_id) {\n return {\n status: \"saml_redirect\",\n requestedAt: new Date().toISOString(),\n message: \"SAML authentication required\",\n saml: {\n redirectRequired: true,\n customerId: data.saml_customer_id,\n email: input.email,\n appSlug\n }\n };\n }\n\n return {\n status: \"ok\",\n requestedAt: new Date().toISOString(),\n message: `Magic link requested for ${input.email}`\n };\n }\n});\n\nexport interface VerifyMagicLinkInput {\n nonce: string;\n}\n\nexport interface VerifyMagicLinkResult {\n token: string;\n raw: unknown;\n}\n\nexport interface VerifyMagicLinkError {\n code: \"invalid_code\" | \"expired\" | \"unknown\";\n message: string;\n isExpired?: boolean;\n}\n\nexport const verifyMagicLink = defineServerAction<\n VerifyMagicLinkInput,\n VerifyMagicLinkResult\n>({\n id: \"auth/verify-magic-link\",\n description: \"Verifies the 12-digit code provided via email and returns a JWT.\",\n visibility: \"customer\",\n tags: [\"auth\", \"login\", \"verify\"],\n async run({ nonce }) {\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/magic-link/verify`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\n \"[portal-components] verifying magic link via %s\",\n endpoint\n );\n }\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({ nonce })\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n // Check if the response indicates an expired link\n try {\n const errorBody = await response.json();\n if (errorBody?.is_expired === true) {\n const error: VerifyMagicLinkError = {\n code: \"expired\",\n message: \"Magic link has expired. A new link has been sent to your email.\",\n isExpired: true\n };\n throw error;\n }\n } catch (parseError) {\n // If we already threw an error, re-throw it\n if ((parseError as VerifyMagicLinkError)?.code === \"expired\") {\n throw parseError;\n }\n // Otherwise fall through to invalid_code\n }\n\n const error: VerifyMagicLinkError = {\n code: \"invalid_code\",\n message: \"Incorrect code, check your email and try again.\"\n };\n throw error;\n }\n const error: VerifyMagicLinkError = {\n code: \"unknown\",\n message: `Magic link verification failed (${response.status} ${response.statusText})`\n };\n throw error;\n }\n\n const payload = await response.json();\n const token = payload?.token ?? payload?.jwt ?? payload?.access_token;\n if (typeof token !== \"string\") {\n throw new Error(\"Magic link verification succeeded but no token returned\");\n }\n\n return { token, raw: payload };\n }\n});\n\nexport interface CustomBrandingResponse {\n brandingData: string;\n documentation: unknown;\n}\n\n// License types are now defined in ./fetch-license.ts\n\nexport interface ListSupportBundlesInput {\n token: string;\n}\n\nexport interface SupportBundleInsight {\n level: string;\n primary: string;\n key?: string;\n detail?: string;\n}\n\nexport interface SupportBundleSummary {\n id: string;\n createdAt?: string;\n status?: string;\n size?: number;\n instanceId?: string;\n insights?: SupportBundleInsight[];\n metadata?: Record<string, unknown>;\n}\n\nexport interface ListSupportBundlesResult {\n bundles: SupportBundleSummary[];\n totalCount: number;\n raw: unknown;\n}\n\nexport interface DownloadSupportBundleInput {\n token: string;\n bundleId: string;\n}\n\nexport interface DownloadSupportBundleResult {\n signedUrl: string;\n}\n\nexport interface DeleteSupportBundleInput {\n token: string;\n bundleId: string;\n}\n\nexport interface DeleteSupportBundleResult {\n success: boolean;\n}\n\nexport interface UploadSupportBundleInput {\n token: string;\n appId: string;\n}\n\nexport interface UploadSupportBundleResult {\n uploadUrl: string;\n appId: string;\n}\n\nexport interface UploadSupportBundleCompleteInput {\n token: string;\n appId: string;\n fileContent: ArrayBuffer;\n contentLength: number;\n}\n\nexport interface UploadSupportBundleCompleteResult {\n bundleId: string;\n slug: string;\n}\n\n// Re-export fetchLicense and types from separate file to avoid server-only imports in client bundles\nexport type { License, LicenseChannel, EntitlementField, EntitlementValue, CustomHostnameOverrides, PortalLicenseField } from \"./fetch-license\";\nexport { fetchLicense } from \"./fetch-license\";\n\n// FetchLicense types - kept for backward compatibility\nexport interface FetchLicenseInput {\n // No input needed - gets session internally\n}\n\nexport type FetchLicenseResult = License;\n\n\nexport interface FetchCustomersInput {\n token: string;\n}\n\nexport interface Customer {\n id: string;\n name: string;\n licenseId: string;\n licenseType: string;\n expiresAt: string;\n isEnterprisePortalEnabled: boolean;\n}\n\nexport interface FetchCustomersResult {\n customers: Customer[];\n}\n\nexport interface SwitchCustomerInput {\n token: string;\n customerId: string;\n}\n\nexport interface SwitchCustomerResult {\n token: string;\n}\n\nexport interface ReleaseHelmChart {\n name: string;\n version: string;\n error?: string;\n is_kots_installer_only?: boolean;\n}\n\nexport interface DownloadPortalRelease {\n channel_sequence: number;\n release_sequence: number;\n is_required: boolean;\n has_kurl_installer: boolean;\n release_date: string;\n label: string;\n release_notes: string;\n download_link: string;\n build_status: string;\n last_update_time: string;\n checksum: string;\n airgap_bundle_images: string[];\n helm_images: string[];\n helm_charts: ReleaseHelmChart[];\n target_kots_version: string;\n embedded_cluster_airgap_bundle_url: string;\n has_ec_installer: boolean;\n ec_version: string;\n ec_replicated_app_domain: string;\n ec_proxy_registry_domain: string;\n}\n\nexport interface ListReleasesResult {\n releases: DownloadPortalRelease[];\n totalCount: number;\n}\n\n/**\n * Internal implementation of fetchCustomBranding.\n * Wrapped with React's cache() to deduplicate calls within a single request.\n *\n * Updated to use the new Enterprise Portal API /enterprise-portal/public/branding endpoint\n * which returns clean, non-base64 encoded data.\n */\nconst fetchCustomBrandingImpl = async (): Promise<CustomBrandingResponse> => {\n const appSlug = process.env.PORTAL_APP_SLUG;\n\n if (!appSlug) {\n throw new Error(\"PORTAL_APP_SLUG is not configured\");\n }\n\n const url = `${getApiOrigin()}/enterprise-portal/public/branding?app_slug=${encodeURIComponent(\n appSlug\n )}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\n \"[portal-components] fetching custom branding via %s (Enterprise Portal API)\",\n url\n );\n }\n\n const response = await fetch(url, {\n headers: {\n accept: \"application/json\"\n }\n });\n\n if (!response.ok) {\n throw new Error(\n `Custom branding request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n\n // New Enterprise Portal API returns clean data, not base64 encoded\n // Map the new field names to the old structure for compatibility\n const brandingObject = {\n logo: payload.logoUrl,\n title: payload.title,\n primaryColor: payload.primaryColor,\n secondaryColor: payload.secondaryColor,\n favicon: payload.faviconUrl,\n supportPortalLink: payload.supportPortalLink || \"\",\n background: payload.background,\n backgroundImage: payload.backgroundImage,\n customColor1: payload.customColor1,\n customColor2: payload.customColor2,\n };\n\n // Encode to base64 to maintain compatibility with existing decodeBranding function\n const brandingData = Buffer.from(JSON.stringify(brandingObject)).toString(\"base64\");\n\n return {\n brandingData,\n documentation: null // Documentation not included in new API's public endpoint\n };\n};\n\n/**\n * Fetches custom branding for the portal.\n * This function is cached per-request to avoid duplicate API calls when called\n * from multiple components (e.g., TopNav and page components).\n */\nexport const fetchCustomBranding = cache(fetchCustomBrandingImpl);\n\nexport const decodeJwtPayload = (token: string): Record<string, unknown> => {\n const parts = token.split(\".\");\n if (parts.length !== 3) {\n throw new Error(\"Invalid JWT received\");\n }\n\n const payloadSegment = parts[1];\n if (!payloadSegment) {\n throw new Error(\"JWT payload segment missing\");\n }\n\n const padded = payloadSegment.padEnd(\n payloadSegment.length + ((4 - (payloadSegment.length % 4)) % 4),\n \"=\"\n );\n const decoded = Buffer.from(padded, \"base64\").toString(\"utf-8\");\n return JSON.parse(decoded) as Record<string, unknown>;\n};\n\n/**\n * Extracts customer ID from JWT token. Throws if extraction fails.\n */\nexport const getCustomerIdFromToken = (token: string): string => {\n const payload = decodeJwtPayload(token);\n const customerId = payload?.customer_id || payload?.customerId;\n if (typeof customerId !== \"string\" || !customerId.trim()) {\n throw new Error(\"Unable to determine customer_id from session token\");\n }\n return customerId.trim();\n};\n\nconst resolveSupportBundlesEndpoint = () => {\n const fallback = `${getApiOrigin()}/v3/supportbundles`;\n const explicit = process.env.SUPPORT_BUNDLES_ENDPOINT;\n\n if (!explicit) {\n return new URL(fallback);\n }\n\n try {\n return new URL(explicit);\n } catch (error) {\n console.warn(\n `[portal-components] invalid SUPPORT_BUNDLES_ENDPOINT, using fallback`,\n error\n );\n return new URL(fallback);\n }\n};\n\nexport const listSupportBundles = defineServerAction<\n ListSupportBundlesInput,\n ListSupportBundlesResult\n>({\n id: \"support/list-bundles\",\n description:\n \"Fetches support bundles associated with the customer found in the portal session JWT.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle listing requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const url = `${getApiOrigin()}/enterprise-portal/support-bundles`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching support bundles via %s (Enterprise Portal API)\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (context?.signal?.aborted) {\n throw new Error(\"Support bundles request was aborted\");\n }\n\n if (!response.ok) {\n throw new Error(\n `Support bundles request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n // Extract from Enterprise Portal API envelope\n const raw = payload.data;\n\n const rawRecord =\n raw && typeof raw === \"object\" ? (raw as Record<string, unknown>) : undefined;\n\n const parseInsights = (raw: unknown): SupportBundleInsight[] | undefined => {\n if (!Array.isArray(raw)) return undefined;\n return raw\n .filter((i): i is Record<string, unknown> => i && typeof i === \"object\")\n .map((i) => ({\n level: String(i.level ?? \"\"),\n primary: String(i.primary ?? \"\"),\n key: typeof i.key === \"string\" ? i.key : undefined,\n detail: typeof i.detail === \"string\" ? i.detail : undefined\n }));\n };\n\n const bundles: SupportBundleSummary[] = Array.isArray(\n rawRecord?.supportBundles\n )\n ? (rawRecord?.supportBundles as unknown[]).map((item) => {\n if (!item || typeof item !== \"object\") {\n return {\n id: \"\",\n createdAt: undefined,\n status: undefined,\n size: undefined,\n instanceId: undefined,\n insights: undefined,\n metadata: undefined\n };\n }\n\n const record = item as Record<string, unknown>;\n return {\n id: String(record.id ?? \"\"),\n createdAt:\n typeof record.createdAt === \"string\"\n ? (record.createdAt as string)\n : undefined,\n status:\n typeof record.status === \"string\"\n ? (record.status as string)\n : undefined,\n size:\n typeof record.size === \"number\"\n ? record.size\n : undefined,\n instanceId:\n typeof record.instanceId === \"string\"\n ? record.instanceId\n : undefined,\n insights: parseInsights(record.insights),\n metadata: record\n };\n })\n : Array.isArray(raw)\n ? (raw as unknown[]).map((item) => {\n if (!item || typeof item !== \"object\") {\n return {\n id: \"\",\n createdAt: undefined,\n status: undefined,\n size: undefined,\n instanceId: undefined,\n insights: undefined,\n metadata: undefined\n };\n }\n const record = item as Record<string, unknown>;\n return {\n id: String(record.id ?? \"\"),\n createdAt:\n typeof record.createdAt === \"string\"\n ? (record.createdAt as string)\n : undefined,\n status:\n typeof record.status === \"string\"\n ? (record.status as string)\n : undefined,\n size:\n typeof record.size === \"number\"\n ? record.size\n : undefined,\n instanceId:\n typeof record.instanceId === \"string\"\n ? record.instanceId\n : undefined,\n insights: parseInsights(record.insights),\n metadata: record\n };\n })\n : [];\n\n const totalCount = (() => {\n if (rawRecord) {\n if (\n typeof rawRecord.totalCount === \"number\" &&\n Number.isFinite(rawRecord.totalCount)\n ) {\n return rawRecord.totalCount;\n }\n if (Array.isArray(rawRecord.supportBundles)) {\n return rawRecord.supportBundles.length;\n }\n }\n\n if (Array.isArray(raw)) {\n return raw.length;\n }\n\n return bundles.length;\n })();\n\n return {\n bundles,\n totalCount,\n raw\n };\n }\n});\n\nexport const downloadSupportBundle = defineServerAction<\n DownloadSupportBundleInput,\n DownloadSupportBundleResult\n>({\n id: \"support/download-bundle\",\n description: \"Gets a signed URL for downloading a support bundle.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\", \"download\"],\n async run({ token, bundleId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle download requires a session token\");\n }\n\n if (!bundleId || typeof bundleId !== \"string\") {\n throw new Error(\"Support bundle download requires a bundle ID\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/${encodeURIComponent(bundleId)}/download?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] getting support bundle download URL via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Support bundle download URL request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data = await response.json();\n const signedUrl = data?.signedUrl;\n\n if (typeof signedUrl !== \"string\" || !signedUrl) {\n throw new Error(\"Support bundle download response missing signedUrl\");\n }\n\n return { signedUrl };\n }\n});\n\nexport const deleteSupportBundle = defineServerAction<\n DeleteSupportBundleInput,\n DeleteSupportBundleResult\n>({\n id: \"support/delete-bundle\",\n description: \"Deletes a support bundle.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\", \"delete\"],\n async run({ token, bundleId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle deletion requires a session token\");\n }\n\n if (!bundleId || typeof bundleId !== \"string\") {\n throw new Error(\"Support bundle deletion requires a bundle ID\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/${encodeURIComponent(bundleId)}?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] deleting support bundle via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n if (response.status === 404) {\n throw new Error(\"Support bundle not found\");\n }\n throw new Error(\n `Support bundle deletion failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n return { success: true };\n }\n});\n\nexport const uploadSupportBundle = defineServerAction<\n UploadSupportBundleCompleteInput,\n UploadSupportBundleCompleteResult\n>({\n id: \"support/upload-bundle\",\n description: \"Uploads a support bundle to the server.\",\n visibility: \"customer\",\n tags: [\"support\", \"bundles\", \"upload\"],\n async run({ token, appId, fileContent, contentLength }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Support bundle upload requires a session token\");\n }\n\n if (!appId || typeof appId !== \"string\") {\n throw new Error(\"Support bundle upload requires an app ID\");\n }\n\n if (!fileContent || !(fileContent instanceof ArrayBuffer)) {\n throw new Error(\"Support bundle upload requires file content\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] uploading support bundle via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: {\n \"content-type\": \"application/gzip\",\n \"content-length\": String(contentLength)\n },\n body: fileContent,\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Support bundle upload failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data = await response.json();\n\n return {\n bundleId: data?.bundleId ?? data?.bundle_id ?? \"\",\n slug: data?.slug ?? \"\"\n };\n }\n});\n\n/**\n * Helper to get the upload endpoint URL for client-side uploads with progress tracking.\n * Use this when you need progress indication - call this to get the URL, then upload directly from client.\n */\nexport const getSupportBundleUploadUrl = (appId: string): string => {\n return `${getApiOrigin()}/enterprise-portal/support-bundles/upload/${encodeURIComponent(appId)}`;\n};\n\nasync function listReleasesImpl(): Promise<ListReleasesResult> {\n const { cookies } = await import(\"next/headers\");\n const sessionStore = await cookies();\n const session = sessionStore.get(\"portal_session\");\n const token = session?.value;\n\n if (!token) {\n throw new Error(\"List releases requires a session token\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/releases`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching releases via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n }\n });\n\n if (!response.ok) {\n throw new Error(\n `List releases request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n const data = envelope.data;\n\n return {\n releases: Array.isArray(data?.releases) ? data.releases : [],\n totalCount: data?.totalCount || 0\n };\n}\n\nexport const listReleases = traceServerAction(\"listReleases\", listReleasesImpl);\n\nconst asRecord = (value: unknown): Record<string, unknown> | undefined => {\n if (value && typeof value === \"object\") {\n return value as Record<string, unknown>;\n }\n return undefined;\n};\n\nconst getValue = (\n record: Record<string, unknown> | undefined,\n key: string\n) => (record ? record[key] : undefined);\n\nconst getString = (\n record: Record<string, unknown> | undefined,\n key: string\n): string | undefined => {\n const value = getValue(record, key);\n return typeof value === \"string\" ? value : undefined;\n};\n\nconst getBoolean = (\n record: Record<string, unknown> | undefined,\n key: string\n): boolean | undefined => {\n const value = getValue(record, key);\n if (typeof value === \"boolean\") {\n return value;\n }\n if (typeof value === \"number\") {\n return value === 1;\n }\n if (typeof value === \"string\") {\n const normalized = value.trim().toLowerCase();\n if ([\"true\", \"1\", \"yes\"].includes(normalized)) {\n return true;\n }\n if ([\"false\", \"0\", \"no\"].includes(normalized)) {\n return false;\n }\n }\n return undefined;\n};\n\nconst toDisplayValue = (value: unknown): string | null => {\n if (value === null || value === undefined) {\n return null;\n }\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\nconst normalizeStringArray = (value: unknown): string[] | undefined => {\n if (Array.isArray(value)) {\n const normalized = value\n .map((item) =>\n typeof item === \"string\" ? item.trim() : \"\"\n )\n .filter((item) => item.length > 0);\n return normalized.length ? normalized : undefined;\n }\n\n if (typeof value === \"string\") {\n const normalized = value\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length > 0);\n return normalized.length ? normalized : undefined;\n }\n\n return undefined;\n};\n\nconst normalizeLicenseFields = (input: unknown): PortalLicenseField[] => {\n if (!input) {\n return [];\n }\n\n if (Array.isArray(input)) {\n return input\n .map((field, index) => {\n if (!field || typeof field !== \"object\") {\n return null;\n }\n const candidate = field as Record<string, unknown>;\n const key =\n typeof candidate.key === \"string\" && candidate.key.trim().length\n ? candidate.key.trim()\n : typeof candidate.name === \"string\" && candidate.name.trim().length\n ? candidate.name.trim()\n : typeof candidate.label === \"string\" && candidate.label.trim().length\n ? candidate.label.trim()\n : `field-${index}`;\n const label =\n typeof candidate.label === \"string\" && candidate.label.trim().length\n ? candidate.label.trim()\n : typeof candidate.name === \"string\" && candidate.name.trim().length\n ? candidate.name.trim()\n : key;\n let value: unknown =\n candidate.value ?? candidate.data ?? candidate.content;\n if (\n (value === undefined || value === null) &&\n typeof candidate.text === \"string\"\n ) {\n value = candidate.text;\n }\n if (\n (value === undefined || value === null) &&\n typeof candidate.defaultValue === \"string\"\n ) {\n value = candidate.defaultValue;\n }\n const isSecret = Boolean(\n candidate.isSecret ?? candidate.secret ?? candidate.masked\n );\n const resolved = toDisplayValue(value);\n return {\n key,\n label,\n value: resolved,\n isSecret\n } as PortalLicenseField;\n })\n .filter((field): field is PortalLicenseField => Boolean(field));\n }\n\n if (typeof input === \"object\") {\n return Object.entries(input as Record<string, unknown>).map(\n ([key, value]) => {\n let resolvedValue: unknown = value;\n let isSecret = false;\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n if (\"value\" in obj) {\n resolvedValue = obj.value;\n }\n isSecret = Boolean(obj.isSecret ?? obj.secret ?? obj.masked);\n }\n const normalized = toDisplayValue(resolvedValue);\n return {\n key,\n label: key,\n value: normalized,\n isSecret\n };\n }\n );\n }\n\n return [];\n};\n\nconst extractChannelNames = (input: unknown): string[] | undefined => {\n if (!Array.isArray(input)) {\n return undefined;\n }\n const names = input\n .map((item) => {\n if (typeof item === \"string\") {\n return item.trim();\n }\n const record = asRecord(item);\n if (!record) {\n return null;\n }\n return (\n getString(record, \"name\") ??\n getString(record, \"channelName\") ??\n getString(record, \"channel\") ??\n getString(record, \"channelSlug\") ??\n getString(record, \"slug\") ??\n undefined\n );\n })\n .filter((name): name is string => Boolean(name && name.length));\n return names.length ? names : undefined;\n};\n\n// fetchLicense and helper functions are now defined in ./fetch-license.ts to avoid server-only imports in client bundles\n\nexport const fetchCustomers = defineServerAction<\n FetchCustomersInput,\n FetchCustomersResult\n>({\n id: \"auth/fetch-customers\",\n description: \"Fetches the list of customers/teams for the authenticated user.\",\n visibility: \"customer\",\n tags: [\"auth\", \"customers\"],\n async run({ token }, context) {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"fetchCustomers requires a non-empty token\");\n }\n\n // NEW: Use Enterprise Portal API /user endpoint (returns customers + user profile)\n const endpoint = `${getApiOrigin()}/enterprise-portal/user`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching customers via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: {\n accept: \"application/json\"\n },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch customers request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n const userData = envelope.data;\n\n return {\n customers: userData?.customers || []\n };\n }\n});\n\nexport const switchCustomer = defineServerAction<\n SwitchCustomerInput,\n SwitchCustomerResult\n>({\n id: \"auth/switch-customer\",\n description: \"Switches the JWT to a different customer/team.\",\n visibility: \"customer\",\n tags: [\"auth\", \"customers\"],\n async run({ token, customerId }, context) {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"switchCustomer requires a non-empty token\");\n }\n \n if (typeof customerId !== \"string\" || customerId.trim().length === 0) {\n throw new Error(\"switchCustomer requires a non-empty customerId\");\n }\n\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/switch-team`;\n\n const requestBody = { customer_id: customerId };\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify(requestBody),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error('[portal-components] switchCustomer error response:', errorText);\n throw new Error(\n `Switch customer request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const payload = await response.json();\n\n // API returns 'jwt' field, not 'token'\n const newToken = payload.jwt || payload.token || token;\n \n return {\n token: newToken\n };\n }\n});\n\n// =============================================================================\n// Security Types\n// =============================================================================\n\nexport type SecurityInstallType = \"linux\" | \"helm\";\n\nexport interface SecurityScanSummary {\n critical: Record<string, string>;\n high: Record<string, string>;\n medium: Record<string, string>;\n low: Record<string, string>;\n}\n\nexport interface SecurityScanWrapper {\n input: string;\n digest?: string;\n last_scanned_at?: string;\n result: SecurityScanSummary;\n not_found?: boolean;\n}\n\nexport interface SecurityReleaseImage {\n image: string;\n sha: string;\n size: number;\n platforms: { os: string; architecture: string }[];\n security?: SecurityScanWrapper;\n}\n\nexport interface GetSecurityInfoInput {\n token: string;\n installType: SecurityInstallType;\n channelSequence: number;\n isAirgap?: boolean;\n}\n\nexport interface GetSecurityInfoResult {\n images: SecurityReleaseImage[];\n activeInstancesByVersion?: Record<string, number>;\n}\n\nexport interface SecurityInfoDiff {\n oldTags: string[];\n newTags: string[];\n oldVulns?: SecurityScanSummary;\n newVulns?: SecurityScanSummary;\n added?: SecurityScanSummary;\n removed?: SecurityScanSummary;\n}\n\nexport interface GetSecurityInfoDiffInput {\n token: string;\n installType: SecurityInstallType;\n fromChannelSequence: number;\n toChannelSequence: number;\n isAirgap?: boolean;\n}\n\nexport interface GetSecurityInfoDiffResult {\n from_channel_sequence: number;\n to_channel_sequence: number;\n images: Record<string, SecurityInfoDiff>;\n}\n\nexport interface SBOMMetadata {\n name: string;\n spdxVersion: string;\n packageCount: number;\n fileCount: number;\n created?: string;\n creator?: string;\n source?: string;\n}\n\nexport interface GetSecurityInfoSBOMInput {\n token: string;\n installType: SecurityInstallType;\n channelSequence: number;\n isAirgap?: boolean;\n unifiedSbom?: boolean;\n}\n\nexport interface GetSecurityInfoSBOMResult {\n sboms: {\n unified?: SBOMMetadata;\n };\n}\n\nexport interface DownloadSBOMInput {\n token: string;\n installType: SecurityInstallType;\n channelSequence: number;\n isAirgap?: boolean;\n}\n\n// =============================================================================\n// Security Actions\n// =============================================================================\n\n/**\n * Fetches security scan (CVE) information for a specific release.\n */\nexport const getSecurityInfo = defineServerAction<\n GetSecurityInfoInput,\n GetSecurityInfoResult\n>({\n id: \"security/get-info\",\n description: \"Fetches CVE security scan results for a specific release\",\n visibility: \"customer\",\n tags: [\"security\", \"cve\"],\n async run({ token, installType, channelSequence, isAirgap = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security info request requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n install_type: installType,\n channel_sequence: channelSequence.toString(),\n is_airgap: isAirgap.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching security info via %s (Enterprise Portal API)\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Security info request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n // Extract from Enterprise Portal API envelope\n return payload.data as GetSecurityInfoResult;\n }\n});\n\n/**\n * Fetches security diff between two releases (fixed/added CVEs).\n */\nexport const getSecurityInfoDiff = defineServerAction<\n GetSecurityInfoDiffInput,\n GetSecurityInfoDiffResult\n>({\n id: \"security/get-info-diff\",\n description: \"Fetches CVE diff between two releases showing fixed and added vulnerabilities\",\n visibility: \"customer\",\n tags: [\"security\", \"cve\", \"diff\"],\n async run({ token, installType, fromChannelSequence, toChannelSequence, isAirgap = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security info diff request requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n install_type: installType,\n from_channel_sequence: fromChannelSequence.toString(),\n to_channel_sequence: toChannelSequence.toString(),\n is_airgap: isAirgap.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security-diff?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching security info diff via %s\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Security info diff request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n // Extract from Enterprise Portal API envelope\n return envelope.data as GetSecurityInfoDiffResult;\n }\n});\n\n/**\n * Fetches SBOM (Software Bill of Materials) for a specific release.\n */\nexport const getSecurityInfoSBOM = defineServerAction<\n GetSecurityInfoSBOMInput,\n GetSecurityInfoSBOMResult\n>({\n id: \"security/get-sbom\",\n description: \"Fetches Software Bill of Materials (SBOM) for a specific release\",\n visibility: \"customer\",\n tags: [\"security\", \"sbom\"],\n async run({ token, installType, channelSequence, isAirgap = false, unifiedSbom = true }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security SBOM request requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n install_type: installType,\n channel_sequence: channelSequence.toString(),\n is_airgap: isAirgap.toString(),\n unified_sbom: unifiedSbom.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security-sbom?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching security SBOM via %s\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n // Handle 204 No Content response\n if (response.status === 204) {\n return { sboms: {} };\n }\n\n if (!response.ok) {\n throw new Error(\n `Security SBOM request failed (${response.status} ${response.statusText})`\n );\n }\n\n const envelope = await response.json();\n // Extract from Enterprise Portal API envelope\n return envelope.data as GetSecurityInfoSBOMResult;\n }\n});\n\n/**\n * Downloads the full SBOM file for a specific release.\n * Returns a download URL that can be used to fetch the SBOM.\n */\nexport const downloadSecuritySBOM = defineServerAction<\n DownloadSBOMInput,\n string\n>({\n id: \"security/download-sbom\",\n description: \"Downloads the full SBOM file for a specific release\",\n visibility: \"customer\",\n tags: [\"security\", \"sbom\", \"download\"],\n async run({ token, installType, channelSequence, isAirgap = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Security SBOM download requires a session token\");\n }\n\n const params = new URLSearchParams({\n install_type: installType,\n channel_sequence: channelSequence.toString(),\n is_airgap: isAirgap.toString()\n });\n\n const url = `${getApiOrigin()}/enterprise-portal/security-sbom/download?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] downloading security SBOM via %s\", url);\n }\n\n const response = await authenticatedFetch(url, {\n token,\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Security SBOM download failed (${response.status} ${response.statusText})`\n );\n }\n\n // Return the SBOM content directly as a string\n // The client will create the blob URL in the browser context\n return await response.text();\n }\n});\n\n// =============================================================================\n// Dashboard Types\n// =============================================================================\n\nexport interface FetchTeamStatsInput {\n token: string;\n}\n\nexport interface TeamUser {\n id: string;\n email: string;\n name?: string;\n createdAt?: string;\n}\n\nexport interface ServiceAccountSummary {\n id: string;\n accountName: string;\n customerId: string;\n isRevoked: boolean;\n createdAt: string;\n}\n\nexport interface FetchTeamStatsResult {\n userCount: number;\n serviceAccountCount: number;\n}\n\nexport interface FetchDashboardInstancesInput {\n token: string;\n}\n\nexport interface FetchDashboardInstancesResult {\n onlineActiveCount: number;\n airgapCount: number;\n onlineUpdates: number;\n airgapUpdates: number;\n // NEW: Additional data from composite endpoint\n license?: {\n type: string;\n expiresAt: string | null;\n isEmbeddedClusterDownloadEnabled: boolean;\n isHelmInstallEnabled: boolean;\n };\n teamStats?: {\n userCount: number;\n serviceAccountCount: number;\n supportBundleCount: number;\n };\n}\n\n// =============================================================================\n// Dashboard Actions\n// =============================================================================\n\n/**\n * NEW: Fetches all dashboard data using the composite Enterprise Portal API endpoint.\n * This replaces multiple v3 calls with a single call that returns:\n * - Instances\n * - Channel releases (for calculating updates)\n * - Notifications\n * - User/app/branding context\n */\nexport const fetchDashboardComposite = defineServerAction<\n FetchDashboardInstancesInput,\n FetchDashboardInstancesResult\n>({\n id: \"dashboard/fetch-composite\",\n description: \"Fetches all dashboard data from the composite Enterprise Portal API endpoint\",\n visibility: \"customer\",\n tags: [\"dashboard\", \"enterprise-portal-api\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Dashboard request requires a session token\");\n }\n\n const origin = getApiOrigin();\n const url = `${origin}/enterprise-portal/dashboard`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching dashboard via %s (Enterprise Portal API)\", url);\n }\n\n const response = await authenticatedFetch(url, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Dashboard request failed (${response.status} ${response.statusText})`\n );\n }\n\n const payload = await response.json();\n\n // Extract data from the Enterprise Portal API envelope\n const data = payload.data;\n const allInstances = data?.instances || [];\n const channelReleases = data?.channelReleases || [];\n const licenseData = data?.license || {};\n const teamStats = data?.teamStats || {};\n\n // Split into online and airgap\n const onlineInstances = allInstances.filter((i: { isAirgap?: boolean }) => !i.isAirgap);\n const airgapInstances = allInstances.filter((i: { isAirgap?: boolean }) => i.isAirgap);\n\n // Filter to active online instances (checked in within 24 hours)\n const twentyFourHoursAgo = Date.now() - 24 * 60 * 60 * 1000;\n const activeOnlineInstances = onlineInstances.filter((instance: { lastCheckin?: string }) => {\n const lastCheckin = instance.lastCheckin\n ? new Date(instance.lastCheckin).getTime()\n : 0;\n return lastCheckin > twentyFourHoursAgo;\n });\n\n const onlineActiveCount = activeOnlineInstances.length;\n const airgapCount = airgapInstances.length;\n\n // Calculate updates for active online instances\n const calculateUpdates = (instances: Array<{ channelId?: string; channelSequence?: number }>) => {\n if (!channelReleases.length) return 0;\n\n let numUpdates = 0;\n for (const instance of instances) {\n const instanceSequence = instance.channelSequence ?? 0;\n const matchingReleases = channelReleases.filter(\n (release: { channelId?: string; channelSequence?: number }) => release.channelId === instance.channelId\n );\n for (const release of matchingReleases) {\n if ((release.channelSequence ?? 0) > instanceSequence) {\n numUpdates++;\n }\n }\n }\n return numUpdates;\n };\n\n const onlineUpdates = calculateUpdates(activeOnlineInstances);\n const airgapUpdates = calculateUpdates(airgapInstances);\n\n // Store the composite data for other dashboard components to use\n // This allows us to eliminate the separate fetchTeamStats, fetchLicenseSummary, and fetchInstallOptions calls\n return {\n onlineActiveCount,\n airgapCount,\n onlineUpdates,\n airgapUpdates,\n // Additional data available from the composite endpoint\n license: licenseData,\n teamStats: teamStats\n };\n }\n});\n\n/**\n * Fetches team statistics including user count and service account count.\n * Used by the Team Settings dashboard card.\n */\nexport const fetchTeamStats = defineServerAction<\n FetchTeamStatsInput,\n FetchTeamStatsResult\n>({\n id: \"dashboard/fetch-team-stats\",\n description: \"Fetches user and service account counts for the dashboard\",\n visibility: \"customer\",\n tags: [\"dashboard\", \"team\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Team stats request requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n // Fetch users count\n let userCount = 0;\n try {\n const usersUrl = `${origin}/v3/users?exclude_invites=false&customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching team users via %s\", usersUrl);\n }\n\n const usersResponse = await authenticatedFetch(usersUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (usersResponse.ok) {\n const usersData = await usersResponse.json();\n userCount = Array.isArray(usersData.users) ? usersData.users.length : 0;\n }\n } catch (error) {\n console.error(\"[portal-components] Error fetching users:\", error);\n }\n\n // Fetch service accounts count\n let serviceAccountCount = 0;\n try {\n const saUrl = `${origin}/v3/service-accounts?customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching service accounts via %s\", saUrl);\n }\n\n const saResponse = await authenticatedFetch(saUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (saResponse.ok) {\n const saData = await saResponse.json();\n serviceAccountCount = Array.isArray(saData.serviceAccounts) \n ? saData.serviceAccounts.length \n : 0;\n }\n } catch (error) {\n console.error(\"[portal-components] Error fetching service accounts:\", error);\n }\n\n return {\n userCount,\n serviceAccountCount\n };\n }\n});\n\n/**\n * Fetches instance counts and available updates for the dashboard.\n * Used by the Updates dashboard card.\n */\nexport const fetchDashboardInstances = defineServerAction<\n FetchDashboardInstancesInput,\n FetchDashboardInstancesResult\n>({\n id: \"dashboard/fetch-instances\",\n description: \"Fetches instance counts and update availability for the dashboard\",\n visibility: \"customer\",\n tags: [\"dashboard\", \"instances\", \"updates\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Dashboard instances request requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const origin = getApiOrigin();\n\n // Fetch instances\n const instancesUrl = `${origin}/v3/instances?customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching instances via %s\", instancesUrl);\n }\n\n const instancesResponse = await authenticatedFetch(instancesUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!instancesResponse.ok) {\n throw new Error(\n `Instances request failed (${instancesResponse.status} ${instancesResponse.statusText})`\n );\n }\n\n const instancesData = await instancesResponse.json();\n const allInstances = instancesData.instances || [];\n\n // Split into online and airgap\n const onlineInstances = allInstances.filter((i: { isAirgap?: boolean }) => !i.isAirgap);\n const airgapInstances = allInstances.filter((i: { isAirgap?: boolean }) => i.isAirgap);\n\n // Filter to active online instances (checked in within 24 hours)\n const twentyFourHoursAgo = Date.now() - 24 * 60 * 60 * 1000;\n const activeOnlineInstances = onlineInstances.filter((instance: { lastCheckin?: string }) => {\n const lastCheckin = instance.lastCheckin \n ? new Date(instance.lastCheckin).getTime() \n : 0;\n return lastCheckin > twentyFourHoursAgo;\n });\n\n const onlineActiveCount = activeOnlineInstances.length;\n const airgapCount = airgapInstances.length;\n\n // Fetch channel releases to calculate updates\n let channelReleases: Array<{ channelId: string; channelSequence: number }> = [];\n try {\n const releasesUrl = `${origin}/v3/channel-releases?customer_id=${encodeURIComponent(customerId)}`;\n \n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching channel releases via %s\", releasesUrl);\n }\n\n const releasesResponse = await authenticatedFetch(releasesUrl, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (releasesResponse.ok) {\n const releasesData = await releasesResponse.json();\n channelReleases = releasesData.channelReleases || [];\n }\n } catch (error) {\n console.error(\"[portal-components] Error fetching channel releases:\", error);\n }\n\n // Calculate updates for active online instances\n const calculateUpdates = (instances: Array<{ channelId?: string; channelSequence?: number }>) => {\n if (!channelReleases.length) return 0;\n \n let numUpdates = 0;\n for (const instance of instances) {\n const instanceSequence = instance.channelSequence ?? 0;\n const matchingReleases = channelReleases.filter(\n (release) => release.channelId === instance.channelId\n );\n for (const release of matchingReleases) {\n if (release.channelSequence > instanceSequence) {\n numUpdates++;\n }\n }\n }\n return numUpdates;\n };\n\n const onlineUpdates = calculateUpdates(activeOnlineInstances);\n const airgapUpdates = calculateUpdates(airgapInstances);\n\n return {\n onlineActiveCount,\n airgapCount,\n onlineUpdates,\n airgapUpdates\n };\n }\n});\n\n// =============================================================================\n// User Settings Types\n// =============================================================================\n\nexport interface FetchCurrentUserInput {\n token: string;\n}\n\nexport interface UserProfile {\n emailAddress: string;\n firstName: string;\n lastName: string;\n}\n\nexport interface FetchCurrentUserResult {\n user: UserProfile;\n}\n\nexport interface UpdateUserInput {\n token: string;\n firstName?: string;\n lastName?: string;\n}\n\nexport interface UpdateUserResult {\n success: boolean;\n}\n\nexport interface NotificationSetting {\n type: string;\n enabled: boolean;\n}\n\nexport interface FetchNotificationsInput {\n token: string;\n customerId: string;\n}\n\nexport interface FetchNotificationsResult {\n notifications: NotificationSetting[];\n}\n\nexport interface UpdateNotificationsInput {\n token: string;\n customerId: string;\n notifications: NotificationSetting[];\n}\n\nexport interface UpdateNotificationsResult {\n notifications: NotificationSetting[];\n}\n\n// =============================================================================\n// User Settings Actions\n// =============================================================================\n\n/**\n * Fetches the current user's profile information.\n */\nexport const fetchCurrentUser = defineServerAction<\n FetchCurrentUserInput,\n FetchCurrentUserResult\n>({\n id: \"user/fetch-current\",\n description: \"Fetches the current user's profile information\",\n visibility: \"customer\",\n tags: [\"user\", \"profile\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch current user requires a session token\");\n }\n\n // NEW: Use Enterprise Portal API endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/profile`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching current user via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch current user request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n user: {\n emailAddress: data.emailAddress || \"\",\n firstName: data.firstName || \"\",\n lastName: data.lastName || \"\"\n }\n };\n }\n});\n\n/**\n * Updates the current user's profile information.\n */\nexport const updateUser = defineServerAction<\n UpdateUserInput,\n UpdateUserResult\n>({\n id: \"user/update\",\n description: \"Updates the current user's first and/or last name\",\n visibility: \"customer\",\n tags: [\"user\", \"profile\"],\n async run({ token, firstName, lastName }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Update user requires a session token\");\n }\n\n if (!firstName && !lastName) {\n throw new Error(\"At least one of firstName or lastName must be provided\");\n }\n\n // NEW: Use Enterprise Portal API endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/profile`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] updating user via %s\", endpoint);\n }\n\n const body: { firstName?: string; lastName?: string } = {};\n if (firstName !== undefined) body.firstName = firstName;\n if (lastName !== undefined) body.lastName = lastName;\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify(body),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Update user request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n return { success: true };\n }\n});\n\n/**\n * Fetches notification preferences for a specific customer/team.\n */\nexport const fetchNotifications = defineServerAction<\n FetchNotificationsInput,\n FetchNotificationsResult\n>({\n id: \"notifications/fetch\",\n description: \"Fetches notification preferences for a specific team\",\n visibility: \"customer\",\n tags: [\"notifications\", \"user\"],\n async run({ token, customerId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch notifications requires a session token\");\n }\n\n if (!customerId || typeof customerId !== \"string\") {\n throw new Error(\"Fetch notifications requires a valid customerId\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/notifications?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching notifications via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch notifications request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n notifications: data.notifications || []\n };\n }\n});\n\n/**\n * Updates notification preferences for a specific customer/team.\n */\nexport const updateNotifications = defineServerAction<\n UpdateNotificationsInput,\n UpdateNotificationsResult\n>({\n id: \"notifications/update\",\n description: \"Updates notification preferences for a specific team\",\n visibility: \"customer\",\n tags: [\"notifications\", \"user\"],\n async run({ token, customerId, notifications }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Update notifications requires a session token\");\n }\n\n if (!customerId || typeof customerId !== \"string\") {\n throw new Error(\"Update notifications requires a valid customerId\");\n }\n\n if (!Array.isArray(notifications)) {\n throw new Error(\"Update notifications requires a notifications array\");\n }\n\n // NOTE: customerId is still required in query params because this endpoint\n // delegates to v3 handler which validates customer_id\n const endpoint = `${getApiOrigin()}/enterprise-portal/user/notifications?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] updating notifications via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ notifications }),\n signal: context?.signal\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Update notifications request failed (${response.status} ${response.statusText}): ${errorText}`\n );\n }\n\n const data = await response.json();\n \n return {\n notifications: data.notifications || []\n };\n }\n});\n\n// =============================================================================\n// Team Settings Types\n// =============================================================================\n\nexport interface TeamUser {\n id: string;\n emailAddress: string;\n firstAccessedAt?: string;\n lastAccessedAt?: string;\n viewCount?: number;\n pendingInvite: boolean;\n}\n\nexport interface FetchTeamUsersInput {\n token: string;\n limit?: number;\n offset?: number;\n}\n\nexport interface FetchTeamUsersResult {\n users: TeamUser[];\n total: number;\n}\n\nexport interface InviteUserInput {\n token: string;\n email: string;\n}\n\nexport interface InviteUserResult {\n success: boolean;\n}\n\nexport interface DeleteUserInput {\n token: string;\n id: string;\n isPendingInvite: boolean; // If true, delete invite; if false, delete user\n}\n\nexport interface DeleteUserResult {\n success: boolean;\n}\n\nexport interface ServiceAccount {\n id: string;\n customerId: string;\n accountName: string;\n emailAddress?: string;\n token: string;\n isRevoked: boolean;\n createdAt: string;\n lastUsedAt?: string;\n tokenRegeneratedAt?: string;\n}\n\nexport interface FetchServiceAccountsInput {\n token: string;\n limit?: number;\n offset?: number;\n includeRevoked?: boolean;\n}\n\nexport interface FetchServiceAccountsResult {\n serviceAccounts: ServiceAccount[];\n total: number;\n}\n\nexport interface RevokeServiceAccountInput {\n token: string;\n accountId: string;\n}\n\nexport interface RevokeServiceAccountResult {\n success: boolean;\n}\n\nexport interface RotateServiceAccountTokenInput {\n token: string;\n accountId: string;\n}\n\nexport interface RotateServiceAccountTokenResult {\n serviceAccount: ServiceAccount;\n helmLoginCommand: string;\n redeployHelm: string[];\n}\n\nexport interface Instance {\n id: string;\n serviceAccountId?: string;\n versionLabel?: string;\n channelId?: string;\n channelSequence?: number;\n lastCheckin?: string;\n isAirgap?: boolean;\n embeddedClusterVersion?: string;\n tags?: Array<{ key: string; value: string }>;\n}\n\nexport interface FetchInstancesInput {\n token: string;\n}\n\nexport interface FetchInstancesResult {\n instances: Instance[];\n}\n\nexport interface SAMLConfig {\n samlAllowed: boolean;\n samlEnabled: boolean;\n entityId: string;\n acsUrl: string;\n hasIdpMetadata: boolean;\n hasIdpCert: boolean;\n}\n\nexport interface FetchSamlConfigInput {\n token: string;\n}\n\nexport interface FetchSamlConfigResult {\n config: SAMLConfig;\n}\n\nexport interface UpdateSamlConfigInput {\n token: string;\n idpMetadataXml: string;\n idpPublicCert: string;\n}\n\nexport interface UpdateSamlConfigResult {\n success: boolean;\n}\n\nexport interface ToggleSamlEnabledInput {\n token: string;\n enabled: boolean;\n}\n\nexport interface ToggleSamlEnabledResult {\n success: boolean;\n samlEnabled: boolean;\n}\n\nexport interface DeprovisionSamlInput {\n token: string;\n}\n\nexport interface DeprovisionSamlResult {\n success: boolean;\n}\n\n// =============================================================================\n// Team Settings Actions\n// =============================================================================\n\n/**\n * Fetches the list of users for a team.\n */\nexport const fetchTeamUsers = defineServerAction<\n FetchTeamUsersInput,\n FetchTeamUsersResult\n>({\n id: \"team/fetch-users\",\n description: \"Fetches paginated list of team users and pending invites\",\n visibility: \"customer\",\n tags: [\"team\", \"users\"],\n async run({ token, limit = 25, offset = 0 }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch team users requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n // NEW: Use Enterprise Portal API endpoint\n // Note: v3 handler still requires customer_id in query params for validation\n const params = new URLSearchParams({\n customer_id: customerId,\n limit: limit.toString(),\n offset: offset.toString()\n });\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/users?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching team users via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch team users request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n users: data.users || [],\n total: data.total || 0\n };\n }\n});\n\n/**\n * Invites a user to the team.\n */\nexport const inviteUser = defineServerAction<\n InviteUserInput,\n InviteUserResult\n>({\n id: \"team/invite-user\",\n description: \"Sends an invitation email to join the team\",\n visibility: \"customer\",\n tags: [\"team\", \"users\", \"invite\"],\n async run({ token, email }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Invite user requires a session token\");\n }\n\n if (!email || typeof email !== \"string\") {\n throw new Error(\"Invite user requires an email address\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n // NEW: Use Enterprise Portal API endpoint (no customer_id needed)\n const params = new URLSearchParams({\n email_address: email\n });\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/invite?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] inviting user via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to invite user\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Removes a user or pending invite from the team by ID.\n */\nexport const deleteUser = defineServerAction<\n DeleteUserInput,\n DeleteUserResult\n>({\n id: \"team/delete-user\",\n description: \"Removes a user or pending invite from the team by ID\",\n visibility: \"customer\",\n tags: [\"team\", \"users\", \"delete\"],\n async run({ token, id, isPendingInvite }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Delete user requires a session token\");\n }\n\n if (!id || typeof id !== \"string\") {\n throw new Error(\"Delete user requires an ID\");\n }\n\n // Use different endpoints for users vs invites\n const resource = isPendingInvite ? \"invites\" : \"users\";\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/${resource}/${encodeURIComponent(id)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] deleting %s %s via %s\", resource, id, endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = isPendingInvite ? \"Failed to delete invite\" : \"Failed to delete user\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Fetches the list of service accounts for a team.\n */\nexport const fetchServiceAccounts = defineServerAction<\n FetchServiceAccountsInput,\n FetchServiceAccountsResult\n>({\n id: \"team/fetch-service-accounts\",\n description: \"Fetches paginated list of service accounts\",\n visibility: \"customer\",\n tags: [\"team\", \"service-accounts\"],\n async run({ token, limit = 50, offset = 0, includeRevoked = false }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch service accounts requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const params = new URLSearchParams({\n customer_id: customerId,\n limit: limit.toString(),\n offset: offset.toString()\n });\n\n // Add filterRevoked parameter - API filters revoked when this param is present\n if (!includeRevoked) {\n params.set(\"filterRevoked\", \"false\");\n }\n\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts?${params.toString()}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching service accounts via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch service accounts request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n serviceAccounts: data.serviceAccounts || [],\n total: data.total || 0\n };\n }\n});\n\n/**\n * Revokes a service account.\n */\nexport const revokeServiceAccount = defineServerAction<\n RevokeServiceAccountInput,\n RevokeServiceAccountResult\n>({\n id: \"team/revoke-service-account\",\n description: \"Revokes a service account (soft delete)\",\n visibility: \"customer\",\n tags: [\"team\", \"service-accounts\", \"revoke\"],\n async run({ token, accountId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Revoke service account requires a session token\");\n }\n\n if (!accountId || typeof accountId !== \"string\") {\n throw new Error(\"Revoke service account requires an account ID\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts/${encodeURIComponent(accountId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] revoking service account via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to revoke service account\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Rotates a service account token.\n */\nexport const rotateServiceAccountToken = defineServerAction<\n RotateServiceAccountTokenInput,\n RotateServiceAccountTokenResult\n>({\n id: \"team/rotate-service-account-token\",\n description: \"Generates a new token for a service account\",\n visibility: \"customer\",\n tags: [\"team\", \"service-accounts\", \"rotate\"],\n async run({ token, accountId }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Rotate service account token requires a session token\");\n }\n\n if (!accountId || typeof accountId !== \"string\") {\n throw new Error(\"Rotate service account token requires an account ID\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/enterprise-portal/team/service-accounts/${encodeURIComponent(accountId)}/rotate-token`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] rotating service account token via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"POST\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to rotate service account token\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n \n return {\n serviceAccount: data.service_account,\n helmLoginCommand: data.helm_login_cmd || \"\",\n redeployHelm: data.redeploy_helm || []\n };\n }\n});\n\n/**\n * Fetches instances for the customer.\n */\nexport const fetchInstances = defineServerAction<\n FetchInstancesInput,\n FetchInstancesResult\n>({\n id: \"team/fetch-instances\",\n description: \"Fetches instances to determine service account usage\",\n visibility: \"customer\",\n tags: [\"team\", \"instances\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch instances requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/instances?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching instances via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch instances request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n instances: data.instances || []\n };\n }\n});\n\n/**\n * Fetches SAML configuration for the customer.\n */\nexport const fetchSamlConfig = defineServerAction<\n FetchSamlConfigInput,\n FetchSamlConfigResult\n>({\n id: \"team/fetch-saml-config\",\n description: \"Fetches SAML SSO configuration for the team\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Fetch SAML config requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/config?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] fetching SAML config via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"GET\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n throw new Error(\n `Fetch SAML config request failed (${response.status} ${response.statusText})`\n );\n }\n\n const data = await response.json();\n \n return {\n config: {\n samlAllowed: data.samlAllowed || false,\n samlEnabled: data.samlEnabled || false,\n entityId: data.entityId || \"\",\n acsUrl: data.acsUrl || \"\",\n hasIdpMetadata: data.hasIdpMetadata || false,\n hasIdpCert: data.hasIdpCert || false\n }\n };\n }\n});\n\n/**\n * Updates SAML configuration (uploads IdP metadata and certificate).\n */\nexport const updateSamlConfig = defineServerAction<\n UpdateSamlConfigInput,\n UpdateSamlConfigResult\n>({\n id: \"team/update-saml-config\",\n description: \"Uploads IdP metadata and certificate for SAML SSO\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\", \"update\"],\n async run({ token, idpMetadataXml, idpPublicCert }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Update SAML config requires a session token\");\n }\n\n if (!idpMetadataXml || !idpPublicCert) {\n throw new Error(\"Both IdP metadata and certificate are required\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/config?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] updating SAML config via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({\n idpMetadataXml,\n idpPublicCert\n }),\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to update SAML configuration\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n/**\n * Toggles SAML authentication enabled/disabled.\n */\nexport const toggleSamlEnabled = defineServerAction<\n ToggleSamlEnabledInput,\n ToggleSamlEnabledResult\n>({\n id: \"team/toggle-saml-enabled\",\n description: \"Enables or disables SAML authentication\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\", \"toggle\"],\n async run({ token, enabled }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Toggle SAML enabled requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/enable?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] toggling SAML enabled via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"PUT\",\n token,\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ enabled }),\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to toggle SAML\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n \n return {\n success: true,\n samlEnabled: data.samlEnabled || enabled\n };\n }\n});\n\n/**\n * Removes SAML configuration (deprovisions SAML).\n */\nexport const deprovisionSaml = defineServerAction<\n DeprovisionSamlInput,\n DeprovisionSamlResult\n>({\n id: \"team/deprovision-saml\",\n description: \"Removes all SAML configuration\",\n visibility: \"customer\",\n tags: [\"team\", \"saml\", \"delete\"],\n async run({ token }, context) {\n if (!token || typeof token !== \"string\") {\n throw new Error(\"Deprovision SAML requires a session token\");\n }\n\n const customerId = getCustomerIdFromToken(token);\n const endpoint = `${getApiOrigin()}/v3/customer/saml/config?customer_id=${encodeURIComponent(customerId)}`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] deprovisioning SAML via %s\", endpoint);\n }\n\n const response = await authenticatedFetch(endpoint, {\n method: \"DELETE\",\n token,\n headers: { accept: \"application/json\" },\n signal: context?.signal\n });\n\n if (!response.ok) {\n let errorMessage = \"Failed to remove SAML configuration\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n// =============================================================================\n// Invite Accept/Refresh Actions\n// =============================================================================\n\nexport interface AcceptInviteInput {\n code: string;\n}\n\nexport interface AcceptInviteResult {\n token: string;\n}\n\nexport interface AcceptInviteError {\n code: \"invalid_code\" | \"expired\" | \"unknown\";\n message: string;\n}\n\n/**\n * Accepts a team invitation using the invite code from email.\n * Returns a JWT token on success that can be used to establish a session.\n */\nexport const acceptInvite = defineServerAction<\n AcceptInviteInput,\n AcceptInviteResult\n>({\n id: \"auth/accept-invite\",\n description: \"Accepts a team invitation and returns a session token\",\n visibility: \"customer\",\n tags: [\"auth\", \"invite\", \"join\"],\n async run({ code }) {\n if (!code || typeof code !== \"string\") {\n const error: AcceptInviteError = {\n code: \"invalid_code\",\n message: \"Invite code is required\"\n };\n throw error;\n }\n\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/invite/accept`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] accepting invite via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ code })\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n const error: AcceptInviteError = {\n code: \"invalid_code\",\n message: \"Invalid or expired invite code. Please check your code and try again.\"\n };\n throw error;\n }\n\n let errorMessage = \"Failed to accept invitation\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n\n const error: AcceptInviteError = {\n code: \"unknown\",\n message: errorMessage\n };\n throw error;\n }\n\n const payload = await response.json();\n const token = payload?.jwt ?? payload?.token;\n\n if (typeof token !== \"string\") {\n throw new Error(\"Invite accepted but no token returned\");\n }\n\n return { token };\n }\n});\n\nexport interface RefreshInviteInput {\n code: string;\n}\n\nexport interface RefreshInviteResult {\n success: boolean;\n}\n\n/**\n * Refreshes an expired invite by generating a new code and resending the email.\n * The original code is used to identify the invite to refresh.\n */\nexport const refreshInvite = defineServerAction<\n RefreshInviteInput,\n RefreshInviteResult\n>({\n id: \"auth/refresh-invite\",\n description: \"Refreshes an expired invite and resends the invitation email\",\n visibility: \"customer\",\n tags: [\"auth\", \"invite\", \"refresh\"],\n async run({ code }) {\n if (!code || typeof code !== \"string\") {\n throw new Error(\"Invite code is required\");\n }\n\n // NEW: Use Enterprise Portal API auth endpoint\n const endpoint = `${getApiOrigin()}/enterprise-portal/auth/invite/refresh`;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.debug(\"[portal-components] refreshing invite via %s (Enterprise Portal API)\", endpoint);\n }\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n accept: \"application/json\"\n },\n body: JSON.stringify({ code })\n });\n\n // The API returns 200 even for non-existent codes to prevent code enumeration\n if (!response.ok) {\n let errorMessage = \"Failed to refresh invitation\";\n try {\n const data = await response.json();\n errorMessage = data.message || data.error || errorMessage;\n } catch {\n // Ignore JSON parse errors\n }\n throw new Error(errorMessage);\n }\n\n return { success: true };\n }\n});\n\n// Re-export install types for template usage\nexport type {\n ChannelRelease,\n FetchChannelReleasesResult,\n NetworkAvailability,\n InstallType,\n RegistryAvailability,\n KubernetesDistribution,\n InstallOptions,\n InstallInstructions,\n InstallStep\n} from \"./install\";\n\n// Re-export install-actions for template usage\nexport {\n fetchPendingInstallationsAction,\n fetchChannelReleasesAction,\n createInstallOptionsAction,\n getInstallOptionsAction,\n updateInstallOptionsAction,\n discardInstallationAction\n} from \"./install-actions\";\n\n// Re-export service-account actions for template usage\nexport {\n createServiceAccountAction\n} from \"./service-account\";\n\n// Re-export fetch-app-info for template usage\nexport { fetchAppInfo } from \"./fetch-app-info\";\n\n\n// Re-export team-settings for template usage\nexport {\n fetchTeamUsersAction,\n inviteUserAction,\n deleteUserAction,\n fetchServiceAccountsAction,\n revokeServiceAccountAction,\n rotateServiceAccountTokenAction,\n fetchInstancesAction,\n fetchSamlConfigAction,\n updateSamlConfigAction,\n toggleSamlEnabledAction,\n deprovisionSamlAction,\n fetchAppFeatures,\n type AppFeatures\n} from \"./team-settings\";\n\n// Re-export user-settings for template usage\nexport {\n fetchCurrentUserAction,\n updateUserAction,\n fetchTeamsForUserSettings,\n fetchNotificationsAction,\n updateNotificationsAction\n} from \"./user-settings\";\nexport type {\n TeamForUserSettings\n} from \"./user-settings\";\n\n// Re-export change-team for template usage\nexport {\n changeTeamAction,\n fetchCustomersForMenu\n} from \"./change-team\";\n\n// Re-export support-bundles for template usage\nexport {\n downloadSupportBundleAction,\n deleteSupportBundleAction,\n uploadSupportBundleAction,\n listSupportBundlesAction\n} from \"./support-bundles\";\nexport type {\n ActionResult as SupportBundleActionResult,\n UploadSupportBundleResult as UploadSupportBundleActionResult,\n ListBundlesResult\n} from \"./support-bundles\";\nexport { fetchUser } from './fetch-user';\nexport type { UserResult, UserContext, UserPermissions } from './fetch-user';\n\n// Trial signup actions are exported separately to avoid bundling server-only code\n// Import from '@replicated/portal-components/actions/trial-signup' instead\nexport type {\n TrialSignupPayload,\n TrialSignupResult,\n TrialSignupVerifyResult\n} from \"./trial-signup\";\n","import type { ReactNode, SVGProps } from \"react\";\nimport { fetchLicense } from \"../actions\";\nimport type {\n License,\n PortalLicenseField\n} from \"../actions\";\n\nexport interface LicenseDetailsProps {\n token: string;\n title?: string;\n description?: string;\n}\n\nconst ShieldIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n </svg>\n);\n\nconst CalendarIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M8 2v4\" />\n <path d=\"M16 2v4\" />\n <rect width={18} height={18} x={3} y={4} rx={2} />\n <path d=\"M3 10h18\" />\n </svg>\n);\n\nconst DownloadIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M12 17V3\" />\n <path d=\"m6 11 6 6 6-6\" />\n <path d=\"M19 21H5\" />\n </svg>\n);\n\nconst BuildingIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <rect width={16} height={20} x={4} y={2} rx={2} ry={2} />\n <path d=\"M9 22v-4h6v4\" />\n <path d=\"M8 6h.01\" />\n <path d=\"M16 6h.01\" />\n <path d=\"M12 6h.01\" />\n <path d=\"M12 10h.01\" />\n <path d=\"M12 14h.01\" />\n <path d=\"M16 10h.01\" />\n <path d=\"M16 14h.01\" />\n <path d=\"M8 10h.01\" />\n <path d=\"M8 14h.01\" />\n </svg>\n);\n\nconst CheckIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M21.8 10A10 10 0 1 1 17 3.33\" />\n <path d=\"m9 11 3 3L22 4\" />\n </svg>\n);\n\nconst formatExpiration = (value?: string | null) => {\n if (!value || value === \"never\") {\n return \"Does not expire\";\n }\n\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return value;\n }\n\n return date.toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\"\n });\n};\n\nconst maskValue = (value?: string | null, isSecret?: boolean) => {\n if (isSecret) {\n return \"••••••••••••\";\n }\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n return \"No value set\";\n};\n\nconst getFieldTextClass = (value?: string | null) => {\n if (value === \"does-not-expire\") {\n return \"text-gray-500\";\n }\n return value && value.trim().length > 0 ? \"text-gray-500\" : \"text-gray-300\";\n};\n\nconst InfoRow = ({\n icon,\n title,\n children\n}: {\n icon: ReactNode;\n title: string;\n children: ReactNode;\n}) => (\n <div>\n <div className=\"flex items-baseline gap-2\">\n <div className=\"flex h-4 w-4 flex-shrink-0 items-center justify-center text-gray-900\">{icon}</div>\n <h3 className=\"text-sm font-medium leading-4 text-gray-900\">{title}</h3>\n </div>\n <div className=\"pl-6\">{children}</div>\n </div>\n);\n\nconst renderInstallOrChannel = (values?: string[]) => {\n if (!values || values.length === 0) {\n return <p className=\"mt-1 text-sm text-gray-500\">Not specified</p>;\n }\n return (\n <p className=\"mt-1 text-sm text-gray-500\">\n {values.join(\", \")}\n </p>\n );\n};\n\nconst buildPrimaryRows = (license: License) => {\n const rows: Array<{ key: string; node: ReactNode }> = [];\n\n rows.push({\n key: \"status\",\n node: (\n <InfoRow\n icon={<ShieldIcon className=\"h-4 w-4\" />}\n title=\"License Status\"\n >\n <div className=\"mt-1 flex items-center text-sm text-gray-600\">\n <CheckIcon className=\"mr-1.5 h-4 w-4 text-green-500\" />\n <span>{license.isExpired ? \"Expired\" : \"Active\"}</span>\n </div>\n {license.environment ? (\n <p className=\"mt-1 text-sm text-gray-500\">\n {license.environment}\n </p>\n ) : null}\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"expiration\",\n node: (\n <InfoRow\n icon={<CalendarIcon className=\"h-4 w-4\" />}\n title=\"Expiration Date\"\n >\n <p className=\"mt-1 text-sm text-gray-500\">\n {formatExpiration(license.expiresAt)}\n </p>\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"channels\",\n node: (\n <InfoRow\n icon={<ShieldIcon className=\"h-4 w-4\" />}\n title=\"Release Channel(s)\"\n >\n {renderInstallOrChannel(license.releaseChannels)}\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"installs\",\n node: (\n <InfoRow\n icon={<DownloadIcon className=\"h-4 w-4\" />}\n title=\"Install Options\"\n >\n {renderInstallOrChannel(license.installMethods)}\n </InfoRow>\n )\n });\n\n rows.push({\n key: \"customer\",\n node: (\n <InfoRow\n icon={<BuildingIcon className=\"h-4 w-4\" />}\n title=\"Customer Name\"\n >\n <p className=\"mt-1 text-sm text-gray-500\">\n {license.customerName ?? \"Unknown customer\"}\n </p>\n {license.customerId ? (\n <p className=\"text-xs text-gray-400\">\n Customer ID: {license.customerId}\n </p>\n ) : null}\n </InfoRow>\n )\n });\n\n return rows;\n};\n\nconst renderFields = (fields: PortalLicenseField[]) => {\n if (!fields.length) {\n return (\n <p className=\"text-sm text-gray-500\">\n No additional fields available.\n </p>\n );\n }\n\n return (\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\">\n {fields.map((field) => (\n <div key={field.key} className=\"flex flex-col\">\n <p className=\"text-sm font-medium text-gray-900\">\n {field.label}\n </p>\n <p\n className={`mt-1 break-words text-sm ${getFieldTextClass(\n field.value\n )}`}\n >\n {maskValue(field.value, field.isSecret)}\n </p>\n </div>\n ))}\n </div>\n );\n};\n\nexport const LicenseDetails = async ({\n token,\n title = \"License Details\",\n description = \"View your enterprise license details\"\n}: LicenseDetailsProps) => {\n if (typeof token !== \"string\" || token.trim().length === 0) {\n throw new Error(\"LicenseDetails component requires a non-empty token\");\n }\n\n const license = await fetchLicense();\n const rows = buildPrimaryRows(license);\n\n return (\n <div className=\"rounded border border-gray-100 bg-white p-8 shadow-[0_18px_45px_rgba(17,24,39,0.08)]\">\n <header className=\"flex flex-col border-b border-gray-100 pb-6\">\n <h1 className=\"text-3xl font-bold text-gray-900\">\n {title}\n </h1>\n {description ? (\n <p className=\"mt-2 text-sm text-gray-600\">\n {description}\n </p>\n ) : null}\n </header>\n\n <div className=\"mt-6 space-y-6\">\n <div className=\"rounded-lg border border-gray-100 bg-white p-6 sm:p-8\">\n <div className=\"grid grid-cols-1 items-start gap-6 md:grid-cols-2 xl:grid-cols-3\">\n {rows.map((row) => (\n <div key={row.key}>{row.node}</div>\n ))}\n </div>\n </div>\n\n <div className=\"rounded-lg border border-gray-100 bg-white p-6 sm:p-8\">\n <h2 className=\"mb-4 text-lg font-medium text-gray-900\">\n Additional License Fields\n </h2>\n <div className=\"overflow-x-auto\">\n {renderFields(license.fields ?? [])}\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import type { ReactNode } from \"react\";\nimport Link from \"next/link\";\nimport { fetchCustomBranding } from \"../actions\";\nimport { decodeBranding, normalizeColor, type BackgroundType } from \"../utils/branding\";\n\nexport interface Customer {\n id: string;\n name: string;\n}\n\nexport interface TopNavLink {\n label: string;\n href?: string;\n icon: ReactNode;\n}\n\nexport interface TopNavBranding {\n logo?: string | null;\n title?: string;\n primaryColor?: string;\n secondaryColor?: string;\n background?: BackgroundType;\n backgroundImage?: string;\n backgroundGradientStart?: string;\n backgroundGradientEnd?: string;\n}\n\nexport interface TopNavProps {\n links?: TopNavLink[];\n hiddenLabels?: string[];\n additionalLinks?: TopNavLink[];\n order?: string[];\n userMenuLabel?: string;\n activeLabel?: string;\n customerName?: string;\n customers?: Customer[];\n currentCustomerId?: string;\n onChangeTeam?: (customerId: string) => Promise<void>;\n userMenuChildren?: ReactNode;\n logoutButton?: ReactNode;\n branding?: TopNavBranding;\n}\n\nconst defaultTopNavLinks: TopNavLink[] = [\n {\n label: \"Dashboard\",\n href: \"/\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect width=\"7\" height=\"9\" x=\"3\" y=\"3\" rx=\"1\" />\n <rect width=\"7\" height=\"5\" x=\"14\" y=\"3\" rx=\"1\" />\n <rect width=\"7\" height=\"9\" x=\"14\" y=\"12\" rx=\"1\" />\n <rect width=\"7\" height=\"5\" x=\"3\" y=\"16\" rx=\"1\" />\n </svg>\n )\n },\n {\n label: \"Install\",\n href: \"/install\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\" />\n </svg>\n )\n },\n {\n label: \"Update\",\n href: \"/update\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\" />\n <path d=\"M21 3v5h-5\" />\n </svg>\n )\n },\n {\n label: \"Security\",\n href: \"/security\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\" />\n </svg>\n )\n },\n {\n label: \"Release History\",\n href: \"/release-history\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\" />\n <path d=\"M14 2v4a2 2 0 0 0 2 2h4\" />\n <path d=\"M10 9H8\" />\n <path d=\"M16 13H8\" />\n <path d=\"M16 17H8\" />\n </svg>\n )\n },\n {\n label: \"License\",\n href: \"/license\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4\" />\n <path d=\"m21 2-9.6 9.6\" />\n <circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\" />\n </svg>\n )\n },\n {\n label: \"Support\",\n href: \"/support\",\n icon: (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n className=\"h-4 w-4\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"m4.93 4.93 4.24 4.24\" />\n <path d=\"m14.83 9.17 4.24-4.24\" />\n <path d=\"m14.83 14.83 4.24 4.24\" />\n <path d=\"m9.17 14.83-4.24 4.24\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n </svg>\n )\n }\n];\n\nconst orderLinks = (links: TopNavLink[], order?: string[]) => {\n if (!order || order.length === 0) {\n return links;\n }\n\n const orderMap = new Map(order.map((label, index) => [label, index]));\n return links\n .map((link, index) => ({\n link,\n originalIndex: index,\n orderIndex: orderMap.has(link.label)\n ? (orderMap.get(link.label) as number)\n : order.length + index\n }))\n .sort((a, b) => {\n if (a.orderIndex === b.orderIndex) {\n return a.originalIndex - b.originalIndex;\n }\n return a.orderIndex - b.orderIndex;\n })\n .map((item) => item.link);\n};\n\n/**\n * TopNav renders the hero navigation bar shown on authenticated dashboards.\n */\nexport const TopNav = async ({\n links,\n hiddenLabels,\n additionalLinks,\n order,\n userMenuLabel,\n activeLabel,\n customerName,\n customers,\n currentCustomerId,\n onChangeTeam,\n userMenuChildren,\n logoutButton,\n branding: brandingProp\n}: TopNavProps) => {\n const displayLabel = userMenuLabel || (customerName ? `Team: ${customerName}` : \"Team: Example\");\n let logo: string | undefined;\n let brandTitle: string | undefined;\n let primaryColor: string | undefined;\n let secondaryColor: string | undefined;\n let background: BackgroundType | undefined;\n let backgroundImageUrl: string | undefined;\n let backgroundGradientStart: string | undefined;\n let backgroundGradientEnd: string | undefined;\n\n // Use branding prop if provided, otherwise fetch it\n if (brandingProp) {\n if (brandingProp.logo && typeof brandingProp.logo === \"string\") {\n logo = brandingProp.logo;\n }\n if (brandingProp.title && typeof brandingProp.title === \"string\") {\n const normalizedTitle = brandingProp.title.trim();\n if (normalizedTitle) {\n brandTitle = normalizedTitle;\n }\n }\n primaryColor = normalizeColor(brandingProp.primaryColor);\n secondaryColor = normalizeColor(brandingProp.secondaryColor);\n background = brandingProp.background;\n backgroundImageUrl = brandingProp.backgroundImage;\n backgroundGradientStart = normalizeColor(brandingProp.backgroundGradientStart);\n backgroundGradientEnd = normalizeColor(brandingProp.backgroundGradientEnd);\n } else {\n try {\n const brandingResponse = await fetchCustomBranding();\n const branding = decodeBranding({ brandingData: brandingResponse.brandingData });\n logo = branding.logo;\n brandTitle = branding.title;\n primaryColor = branding.primaryColor;\n secondaryColor = branding.secondaryColor;\n background = branding.background;\n backgroundImageUrl = branding.backgroundImage;\n backgroundGradientStart = branding.backgroundGradientStart;\n backgroundGradientEnd = branding.backgroundGradientEnd;\n } catch (error) {\n console.debug(\"[portal-components] branding fetch failed\", error);\n }\n }\n\n const baseLinks = links ?? defaultTopNavLinks;\n const hiddenSet = hiddenLabels ? new Set(hiddenLabels) : null;\n let resolvedLinks = baseLinks.filter(\n (link) => !hiddenSet?.has(link.label)\n );\n\n if (additionalLinks?.length) {\n resolvedLinks = [...resolvedLinks, ...additionalLinks];\n }\n\n resolvedLinks = orderLinks(resolvedLinks, order);\n\n // Determine header background style based on background type:\n // - \"custom\": use background gradient colors (customColor1/customColor2)\n // - \"image\": use the background image URL with overlay gradient\n // - \"minimal\" or undefined: use primary/secondary colors\n const getHeaderBackgroundStyle = (): React.CSSProperties => {\n if (background === \"image\" && backgroundImageUrl) {\n return {\n background: `url(${backgroundImageUrl})`,\n backgroundImage: `linear-gradient(to top, rgba(255, 255, 255, 0.3) 30%, rgba(255, 255, 255, 0)), url(${backgroundImageUrl})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\"\n };\n }\n\n const gradientStart = (background === \"custom\" && backgroundGradientStart)\n ? backgroundGradientStart\n : primaryColor;\n const gradientEnd = (background === \"custom\" && backgroundGradientEnd)\n ? backgroundGradientEnd\n : secondaryColor;\n\n return {\n backgroundImage: `linear-gradient(to top, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0) 33%), linear-gradient(${gradientStart}, ${gradientEnd})`,\n backgroundRepeat: \"no-repeat\",\n backgroundSize: \"100% 100%\"\n };\n };\n\n return (\n <div\n className=\"relative flex h-[280px] w-full items-start justify-center\"\n style={getHeaderBackgroundStyle()}\n >\n <div className=\"mx-auto mt-[30px] w-full max-w-[1248px] px-6\">\n <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)]\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {logo ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={logo}\n alt=\"Portal logo\"\n className=\"object-contain\"\n style={{\n maxWidth: \"240px\",\n maxHeight: \"48px\"\n }}\n />\n ) : (\n <svg\n className=\"h-8 w-8 text-gray-400\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <ellipse cx=\"12\" cy=\"12\" rx=\"4\" ry=\"10\" />\n <path d=\"M2 12h20\" />\n </svg>\n )}\n <span className=\"text-xl font-bold text-gray-900\">\n {brandTitle || \"Enterprise Portal\"}\n </span>\n </div>\n <details className=\"group relative\">\n <summary className=\"flex cursor-pointer items-center gap-2 text-sm font-medium text-gray-600 hover:text-gray-900 list-none\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-gray-500\"\n >\n <path d=\"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2\"></path>\n <circle cx=\"12\" cy=\"7\" r=\"4\"></circle>\n </svg>\n <span>{displayLabel}</span>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"text-gray-500\"\n >\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n </summary>\n <div className=\"absolute right-0 mt-2 w-48 rounded-md border border-gray-200 bg-white py-2 text-sm text-gray-700 shadow-lg z-50\">\n <Link\n href=\"/user-settings\"\n className=\"block w-full px-4 py-2 text-left hover:bg-gray-100\"\n >\n User settings\n </Link>\n <Link\n href=\"/team-settings\"\n className=\"block w-full px-4 py-2 text-left hover:bg-gray-100\"\n >\n Team settings\n </Link>\n {userMenuChildren}\n {logoutButton}\n </div>\n </details>\n </div>\n <div className=\"mt-3 flex flex-wrap gap-3 pb-2 text-sm font-medium text-gray-500\">\n {resolvedLinks.map(({ label, icon, href }) => {\n const isActive = activeLabel === label;\n const className = `flex items-center gap-2 px-4 py-1 transition text-gray-500 ${\n isActive ? \"underline underline-offset-8 decoration-2\" : \"\"\n }`;\n\n if (href) {\n return (\n <Link key={label} href={href} className={className}>\n <span className={isActive ? \"text-gray-900\" : \"text-gray-500\"}>\n {icon}\n </span>\n <span>{label}</span>\n </Link>\n );\n }\n\n return (\n <button key={label} className={className} type=\"button\">\n <span className={isActive ? \"text-gray-900\" : \"text-gray-500\"}>\n {icon}\n </span>\n <span>{label}</span>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport { defaultTopNavLinks };\n","import type { SVGProps } from \"react\";\nimport Link from \"next/link\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\nconst GlobeIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418\" />\n </svg>\n);\n\nconst AirGapIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M13.181 8.68a4.503 4.503 0 0 1 1.903 6.405m-9.768-2.782L3.56 14.06a4.5 4.5 0 0 0 6.364 6.365l3.129-3.129m5.614-5.615 1.757-1.757a4.5 4.5 0 0 0-6.364-6.365l-4.5 4.5c-.258.26-.479.541-.661.84m1.903 6.405a4.495 4.495 0 0 1-1.242-.88 4.483 4.483 0 0 1-1.062-1.683m6.587 2.345 5.907 5.907m-5.907-5.907L8.898 8.898M2.991 2.99 8.898 8.9\" />\n </svg>\n);\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst contentClass = \"mt-4 flex-1 space-y-3\";\nconst itemClass = \"flex items-center gap-3 text-sm text-gray-600\";\nconst iconClass = \"h-5 w-5 text-gray-500\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold hover:opacity-80\";\nconst badgeClass =\n \"ml-2 inline-flex h-5 min-w-[20px] items-center justify-center rounded-full px-1.5 text-xs font-medium text-white\";\n\nexport interface UpdatesCardProps {\n /** Number of active online instances (checked in within 24 hours) */\n onlineActiveCount?: number;\n /** Number of air gap instances */\n airgapCount?: number;\n /** Number of updates available for online instances */\n onlineUpdates?: number;\n /** Number of updates available for airgap instances */\n airgapUpdates?: number;\n}\n\nconst Badge = ({ count }: { count: number }) => (\n <span\n className={badgeClass}\n style={{ backgroundColor: `var(--portal-branding-primary, ${DEFAULT_SECONDARY_COLOR})` }}\n aria-label={`${count} updates available`}\n >\n {count}\n </span>\n);\n\nexport const UpdatesCard = ({\n onlineActiveCount = 0,\n airgapCount = 0,\n onlineUpdates = 0,\n airgapUpdates = 0\n}: UpdatesCardProps) => (\n <section className={baseCardClass} aria-labelledby=\"updates-card-heading\">\n <header>\n <h2 id=\"updates-card-heading\" className={headingClass}>\n Updates\n </h2>\n </header>\n <div className={contentClass}>\n <div className={itemClass}>\n <GlobeIcon className={iconClass} />\n <span>\n {onlineActiveCount} Active Online {onlineActiveCount === 1 ? \"instance\" : \"instances\"}\n </span>\n {onlineUpdates > 0 && <Badge count={onlineUpdates} />}\n </div>\n <div className={itemClass}>\n <AirGapIcon className={iconClass} />\n <span>\n {airgapCount} Air gap {airgapCount === 1 ? \"instance\" : \"instances\"}\n </span>\n {airgapUpdates > 0 && <Badge count={airgapUpdates} />}\n </div>\n </div>\n <footer className={footerClass}>\n <Link href=\"/update\" style={{ color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }}>View updates →</Link>\n </footer>\n </section>\n);\n\nUpdatesCard.displayName = \"UpdatesCard\";\n","import type { SVGProps } from \"react\";\nimport Link from \"next/link\";\nimport { listSupportBundles } from \"../actions\";\nimport { isRedirectError } from \"../utils/api-client\";\n\nconst UploadIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5\" />\n </svg>\n);\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst contentClass = \"mt-4 flex-1 space-y-3\";\nconst itemClass = \"flex items-center gap-3 text-sm text-gray-600\";\nconst iconClass = \"h-5 w-5 text-gray-500\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold text-primary hover:text-primary/80\";\n\nexport const SupportCard = async () => {\n let totalCount: number | null = null;\n try {\n const headersModule = await import(\"next/headers\");\n const store = await headersModule.cookies();\n const session = store.get(\"portal_session\");\n const token = session?.value;\n if (token) {\n const result = await listSupportBundles.run({ token });\n totalCount = result.totalCount;\n } else {\n console.debug(\"[portal-components] no portal_session token for support bundles\");\n }\n } catch (error) {\n // Re-throw redirect errors so Next.js can handle navigation\n if (isRedirectError(error)) {\n throw error;\n }\n console.error(\"[portal-components] support bundles fetch failed\", error);\n }\n\n return (\n <section className={baseCardClass} aria-labelledby=\"support-card-heading\">\n <header>\n <h2 id=\"support-card-heading\" className={headingClass}>\n Support\n </h2>\n </header>\n <div className={contentClass}>\n <div className={itemClass}>\n <UploadIcon className={iconClass} />\n <span>\n Support bundles uploaded ({totalCount ?? 0})\n </span>\n </div>\n </div>\n <footer className={footerClass}>\n <Link href=\"/support\" className=\"inline-flex items-center gap-1\">\n View support guide →\n </Link>\n </footer>\n </section>\n );\n};\n\nSupportCard.displayName = \"SupportCard\";\n","\"use client\";\n\nimport { useState, useMemo } from \"react\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UserSettingsUser {\n emailAddress: string;\n firstName?: string;\n lastName?: string;\n}\n\nexport interface UserSettingsTeam {\n id: string;\n name: string;\n appId: string;\n appName: string;\n appSlug: string;\n}\n\nexport interface UserSettingsCustomer {\n id: string;\n name: string;\n}\n\nexport interface UserSettingsNotification {\n type: string;\n enabled: boolean;\n}\n\nexport interface UserSettingsProps {\n // User profile\n user?: UserSettingsUser;\n isUserLoading?: boolean;\n userError?: Error | null;\n \n // Profile editing\n isUpdating?: boolean;\n updateError?: Error | null;\n onUpdateUser?: (data: { firstName?: string; lastName?: string }) => Promise<void>;\n \n // Teams\n teams?: UserSettingsTeam[];\n currentCustomer?: UserSettingsCustomer;\n isTeamsLoading?: boolean;\n onTeamSwitch?: (team: UserSettingsTeam) => Promise<void>;\n \n // Notifications\n notifications?: UserSettingsNotification[];\n isNotificationsLoading?: boolean;\n onToggleNotification?: (notificationType: string, enabled: boolean) => Promise<void>;\n \n // Optional branding\n primaryColor?: string;\n}\n\n// =============================================================================\n// Notification descriptions\n// =============================================================================\n\nconst NOTIFICATION_DESCRIPTIONS: Record<string, string> = {\n \"new-version\": \"New version available\",\n};\n\n// =============================================================================\n// Email Notifications Section\n// =============================================================================\n\ninterface EmailNotificationsSectionProps {\n teamName: string;\n notifications: UserSettingsNotification[];\n isLoading: boolean;\n onToggle?: (type: string, enabled: boolean) => Promise<void>;\n}\n\nconst EmailNotificationsSection = ({\n teamName,\n notifications,\n isLoading,\n onToggle,\n}: EmailNotificationsSectionProps) => {\n // Merge API data with all notification types to ensure all options are always shown\n const allNotificationTypes = Object.keys(NOTIFICATION_DESCRIPTIONS);\n const mergedNotifications = allNotificationTypes.map((type) => {\n const existing = notifications.find((n) => n.type === type);\n return {\n type,\n enabled: existing ? existing.enabled : type === \"new-version\", // Default new-version to true\n };\n });\n\n if (isLoading) {\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">\n Email Notifications for {teamName}\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Choose which email notifications you want to receive for this team.\n </p>\n <div className=\"mt-6 flex justify-center py-8\">\n <p className=\"text-sm text-gray-500\">Loading notifications...</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">\n Email Notifications for {teamName}\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Choose which email notifications you want to receive for this team.\n </p>\n\n <div className=\"mt-6 overflow-hidden rounded-lg border border-gray-200\">\n <div className=\"flex items-center justify-between bg-gray-50 px-4 py-2\">\n <span className=\"text-xs font-medium uppercase text-gray-600\">\n Description\n </span>\n <span className=\"text-xs font-medium uppercase text-gray-600\">\n Enabled\n </span>\n </div>\n {mergedNotifications.map((notification) => (\n <div\n key={notification.type}\n className=\"flex items-center justify-between border-t border-gray-200 px-4 py-3\"\n >\n <span className=\"text-sm text-gray-900\">\n {NOTIFICATION_DESCRIPTIONS[notification.type]}\n </span>\n <input\n type=\"checkbox\"\n checked={notification.enabled}\n onChange={() => onToggle?.(notification.type, !notification.enabled)}\n className=\"portal-checkbox\"\n />\n </div>\n ))}\n </div>\n <p className=\"mt-3 text-xs text-gray-500\">\n These notification preferences are specific to the {teamName} team.\n Switch teams to manage notifications for other teams.\n </p>\n </div>\n );\n};\n\n// =============================================================================\n// Teams Section\n// =============================================================================\n\ninterface TeamsSectionProps {\n teams: UserSettingsTeam[];\n currentCustomer?: UserSettingsCustomer;\n isLoading: boolean;\n onTeamSwitch?: (team: UserSettingsTeam) => Promise<void>;\n primaryColor?: string;\n}\n\nconst TeamsSection = ({\n teams,\n currentCustomer,\n isLoading,\n onTeamSwitch,\n primaryColor,\n}: TeamsSectionProps) => {\n // Group teams by app\n const groupedTeams = useMemo(() => {\n const groups = new Map<string, { appName: string; teams: UserSettingsTeam[] }>();\n \n for (const team of teams) {\n const existing = groups.get(team.appId);\n if (existing) {\n existing.teams.push(team);\n } else {\n groups.set(team.appId, {\n appName: team.appName,\n teams: [team],\n });\n }\n }\n \n return groups;\n }, [teams]);\n\n if (isLoading) {\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">Teams</h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Teams associate your email address with any additional licenses your\n account has access to.\n </p>\n <div className=\"mt-6\">\n <p className=\"text-sm text-gray-500\">Loading teams...</p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <h2 className=\"text-lg font-semibold text-gray-900\">Teams</h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n Teams associate your email address with any additional licenses your\n account has access to.\n </p>\n\n <div className=\"mt-6 space-y-6\">\n {Array.from(groupedTeams.values()).map((appGroup) => (\n <div key={appGroup.appName} className=\"space-y-3\">\n <h3 className=\"text-base font-medium text-gray-900\">\n {appGroup.appName}\n </h3>\n <div className=\"space-y-2\">\n {appGroup.teams.map((team) => {\n const isCurrentTeam = currentCustomer?.id === team.id;\n return (\n <button\n key={team.id}\n type=\"button\"\n onClick={() => !isCurrentTeam && onTeamSwitch?.(team)}\n disabled={isCurrentTeam}\n className={`flex w-full items-center justify-between rounded-lg border p-4 text-left transition ${\n isCurrentTeam\n ? \"cursor-default border-gray-300 bg-gray-50\"\n : \"cursor-pointer border-gray-200 hover:border-gray-400\"\n }`}\n style={\n !isCurrentTeam && primaryColor\n ? { \"--hover-border\": primaryColor } as React.CSSProperties\n : undefined\n }\n >\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"h-4 w-4\"\n style={{ color: primaryColor || DEFAULT_SECONDARY_COLOR }}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z\"\n />\n </svg>\n <div>\n <p className=\"text-sm font-medium text-gray-900\">\n {team.name}\n </p>\n {isCurrentTeam && (\n <p className=\"text-xs text-gray-500\">Current Team</p>\n )}\n </div>\n </div>\n {!isCurrentTeam && (\n <svg\n className=\"h-4 w-4\"\n style={{ color: primaryColor || DEFAULT_SECONDARY_COLOR }}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n strokeWidth={2}\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n )}\n </button>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n};\n\n// =============================================================================\n// Profile Section\n// =============================================================================\n\ninterface ProfileSectionProps {\n user?: UserSettingsUser;\n isLoading: boolean;\n isUpdating: boolean;\n error?: Error | null;\n updateError?: Error | null;\n onSave?: (data: { firstName?: string; lastName?: string }) => Promise<void>;\n primaryColor?: string;\n}\n\nconst ProfileSection = ({\n user,\n isLoading,\n isUpdating,\n error,\n updateError,\n onSave,\n primaryColor,\n}: ProfileSectionProps) => {\n const [isEditing, setIsEditing] = useState(false);\n const [firstName, setFirstName] = useState(user?.firstName || \"\");\n const [lastName, setLastName] = useState(user?.lastName || \"\");\n const [inputError, setInputError] = useState<string | null>(null);\n\n // Reset form when user changes\n const resetForm = () => {\n setFirstName(user?.firstName || \"\");\n setLastName(user?.lastName || \"\");\n setInputError(null);\n };\n\n const handleSave = async () => {\n if (!firstName && !lastName) {\n setInputError(\"Please enter a first name or last name\");\n return;\n }\n\n if (firstName === user?.firstName && lastName === user?.lastName) {\n setIsEditing(false);\n return;\n }\n\n try {\n await onSave?.({ firstName, lastName });\n setIsEditing(false);\n } catch (err) {\n console.error(\"Error updating user information:\", err);\n }\n };\n\n const handleCancel = () => {\n setIsEditing(false);\n resetForm();\n };\n\n const handleEdit = () => {\n resetForm();\n setIsEditing(true);\n };\n\n const buttonStyle = {\n backgroundColor: primaryColor || DEFAULT_SECONDARY_COLOR,\n borderColor: primaryColor || DEFAULT_SECONDARY_COLOR\n };\n\n return (\n <div className=\"rounded-2xl border border-gray-200 bg-white p-6 shadow-sm\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900\">\n Profile Information\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">Your account information.</p>\n {(error || updateError) && (\n <p className=\"mt-2 text-sm text-red-600\">\n {error?.message || updateError?.message || \"Failed to update profile\"}\n </p>\n )}\n {inputError && (\n <p className=\"mt-2 text-sm text-red-600\">{inputError}</p>\n )}\n </div>\n {isEditing ? (\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={handleCancel}\n disabled={isUpdating}\n className=\"inline-flex items-center rounded-md border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 shadow-sm transition hover:bg-gray-50 disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={isUpdating}\n style={buttonStyle}\n 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]\"\n >\n {isUpdating ? \"Saving...\" : \"Save\"}\n </button>\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={handleEdit}\n style={buttonStyle}\n 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]\"\n >\n Edit\n </button>\n )}\n </div>\n\n <div className=\"mt-6 flex gap-8\">\n {isEditing ? (\n <div className=\"flex gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-gray-600\">\n First Name\n </label>\n <input\n type=\"text\"\n value={firstName}\n onChange={(e) => {\n setInputError(null);\n setFirstName(e.target.value);\n }}\n disabled={isUpdating}\n placeholder=\"First Name\"\n className=\"portal-input mt-1 block w-48\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-600\">\n Last Name\n </label>\n <input\n type=\"text\"\n value={lastName}\n onChange={(e) => {\n setInputError(null);\n setLastName(e.target.value);\n }}\n disabled={isUpdating}\n placeholder=\"Last Name\"\n className=\"portal-input mt-1 block w-48\"\n />\n </div>\n </div>\n ) : (\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium text-gray-600\">\n Full Name (optional)\n </label>\n <p className=\"mt-1 text-sm text-gray-900\">\n {user?.firstName || user?.lastName\n ? `${user.firstName || \"\"} ${user.lastName || \"\"}`.trim()\n : \"—\"}\n </p>\n </div>\n )}\n <div className=\"flex-1\">\n <label className=\"block text-sm font-medium text-gray-600\">Email</label>\n <p className=\"mt-1 text-sm text-gray-500\">\n {isLoading ? \"Loading...\" : user?.emailAddress || \"\"}\n </p>\n </div>\n </div>\n </div>\n );\n};\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\nexport const UserSettings = ({\n user,\n isUserLoading = false,\n userError,\n isUpdating = false,\n updateError,\n onUpdateUser,\n teams = [],\n currentCustomer,\n isTeamsLoading = false,\n onTeamSwitch,\n notifications = [],\n isNotificationsLoading = false,\n onToggleNotification,\n primaryColor,\n}: UserSettingsProps) => {\n if (userError) {\n return (\n <div className=\"p-8\">\n <div className=\"text-red-600\">\n Failed to load user settings. {userError?.message} Please try again later.\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"w-full space-y-6\">\n <header>\n <h1 className=\"text-2xl font-semibold text-gray-900\">User Settings</h1>\n </header>\n\n <div className=\"space-y-6\">\n <ProfileSection\n user={user}\n isLoading={isUserLoading}\n isUpdating={isUpdating}\n error={userError}\n updateError={updateError}\n onSave={onUpdateUser}\n primaryColor={primaryColor}\n />\n\n <TeamsSection\n teams={teams}\n currentCustomer={currentCustomer}\n isLoading={isTeamsLoading}\n onTeamSwitch={onTeamSwitch}\n primaryColor={primaryColor}\n />\n\n {currentCustomer && (\n <EmailNotificationsSection\n teamName={currentCustomer.name}\n notifications={notifications}\n isLoading={isNotificationsLoading}\n onToggle={onToggleNotification}\n />\n )}\n </div>\n </div>\n );\n};\n\nUserSettings.displayName = \"UserSettings\";\n","import Link from \"next/link\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst bodySpacerClass = \"mt-4 flex-1\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold hover:opacity-80\";\n\nexport const UserSettingsCard = () => (\n <section className={baseCardClass} aria-labelledby=\"user-settings-card-heading\">\n <header>\n <h2 id=\"user-settings-card-heading\" className={headingClass}>\n User Settings\n </h2>\n </header>\n <div className={bodySpacerClass} />\n <footer className={footerClass}>\n <Link href=\"/user-settings\" style={{ color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }}>View user settings →</Link>\n </footer>\n </section>\n);\n\nUserSettingsCard.displayName = \"UserSettingsCard\";\n","import type { SVGProps } from \"react\";\nimport Link from \"next/link\";\nimport { DEFAULT_SECONDARY_COLOR } from \"../utils/constants\";\n\nconst UsersIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z\" />\n </svg>\n);\n\nconst KeyIcon = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n <path d=\"M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z\" />\n </svg>\n);\n\nconst baseCardClass =\n \"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)]\";\nconst headingClass = \"text-lg font-semibold text-gray-900\";\nconst contentClass = \"mt-4 flex-1 space-y-3\";\nconst itemClass = \"flex items-center gap-3 text-sm text-gray-600\";\nconst iconClass = \"h-5 w-5 text-gray-500\";\nconst footerClass =\n \"mt-6 flex justify-end text-sm font-semibold hover:opacity-80\";\n\nexport interface TeamSettingsCardProps {\n /** Number of team members */\n userCount?: number;\n /** Number of service accounts */\n serviceAccountCount?: number;\n}\n\nexport const TeamSettingsCard = ({\n userCount = 0,\n serviceAccountCount = 0\n}: TeamSettingsCardProps) => (\n <section className={baseCardClass} aria-labelledby=\"team-settings-card-heading\">\n <header>\n <h2 id=\"team-settings-card-heading\" className={headingClass}>\n Team Settings\n </h2>\n </header>\n <div className={contentClass}>\n <div className={itemClass}>\n <UsersIcon className={iconClass} />\n <span>\n {userCount} Team {userCount === 1 ? \"Member\" : \"Members\"}\n </span>\n </div>\n <div className={itemClass}>\n <KeyIcon className={iconClass} />\n <span>\n {serviceAccountCount} Service {serviceAccountCount === 1 ? \"Account\" : \"Accounts\"}\n </span>\n </div>\n </div>\n <footer className={footerClass}>\n <Link href=\"/team-settings\" style={{ color: `var(--portal-branding-secondary, ${DEFAULT_SECONDARY_COLOR})` }}>View team settings →</Link>\n </footer>\n </section>\n);\n\nTeamSettingsCard.displayName = \"TeamSettingsCard\";\n","import { ReactNode } from \"react\";\nimport { TopNav } from \"./top-nav\";\n\ninterface UpdateLayoutProps {\n children: ReactNode;\n}\n\nexport const UpdateLayout = ({ children }: UpdateLayoutProps) => {\n return (\n <div className=\"min-h-screen bg-white\">\n <TopNav activeLabel=\"Updates\" />\n <div className=\"px-6 py-8\">\n <div className=\"mx-auto w-full max-w-[1248px]\">\n {children}\n </div>\n </div>\n </div>\n );\n};\n\nUpdateLayout.displayName = \"UpdateLayout\";\n","import { getApiOrigin } from \"./actions\";\n\n/**\n * Result of setting a SAML session.\n */\nexport interface SetSamlSessionResult {\n success: boolean;\n message?: string;\n}\n\n/**\n * Implementation for setting the SAML session cookie after successful authentication.\n * This must be wrapped in a server action with 'use server' in your Next.js app.\n * \n * @param token - The JWT token from SAML authentication (with or without \"Bearer \" prefix)\n * @returns Result indicating success or failure with optional error message\n * \n * Usage in template actions.ts:\n * ```typescript\n * 'use server';\n * import { setSamlSessionImpl } from \"@replicated/portal-components/saml-handlers\";\n * import { traceServerAction } from \"@replicated/portal-components/observability\";\n * \n * async function setSamlSessionActionImpl(token: string) {\n * return setSamlSessionImpl(token);\n * }\n * \n * export const setSamlSessionAction = traceServerAction(\"setSamlSessionAction\", setSamlSessionActionImpl);\n * ```\n */\nexport async function setSamlSessionImpl(token: string): Promise<SetSamlSessionResult> {\n try {\n if (!token) {\n return { success: false, message: \"No token provided\" };\n }\n\n // Remove \"Bearer \" prefix if present\n const cleanToken = token.startsWith(\"Bearer \") ? token.slice(7) : token;\n\n // Dynamic import to ensure this only runs in server context\n const { cookies } = await import(\"next/headers\");\n const cookieStore = await cookies();\n\n // For cross-origin iframes over HTTP (repldev), we need sameSite: \"none\" + secure: true\n // Chrome allows this for localhost even over HTTP\n const isHttpOrigin = process.env.REPLICATED_APP_ORIGIN?.startsWith('http://');\n \n // Force secure: true and sameSite: \"none\" for repldev cross-origin iframe\n const secure = true;\n const sameSiteValue = isHttpOrigin ? \"none\" : \"lax\";\n\n // Use the string-based API which is compatible across Next.js versions\n cookieStore.set(\"portal_session\", cleanToken, {\n httpOnly: true,\n secure: secure,\n sameSite: sameSiteValue,\n path: \"/\"\n });\n\n return { success: true };\n } catch (error) {\n console.error(\"[saml-handlers] Error setting session:\", error);\n return { \n success: false, \n message: \"Failed to establish session\" \n };\n }\n}\n\n/**\n * Shared SAML ACS (Assertion Consumer Service) handler logic.\n * This proxies SAML responses from the IdP to the backend API.\n * \n * Flow:\n * 1. IdP POSTs SAMLResponse here\n * 2. Forward to backend /saml/acs\n * 3. Backend validates, creates JWT, returns 302 redirect\n * 4. Pass redirect through to browser to hit /saml/callback\n * \n * Usage in Next.js route handler:\n * ```typescript\n * import { handleSamlAcs } from \"@replicated/portal-components/saml-handlers\";\n * \n * export async function POST(request: NextRequest) {\n * return handleSamlAcs(request);\n * }\n * ```\n */\nexport async function handleSamlAcs(request: Request): Promise<Response> {\n try {\n const apiOrigin = getApiOrigin();\n \n // Get form data from IdP POST request\n const formData = await request.formData();\n \n // Forward to backend, don't follow redirects automatically\n const response = await fetch(`${apiOrigin}/saml/acs`, {\n method: 'POST',\n body: formData,\n redirect: 'manual',\n });\n \n // Backend should return 302 with Location header pointing to /saml/callback#token=...\n if (response.status === 302 || response.status === 301) {\n const location = response.headers.get('Location');\n if (location) {\n // Pass through the redirect to the browser\n return Response.redirect(location, response.status);\n }\n }\n \n // Handle error responses from backend\n console.error('[saml-acs] Error response from backend:', {\n status: response.status,\n statusText: response.statusText,\n });\n \n // Map status codes to user-friendly messages\n let errorMessage = 'SAML authentication failed';\n if (response.status === 401 || response.status === 403) {\n errorMessage = 'Authentication failed. Please check your credentials or contact your administrator.';\n } else if (response.status === 400) {\n errorMessage = 'Invalid SAML request. Please try again.';\n }\n \n // Redirect to error page with actual status code\n return Response.redirect(\n new URL(`/error?code=${response.status}&message=${encodeURIComponent(errorMessage)}`, request.url),\n 302\n );\n } catch (error) {\n console.error('[saml-acs] Error processing SAML response:', error);\n \n // Redirect to error page\n return Response.redirect(\n new URL(`/error?code=500&message=${encodeURIComponent('SAML authentication error')}`, request.url),\n 302\n );\n }\n}\n","import packageJson from \"../package.json\";\n\nexport const portalComponentsVersion = packageJson.version;\n\nexport type {\n ComponentAccessibilityMetadata,\n ComponentBehaviorMetadata,\n ComponentCategory,\n ComponentRegistryDocument,\n ComponentRegistryEntry,\n ComponentExampleMetadata,\n ComponentPerformanceMetadata,\n ComponentPropMetadata\n} from \"./types/metadata\";\n\nexport {\n createPortalTheme,\n portalThemeTokens\n} from \"./tokens\";\nexport type { PortalThemeTokens, PortalThemeOverrides } from \"./tokens\";\n\nexport * from \"./components\";\nexport * from \"./utils\";\nexport * from \"./saml-handlers\";\n\nexport {\n defineServerAction,\n fetchCustomBranding,\n fetchLicense,\n listReleases,\n initiateLogin,\n listSupportBundles,\n downloadSupportBundle,\n deleteSupportBundle,\n uploadSupportBundle,\n getSupportBundleUploadUrl,\n decodeJwtPayload,\n getCustomerIdFromToken,\n verifyMagicLink,\n // Dashboard actions\n fetchDashboardComposite,\n // Security actions\n getSecurityInfo,\n getSecurityInfoDiff,\n getSecurityInfoSBOM,\n downloadSecuritySBOM,\n // User settings actions\n fetchCurrentUser,\n updateUser,\n fetchNotifications,\n updateNotifications\n} from \"./actions\";\n\n// Client components have their own entry points - don't export from main index\n// See src/components/index.ts for the full list and import paths\nexport type {\n PortalActionContext,\n PortalActionVisibility,\n PortalServerActionDefinition,\n CustomBrandingResponse,\n FetchLicenseInput,\n FetchLicenseResult,\n ReleaseHelmChart,\n DownloadPortalRelease,\n ListReleasesResult,\n License,\n LicenseChannel,\n EntitlementField,\n EntitlementValue,\n CustomHostnameOverrides,\n PortalLicenseField,\n InitiateLoginInput,\n InitiateLoginResult,\n VerifyMagicLinkInput,\n VerifyMagicLinkResult,\n VerifyMagicLinkError,\n ListSupportBundlesInput,\n ListSupportBundlesResult,\n SupportBundleSummary,\n SupportBundleInsight,\n DownloadSupportBundleInput,\n DownloadSupportBundleResult,\n DeleteSupportBundleInput,\n DeleteSupportBundleResult,\n UploadSupportBundleCompleteInput,\n UploadSupportBundleCompleteResult,\n // Security types\n SecurityInstallType,\n SecurityScanSummary,\n SecurityScanWrapper,\n SecurityReleaseImage,\n GetSecurityInfoInput,\n GetSecurityInfoResult,\n SecurityInfoDiff,\n GetSecurityInfoDiffInput,\n GetSecurityInfoDiffResult,\n SBOMMetadata,\n GetSecurityInfoSBOMInput,\n GetSecurityInfoSBOMResult,\n DownloadSBOMInput,\n // Install types\n ChannelRelease,\n FetchChannelReleasesResult,\n // User settings types\n FetchCurrentUserInput,\n FetchCurrentUserResult,\n UserProfile,\n UpdateUserInput,\n UpdateUserResult,\n NotificationSetting,\n FetchNotificationsInput,\n FetchNotificationsResult,\n UpdateNotificationsInput,\n UpdateNotificationsResult\n} from \"./actions\";\n\nexport type { InitialSecurityData } from \"./components/security-card\";\n"]}
|