"use client"; import CertificateStatus from "@app/components/CertificateStatus"; import CopyToClipboard from "@app/components/CopyToClipboard"; import { InfoSection, InfoSectionContent, InfoSections, InfoSectionTitle } from "@app/components/InfoSection"; import { Alert, AlertDescription } from "@app/components/ui/alert"; import { useSiteResourceContext } from "@app/hooks/useSiteResourceContext"; import { formatPortRestrictionDisplay } from "@app/lib/launcherResourceDetails"; import { formatSiteResourceAccess, formatSiteResourceDestinationDisplay, isSafeUrlForLink, type LauncherAccessFields } from "@app/lib/launcherResourceAccess"; import type { PrivateResourceMode } from "@app/lib/privateResourceForm"; import { build } from "@server/build"; import { useTranslations } from "next-intl"; type SiteResourceInfoInput = { orgId: string; mode: PrivateResourceMode; destination: string | null; destinationPort: number | null; scheme: "http" | "https" | null; ssl: boolean; domainId?: string | null; fullDomain?: string | null; alias?: string | null; aliasAddress?: string | null; authDaemonMode?: "site" | "remote" | "native" | null; tcpPortRangeString?: string | null; udpPortRangeString?: string | null; }; type SiteResourceInfoBoxVariant = "settings" | "panel"; type SiteResourceInfoSectionsProps = { siteResource: SiteResourceInfoInput; access: LauncherAccessFields; variant: SiteResourceInfoBoxVariant; accessClassName?: string; }; function AccessMethodContent({ accessDisplay, accessCopyValue, accessUrl, className }: LauncherAccessFields & { className?: string }) { if (!accessDisplay) { return -; } const href = accessUrl ?? undefined; const canLink = Boolean(href && isSafeUrlForLink(href)); if (canLink && href) { return ( ); } return ( ); } export function SiteResourceInfoSections({ siteResource, access, variant, accessClassName }: SiteResourceInfoSectionsProps) { const t = useTranslations(); const isPanel = variant === "panel"; const modeLabel: Record = { host: t("editInternalResourceDialogModeHost"), cidr: t("editInternalResourceDialogModeCidr"), http: t("editInternalResourceDialogModeHttp"), ssh: t("editInternalResourceDialogModeSsh") }; const destination = formatSiteResourceDestinationDisplay({ mode: siteResource.mode, destination: siteResource.destination, destinationPort: siteResource.destinationPort, scheme: siteResource.scheme }); const portRestrictions = formatPortRestrictionDisplay({ tcpPortRangeString: siteResource.tcpPortRangeString ?? "*", udpPortRangeString: siteResource.udpPortRangeString ?? "*" }); const showAlias = siteResource.mode !== "cidr" && siteResource.mode !== "http"; const showDestination = !( siteResource.mode === "ssh" && siteResource.authDaemonMode === "native" ); const showCertificate = !!( siteResource.mode === "http" && siteResource.ssl && siteResource.domainId && siteResource.fullDomain && build != "oss" ); const numSections = 2 + (showDestination ? 1 : 0) + (showAlias ? 1 : 0) + (showCertificate ? 1 : 0) + (isPanel ? 1 : 0); const sections = ( {t("type")} {modeLabel[siteResource.mode]} {t("access")} {showDestination ? ( {t("editInternalResourceDialogDestination")} {destination || "-"} ) : null} {showAlias ? ( {t("editInternalResourceDialogAlias")} {siteResource.alias?.trim() ? siteResource.alias : "-"} ) : null} {showCertificate ? ( {t("certificateStatus", { defaultValue: "Certificate" })} ) : null} {isPanel ? ( {t("portRestrictions")} {!portRestrictions.hasNonDefaultPorts ? ( {t("resourceLauncherNoPortRestrictions")} ) : (
{portRestrictions.tcp.state !== "all" ? (
{t("resourceLauncherTcp")}:{" "} {portRestrictions.tcp.state === "blocked" ? t("blocked") : portRestrictions.tcp.ports}
) : null} {portRestrictions.udp.state !== "all" ? (
{t("resourceLauncherUdp")}:{" "} {portRestrictions.udp.state === "blocked" ? t("blocked") : portRestrictions.udp.ports}
) : null}
)}
) : null}
); if (isPanel) { return sections; } return ( {sections} ); } type SiteResourceInfoBoxProps = { variant?: "settings"; }; export default function SiteResourceInfoBox({ variant = "settings" }: SiteResourceInfoBoxProps) { const { siteResource } = useSiteResourceContext(); const access = formatSiteResourceAccess({ mode: siteResource.mode, destination: siteResource.destination, destinationPort: siteResource.destinationPort, scheme: siteResource.scheme, ssl: siteResource.ssl, fullDomain: siteResource.fullDomain ?? null, alias: siteResource.alias ?? null, aliasAddress: siteResource.aliasAddress ?? null }); return ( ); }