/**
 * Per-account encrypted token store for Outlook OAuth credentials.
 *
 * Adapted from nsakki55/outlook-mcp@e49d8e68ac8d69db653c25803127dc3b98626cda
 * (MIT). Adaptations:
 *   - Per-account paths under {ACCOUNTS_DIR}/{accountId}/secrets/outlook/
 *   - keytar fallback removed (Pi runs headless, no Secret Service)
 *   - node-persist removed; single JSON blob written atomically (temp + rename)
 *
 *   tokens.enc      AES-256-CBC ciphertext "<iv-hex>:<cipher-hex>" of the JSON blob
 *   .key            32 random bytes, base64, mode 0600 (the AES key)
 *
 * The JSON blob shape is {accessToken, refreshToken, accessTokenExpiry,
 * refreshTokenExpiry, lastRefresh, graphUserId, scopes}.
 *
 * Rationale: per CLAUDE.md doctrine, account scope is absolute. Each account
 * holds its own AES key — compromising account A's keyfile cannot decrypt
 * account B's tokens.
 */
export interface TokenBlob {
    accessToken: string;
    refreshToken: string | null;
    accessTokenExpiry: number;
    refreshTokenExpiry: number;
    lastRefresh: number;
    graphUserId: string | null;
    scopes: string[];
}
export declare class TokenStore {
    readonly accountId: string;
    private cachedBlob;
    private encryptionKey;
    private readonly secretsDir;
    private readonly tokensPath;
    private readonly keyPath;
    constructor(accountId: string, accountsDir: string);
    /** Load (or create) the AES key. Idempotent and TOCTOU-safe via wx flag. */
    private loadKey;
    private encrypt;
    private decrypt;
    /** Atomic write — temp + rename. Either old or new tokens, never partial. */
    private writeBlob;
    /** Read and decrypt the blob from disk; cached after first read. */
    read(): TokenBlob | null;
    store(accessToken: string, refreshToken: string | null, expiresInSeconds: number, extras?: {
        graphUserId?: string | null;
        scopes?: string[];
    }): TokenBlob;
    private tryReadSilent;
    /**
     * Whether the access token is within the refresh threshold of expiry. Caller
     * should refresh before next Graph call when this is true.
     */
    needsRefresh(): boolean;
    hasTokens(): boolean;
    refreshTokenExpired(): boolean;
    clear(): void;
}
/** Exported for tests + the mailbox-info tool. */
export declare const refreshThresholdMs: number;
//# sourceMappingURL=token-store.d.ts.map