import { type ReactNode, useState } from "react"; import type { ResourceAuthorityScope } from "@opengeni/sdk"; import { CircleAlertIcon, LaptopIcon, MonitorIcon, ScreenShareIcon, ShieldAlertIcon, TerminalIcon, UsersIcon, } from "lucide-react"; import { cn } from "../lib/cn"; import { useOpenGeniText } from "../messages/runtime"; /** The machine identity surfaced to the approver, from the device-flow start. */ export type EnrollmentConsentMachine = { /** Human-friendly name (hostname by default). */ machineName: string; os: string; arch: string; /** The agent can offer a display (a real screen / Xvfb is available). */ canOfferDisplay: boolean; /** The agent requests screen control (computer-use). */ requestsScreenControl: boolean; }; /** The phase of the approve page (drives the rendered panel). */ export type EnrollmentConsentPhase = "review" | "approving" | "approved" | "denied" | "error"; export type EnrollmentConsentProps = { /** The short code the user typed / scanned (echoed back for confirmation). */ userCode: string; machine: EnrollmentConsentMachine; phase?: EnrollmentConsentPhase | undefined; /** Whether this caller may publish the machine to the whole organization. */ allowOrganizationScope?: boolean | undefined; /** Approve with the chosen screen-control consent and explicit access scope. */ onApprove?: ((allowScreenControl: boolean, scope: ResourceAuthorityScope) => void) | undefined; onDeny?: (() => void) | undefined; /** Error message when phase === "error". */ errorMessage?: string | undefined; className?: string | undefined; }; function Capability({ icon, title, body }: { icon: ReactNode; title: string; body: string }) { return (
  • {icon} {title} {body}
  • ); } /** * The user-facing APPROVE page for the device-flow enrollment: a LOUD, * un-minimised whole-machine consent. Approving grants the agent FULL access to * this machine — exec, files, terminal — and (when toggled) live screen control. * The danger framing is deliberate (§18 hardening: whole-machine = loud consent), * never buried. Renders review / approving / approved / denied / error phases. */ export function EnrollmentConsent({ userCode, machine, phase = "review", allowOrganizationScope = false, onApprove, onDeny, errorMessage, className, }: EnrollmentConsentProps) { const t = useOpenGeniText(); const [allowScreenControl, setAllowScreenControl] = useState(machine.requestsScreenControl); const [scope, setScope] = useState("user"); const busy = phase === "approving"; const scopeCopy = { user: { label: t("enrollmentConsent.personal"), body: t("enrollmentConsent.onlyYouCanUseThis"), }, workspace: { label: t("enrollmentConsent.workspace"), body: t("enrollmentConsent.everyoneWithAccessToThis"), }, organization: { label: t("enrollmentConsent.organization"), body: t("enrollmentConsent.membersOfThisOrganizationCan"), }, } satisfies Record; if (phase === "approved") { return ( ); } if (phase === "denied") { return ( ); } if (phase === "error") { return ( ); } return (

    {t("enrollmentConsent.giveTheAgentYourWhole")}

    {t("enrollmentConsent.approvingLetsTheOpengeniAgent")}{" "} {machine.machineName}{" "} {t("enrollmentConsent.withFullAccessThisIs")}

    {machine.machineName} {machine.os}/{machine.arch} · {t("enrollmentConsent.code")}{" "} {userCode}
      } title={t("enrollmentConsent.readWriteRunAnything")} body={t("enrollmentConsent.theAgentCanReadAnd")} /> {machine.canOfferDisplay ? ( } title={t("enrollmentConsent.seeYourScreen")} body={t("enrollmentConsent.theAgentCanCaptureThis")} /> ) : null} } title={t("enrollmentConsent.labelAccessWhileConnected", { label: scopeCopy[scope].label, })} body={t("enrollmentConsent.bodyDisconnectTheAgentTo", { body: scopeCopy[scope].body })} />
    {t("enrollmentConsent.whoCanUseThisMachine")} {(["user", "workspace", "organization"] as const).map((candidate) => { const disabled = candidate === "organization" && !allowOrganizationScope; return ( ); })}
    {machine.canOfferDisplay ? ( ) : (

    {t("enrollmentConsent.thisMachineHasNoDisplay")}

    )}
    ); } function ConsentResult({ tone, title, body, className, }: { tone: "ok" | "muted" | "danger"; title: string; body: string; className?: string | undefined; }) { const ring = tone === "ok" ? "border-og-status-running/30" : tone === "danger" ? "border-og-status-failed/30" : "border-og-border"; const iconClass = tone === "ok" ? "text-og-status-running" : tone === "danger" ? "text-og-status-failed" : "text-og-fg-subtle"; return (

    {title}

    {body}

    ); }