import { type Settings } from "@opengeni/config"; import { type DeviceEnrollmentLookupResponse, type DeviceEnrollmentPollResponse, type DeviceEnrollmentStartResponse, type EnrollTokenExchangeResponse, type MintEnrollTokenResponse } from "@opengeni/contracts"; import { type Database, type DeviceEnrollmentRequestRecord, type EnrollmentOs } from "@opengeni/db"; export declare const DEVICE_CODE_TTL_SECONDS = 600; export declare const DEVICE_POLL_INTERVAL_SECONDS = 5; export declare const ENROLLMENT_BEARER_TTL_SECONDS: number; export declare const RELAY_TOKEN_TTL_SECONDS: number; export declare const ENROLL_TOKEN_TTL_SECONDS = 3600; export type EnrollmentServices = { db: Database; settings: Settings; }; /** A workspace-scoped flow START context (the route resolves the workspace the * agent's flow binds to from the deployment edge / a workspace hint). */ export type DeviceStartInput = { accountId: string; workspaceId: string; publicKey: string; os: EnrollmentOs; arch: string; machineName?: string | null; canOfferDisplay: boolean; requestsScreenControl: boolean; verificationOrigin: string; }; /** * START a device-flow: persist a short-TTL single-use pending request + return the * DeviceAuthStart. Retries the user_code mint on the (astronomically rare) partial- * unique collision among live pending rows. */ export declare function startDeviceEnrollment(services: EnrollmentServices, input: DeviceStartInput): Promise; /** APPROVE a flow by user_code (the LOUD consent step). Returns the resulting * enrollment + sandbox ids, or null when no LIVE pending request matches the code * in this workspace (an unknown/expired/already-terminal code). */ export declare function approveDeviceEnrollment(services: EnrollmentServices, input: { accountId: string; workspaceId: string; scope?: "organization" | "workspace" | "user"; allowOrganization?: boolean; userCode: string; allowScreenControl: boolean; approvedBySubjectId: string; approvedBySubjectLabel?: string | null; }): Promise<{ enrollmentId: string; sandboxId: string; allowScreenControl: boolean; } | null>; /** LOOK UP a pending flow by user_code GLOBALLY (the click-Grant approve page; * design 11 §B.1). Returns the resolved pending record (carrying its workspaceId) * or null when no live pending row matches the code. The ROUTE authorizes the * caller against the resolved workspaceId (enrollments:read) BEFORE exposing * anything — a failed grant OR a null here both surface as 404 so cross-workspace * existence is never revealed. This does NOT consume the request. */ export declare function lookupDeviceEnrollment(services: EnrollmentServices, input: { userCode: string; }): Promise; /** Project a resolved pending record to the presentational lookup response (no * secrets, no device_code) the approve screen (EnrollmentConsent) renders. */ export declare function toLookupResponse(record: DeviceEnrollmentRequestRecord): DeviceEnrollmentLookupResponse; /** DENY a flow by user_code (the explicit "no" at the approve page; design 11 * §B.2). Workspace-scoped (the route asserts the grant). Returns whether a pending * row was flipped to denied (false for an unknown / already-terminal code). */ export declare function denyDeviceEnrollment(services: EnrollmentServices, input: { accountId: string; workspaceId: string; userCode: string; }): Promise<{ denied: boolean; }>; /** MINT a headless enroll token (design 11 §A2.2). Signs an `oget_` token bound to * the workspace + account + the screen-control consent, with a 1h TTL. Returns * null when the credential plane is disabled (no signing secret) so the route can * mirror poll's "disabled" handling. The token value is NEVER logged. */ export declare function mintEnrollToken(services: EnrollmentServices, input: { accountId: string; workspaceId: string; allowScreenControl: boolean; }): Promise; /** Distinguishes the two exchange failure modes for the route. */ export type ExchangeEnrollTokenResult = { ok: true; credentials: EnrollTokenExchangeResponse["credentials"]; } | { ok: false; reason: "disabled"; } | { ok: false; reason: "invalid"; }; /** EXCHANGE a headless enroll token (design 11 §A2.3) — the UNAUTHENTICATED path * where the token IS the auth. Verifies the `oget_` token, then performs the SAME * finalize as approve (upsert enrollment + ensure selfhosted sandbox, * consentedWholeMachine=true, consentedScreenControl=token.allowScreenControl) and * builds the IDENTICAL EnrollmentCredentials the poll authorized branch returns. * Returns reason "disabled" when no signing secret (mirror poll), "invalid" when * the token fails verification (the route 401s). */ export declare function exchangeEnrollToken(services: EnrollmentServices, input: { token: string; publicKey: string; os: EnrollmentOs; arch: string; machineName?: string | null; canOfferDisplay: boolean; }): Promise; /** * POLL a flow by device_code. Resolves the state machine: * - unknown code → "expired" (do not leak existence; an unknown code * behaves like an expired one to the agent). * - pending + within TTL → "pending". * - pending + past TTL → "expired". * - denied → "denied". * - approved | consumed → "authorized" + the EnrollmentCredentials (the * approved row is flipped to consumed; a legitimate * re-poll of a consumed row still returns the creds). * When the credential plane is disabled (no resolvable signing secret), an * otherwise-authorized poll returns "disabled" so the agent surfaces a clear reason * rather than half-enrolling. */ export declare function pollDeviceEnrollment(services: EnrollmentServices, input: { deviceCode: string; }): Promise;