/**
 * Console session token storage and verification (#1780).
 *
 * Manages the file at `~/.dollhouse/run/console-token.auth.json` which
 * holds the Bearer tokens that authenticate requests to the web console.
 * The file is created on first leader election and persists across
 * restarts — tokens only rotate when explicitly requested.
 *
 * The `.auth` filename suffix keeps this state isolated from any legacy
 * no-authentication DollhouseMCP installation running on the same
 * machine. The port, lock file, and token file all share the same
 * isolation strategy — see `src/config/env.ts` for the port, and
 * `LeaderElection.ts` for the lock file.
 *
 * Schema is forward-compatible with multi-device, multi-tenant, and
 * scope-restricted tokens for Phase 2+. Phase 1 uses a single "console"
 * kind token and stubs the scope/boundary checks.
 *
 * File format (version 1):
 * ```json
 * {
 *   "version": 1,
 *   "tokens": [
 *     {
 *       "id": "018e1a2b-...",
 *       "name": "Kermit on mick-MacBook-Pro",
 *       "kind": "console",
 *       "token": "<64-hex>",
 *       "scopes": ["admin"],
 *       "elementBoundaries": null,
 *       "tenant": null,
 *       "platform": "local",
 *       "labels": {},
 *       "createdAt": "2026-04-04T20:00:00.000Z",
 *       "lastUsedAt": null,
 *       "createdVia": "initial-setup"
 *     }
 *   ],
 *   "totp": { "enrolled": false, "secret": null, "backupCodes": [] }
 * }
 * ```
 *
 * @since v2.1.0 — Issue #1780
 */
/**
 * Default path to the authenticated console's token file.
 *
 * The `.auth` suffix isolates this from any legacy no-authentication
 * DollhouseMCP installation that may also be running on the same
 * machine. Legacy installs did not write a token file at all; the
 * authenticated console writes `console-token.auth.json`. Combined with
 * the port and lock-file separation, this gives the two generations of
 * the console fully independent state trees under `~/.dollhouse/run/`.
 *
 * Callers can override via `DOLLHOUSE_CONSOLE_TOKEN_FILE` in the env.
 */
declare const DEFAULT_TOKEN_FILE: string;
/** Current token file schema version. */
declare const TOKEN_FILE_VERSION: 1;
/**
 * Element visibility boundary — Phase 3 enterprise feature.
 * Phase 1 always stores `null`; the field exists so the schema is stable.
 */
export interface ElementBoundary {
    allowCategories?: string[];
    denyCategories?: string[];
    allowTypes?: string[];
    denyTypes?: string[];
}
/**
 * A single token entry in the console token file.
 *
 * Enterprise-ready fields (`scopes`, `elementBoundaries`, `tenant`, `platform`,
 * `labels`) are present from Phase 1 but not enforced — the middleware treats
 * every valid token as admin-scoped, single-tenant, all-elements for now.
 * Phase 2+ flips enforcement on without requiring a schema migration.
 */
export interface ConsoleTokenEntry {
    /** Stable unique identifier for this token (UUID v4). */
    id: string;
    /** Human-readable name shown in the Security tab. */
    name: string;
    /** What kind of client this token is for. */
    kind: 'console' | 'device' | 'automation';
    /** The secret Bearer value. 64 hex chars (256 bits of entropy). */
    token: string;
    /** Scopes granted to this token. Phase 1 = always `["admin"]`. */
    scopes: string[];
    /** Element visibility restriction. Phase 1 = always `null`. */
    elementBoundaries: ElementBoundary | null;
    /** Tenant identifier for multi-tenant deployments. Phase 1 = always `null`. */
    tenant: string | null;
    /** Where this token is used. Phase 1 = always `"local"`. */
    platform: string;
    /** Opaque metadata for enterprise tooling. Phase 1 = always `{}`. */
    labels: Record<string, string>;
    /** ISO timestamp of token creation. */
    createdAt: string;
    /** ISO timestamp of most recent use, or null if never used. */
    lastUsedAt: string | null;
    /** How this token was created — "initial-setup", "pairing", "rotation", etc. */
    createdVia: string;
}
/**
 * TOTP enrollment state.
 *
 * Populated by Phase 2 (#1794). The `secret` field holds the base32-encoded
 * RFC 6238 secret in plaintext — the surrounding file is 0600, which matches
 * standard file-based TOTP storage practice (SSH keys, age identity files,
 * 1Password vault backups). Encrypting the secret at rest with an OS keychain
 * is a future enhancement.
 *
 * Backup codes are stored as **sha256 hex hashes**, never plaintext. The
 * plaintext codes are shown to the user exactly once at enrollment confirm
 * time. Each backup code is single-use: consuming one removes its hash from
 * this array.
 *
 * `enrolledAt` is optional for backward compatibility with Phase 1 files,
 * which were written with only `{enrolled, secret, backupCodes}`.
 */
export interface TotpState {
    enrolled: boolean;
    secret: string | null;
    backupCodes: string[];
    enrolledAt?: string | null;
}
/**
 * Public-safe view of TOTP state — never leaks secret material.
 * Returned from the status endpoint and from store methods that need to
 * report enrollment state to callers.
 */
export interface TotpStatus {
    enrolled: boolean;
    enrolledAt: string | null;
    backupCodesRemaining: number;
}
/**
 * Result of `beginTotpEnrollment` — the caller needs all of these to show a
 * QR code and manual-entry fallback in the UI. None of this is persisted;
 * the pending state only lives in-memory until confirmed.
 */
export interface TotpEnrollmentBegin {
    pendingId: string;
    /** Base32-encoded TOTP secret for manual entry (grouped display is caller's job). */
    secret: string;
    /** Full `otpauth://` URI for authenticator apps to import. */
    otpauthUri: string;
    /** Timestamp (ms since epoch) when this pending enrollment expires. */
    expiresAt: number;
}
/**
 * Result of `confirmTotpEnrollment` — the plaintext backup codes are
 * returned to the caller exactly once, at this point, and then only their
 * hashes are retained. The caller must display them to the user immediately
 * and never log them.
 */
export interface TotpEnrollmentConfirm {
    backupCodes: string[];
    enrolledAt: string;
}
/**
 * Result of `rotatePrimary` — returned to the caller so they can update
 * the browser token in-place and display the grace-window deadline.
 */
export interface RotationResult {
    /** The new 64-hex token value. The caller must treat this as a secret. */
    token: string;
    /** ISO timestamp of the rotation. */
    rotatedAt: string;
    /** ms-since-epoch deadline after which the old token stops verifying. */
    graceUntil: number;
}
/**
 * Typed error for TOTP store operations. Carries a machine-readable
 * `code` field so the HTTP layer can map failures to consistent response
 * codes without parsing free-form error messages. Callers (CLI, UI) can
 * branch on `code` instead of the human-readable `message`.
 */
export declare class TotpError extends Error {
    readonly code: TotpErrorCode;
    constructor(message: string, code: TotpErrorCode);
}
/** Discriminated set of TOTP failure reasons surfaced by the store. */
export type TotpErrorCode = 'ALREADY_ENROLLED' | 'NOT_ENROLLED' | 'PENDING_NOT_FOUND' | 'INVALID_TOTP_CODE' | 'STORE_NOT_INITIALIZED' | 'TOO_MANY_PENDING' | 'TOTP_REQUIRED';
/**
 * The full on-disk token file structure.
 */
export interface ConsoleTokenFile {
    version: typeof TOKEN_FILE_VERSION;
    tokens: ConsoleTokenEntry[];
    totp: TotpState;
}
/**
 * A safe-to-log view of a token entry — the secret `token` field is
 * replaced with a masked preview so it never appears in logs or API responses.
 */
export interface MaskedTokenEntry extends Omit<ConsoleTokenEntry, 'token'> {
    tokenPreview: string;
}
/**
 * Stateful store that owns the console token file and verifies presented tokens.
 *
 * Designed to live on the leader process. Followers should not construct this —
 * they read the file directly via `readTokenFileRaw()` for their own HTTP calls.
 */
export declare class ConsoleTokenStore {
    private readonly filePath;
    private data;
    /**
     * Pre-converted Buffer cache keyed by entry id. Populated whenever `this.data`
     * is assigned (load, create, future rotation). Verify() reuses the stored
     * buffers so the hot path doesn't re-allocate per-token on every request.
     * Negligible win with 1 token today; meaningful with Phase 2 multi-token
     * lookups. Not serialized — buffers are never written to disk.
     */
    private readonly tokenBuffers;
    /**
     * In-memory pending TOTP enrollments, keyed by opaque pendingId. Nothing
     * lives on disk until confirmTotpEnrollment() succeeds, which limits the
     * window in which a half-completed enrollment leaks a secret via file read.
     * Entries expire after TOTP_PENDING_TTL_MS (#1794).
     */
    private readonly pendingEnrollments;
    /**
     * In-memory grace buffer for recently-rotated tokens (#1795). After a
     * rotation, the old token value is stashed here with a per-rotation expiry
     * so in-flight requests that were sent before the rotation response arrived
     * still authenticate. Entries are per-rotation (concurrent rotations each
     * get their own grace slot) and never persisted to disk.
     */
    private readonly graceEntries;
    constructor(filePath?: string);
    /**
     * Rebuild the token buffer cache after a data load, create, or mutation.
     * Keeps the hot verify() path allocation-free for the stored side.
     */
    private rebuildTokenBuffers;
    /**
     * Read the existing token file, or create a new one with a single initial
     * token if none exists. Idempotent — safe to call on every leader election.
     *
     * @param puppetName - A puppet name picked by the caller (e.g. from SessionNames)
     *                     used to build the default display name on first run.
     * @returns The primary (first) token entry — convenient for server startup
     *          to inject into HTML and stamp on followers.
     */
    ensureInitialized(puppetName: string): Promise<ConsoleTokenEntry>;
    /**
     * Verify a presented Bearer token against the stored entries.
     * Uses timing-safe comparison to prevent side-channel attacks.
     *
     * Updates `lastUsedAt` on the matched entry (in memory only; disk write
     * is debounced to avoid disk thrash on every request — Phase 2 feature).
     *
     * @returns The matching entry, or null if no match.
     */
    verify(presented: string): ConsoleTokenEntry | null;
    /**
     * Get the primary token value for injection into HTML or forwarder config.
     * Returns the first entry's token string, or null if uninitialized.
     */
    getPrimaryTokenValue(): string | null;
    /**
     * Return all tokens with the secret value masked — safe to serialize for
     * the Security tab UI or `GET /api/console/token/info` responses.
     */
    listMasked(): MaskedTokenEntry[];
    /**
     * Get the path to the token file on disk.
     */
    getFilePath(): string;
    /**
     * Returns a safe-to-serialize view of TOTP enrollment state. Never leaks
     * the secret or any backup code material.
     */
    getTotpStatus(): TotpStatus;
    /** Convenience: true if the user has a confirmed TOTP secret. */
    isTotpEnrolled(): boolean;
    /**
     * Begin a TOTP enrollment. Generates a fresh secret, holds it in the
     * in-memory pending map, and returns the data the UI needs to render a
     * QR code and manual-entry fallback. Nothing is persisted until
     * `confirmTotpEnrollment` succeeds.
     *
     * Callers may call this multiple times; each call produces a new pendingId
     * and secret. Old pending entries expire after TOTP_PENDING_TTL_MS.
     *
     * @throws Error if TOTP is already enrolled — callers must disable first.
     */
    beginTotpEnrollment(label?: string): TotpEnrollmentBegin;
    /**
     * Confirm a pending TOTP enrollment. Verifies the code against the pending
     * secret; on success, generates 10 plaintext backup codes, hashes them for
     * storage, and persists the enrollment. Returns the plaintext backup codes
     * exactly once — the caller is responsible for showing them to the user
     * and then discarding them.
     *
     * Wrong codes do NOT consume or invalidate the pending enrollment — the
     * user can retry until it expires. This matches user expectations for
     * "oops, typed the wrong code" and limits the damage from a fat-fingered
     * first attempt.
     *
     * @throws Error if pendingId is unknown, expired, or code invalid.
     */
    confirmTotpEnrollment(pendingId: string, code: string): Promise<TotpEnrollmentConfirm>;
    /**
     * Verify a user-presented code. Accepts either a live TOTP code or a
     * single-use backup code. On successful backup-code match, the consumed
     * code's hash is removed from storage and the file is re-written.
     *
     * Returns a discriminated result so the caller can distinguish "consumed
     * a backup code" (which the UI should surface with a warning about
     * remaining count) from "valid TOTP code" (normal case). Returns
     * `{ ok: false }` on any failure — the caller should not retry within
     * the same request lifecycle.
     */
    verifyTotp(code: string): Promise<{
        ok: true;
        method: 'totp' | 'backup';
        backupCodesRemaining: number;
    } | {
        ok: false;
    }>;
    /**
     * Disable TOTP. Requires a valid code (TOTP or backup) as confirmation so
     * an attacker who momentarily has access to a live session can't silently
     * strip the second factor.
     *
     * @throws Error if not enrolled or code invalid.
     */
    disableTotp(code: string): Promise<void>;
    /** Remove any pending enrollments whose TTL has passed. */
    private sweepExpiredEnrollments;
    /**
     * Rotate the primary console token. Requires TOTP confirmation (Pattern B).
     *
     * Flow:
     * 1. Verify the confirmation code via `verifyTotp()` (live TOTP or backup code).
     * 2. Stash the old token value in the in-memory grace buffer so in-flight
     *    requests from the rotating tab (and any other local process that read
     *    the file before the rotation) still authenticate for ROTATION_GRACE_MS.
     * 3. Generate a new 32-byte token, mutate the primary entry in place, write
     *    the file atomically, and rebuild the buffer cache.
     * 4. Return the new token inline so the caller can update `DollhouseAuth.token`
     *    without a page reload.
     *
     * Pattern A (OS dialog fallback for users without TOTP) is deferred — the
     * caller should gate the UI so the rotate action is only available when
     * TOTP is enrolled.
     *
     * @throws TotpError STORE_NOT_INITIALIZED — store never loaded
     * @throws TotpError TOTP_REQUIRED — TOTP not enrolled, rotation requires second-factor confirmation
     * @throws TotpError INVALID_TOTP_CODE — wrong code
     */
    rotatePrimary(confirmationCode: string): Promise<RotationResult>;
    /** Remove expired grace entries so they stop matching in verify(). */
    private sweepExpiredGraceEntries;
    /**
     * Read the token file and distinguish missing from corrupt.
     *
     * Returning a tagged union lets `ensureInitialized()` back up corrupt files
     * before overwriting them — users who hand-edited their tokens with custom
     * names or labels deserve a recovery path instead of a silent destroy.
     */
    private readWithStatus;
    /**
     * Copy the current (presumed corrupt) token file to a timestamped backup
     * alongside it so the user can recover hand-edited data after an accidental
     * syntax error. Best-effort — failure to back up does not block creating
     * a fresh file, since the primary goal is keeping the console usable.
     */
    private backupCorruptFile;
    /**
     * Atomically write the token file with owner-only permissions.
     * Uses temp+rename to avoid partial writes on crash.
     *
     * On Windows, `chmod(0o600)` is effectively a no-op because the file
     * system uses ACLs instead of POSIX modes. We log a one-time warning so
     * users on Windows know the token file does not have OS-enforced access
     * control and can decide whether to use additional tooling (icacls, NTFS
     * permissions, or a different storage location).
     */
    private write;
    /** One-shot flag so the Windows permissions warning is logged at most once. */
    private windowsWarningLogged;
    private warnIfWindowsPermissions;
}
/**
 * Read the raw token file from disk without constructing a store.
 * Intended for follower processes that need the primary token to attach
 * to their ingest POSTs. Returns null if the file does not exist or is invalid.
 *
 * @param filePath - Optional override for the token file location
 */
export declare function readTokenFileRaw(filePath?: string): Promise<ConsoleTokenFile | null>;
/**
 * Get the primary token value from the token file on disk.
 * Convenience helper for followers and external consumers.
 */
export declare function getPrimaryTokenFromFile(filePath?: string): Promise<string | null>;
/** Export the default file path so callers can reference it in logs/docs. */
export { DEFAULT_TOKEN_FILE };
//# sourceMappingURL=consoleToken.d.ts.map