/** * Auto-approve token store + macOS password verification. * * Replaces the osascript dialog (CSO #4) with a phone-supplied macOS password. * The dialog required physical presence at the laptop — fine for desktop use, * but defeats the entire premise of remote phone control. Now the phone * proves knowledge of the macOS user password instead, daemon verifies via * `dscl . -authonly`, and mints a per-phone token so subsequent auto-approve * sessions need no further prompting. * * Wire flow: * * First time (no token cached on phone): * phone → daemon : { type: 'session-open', auto: true, * phoneId, sudoPassword: '' } * daemon : dscl-verify password * mint random 32-byte token * store sha256(token) keyed by phoneId * daemon → phone : { type: 'auto-approve-granted', phoneId, token } * * Subsequent: * phone → daemon : { type: 'session-open', auto: true, * phoneId, approveToken: '<cached>' } * daemon : sha256(token) → lookup phoneId → match * * Threat model: * - Stolen unlocked phone with the app open: cannot auto-approve unless the * attacker also knows the macOS password. Worst case they get a non-auto * session, which is gated by per-command denylist + permission prompts. * - Lost phone, attacker reads cached token: equivalent to stealing the * phone_secret. Mitigation: revoke the phone via `loopsy phone revoke`, * which also wipes the auto-approve entry. * - Replayed password from network: TLS to relay, relay is yours, so a * well-positioned attacker would need to break TLS or compromise the CF * account. End-to-end encryption is a v2 nice-to-have. */ /** * Verify a macOS user password without spawning a UI prompt. Uses Apple's * `dscl` Open Directory CLI in -authonly mode — same auth backend as `sudo`. * * Returns true if the password is valid for the current OS user. */ export declare function verifyMacPassword(password: string): Promise<boolean>; /** * Mint a fresh approval token for a phone after the phone proved knowledge * of the macOS password. Stores sha256(token) on disk and returns the raw * token to be sent to the phone exactly once. */ export declare function grantAutoApprove(phoneId: string, label?: string): Promise<string>; /** * Constant-time check of an inbound approval token against the stored hash * for a given phone. Returns true if the phone has previously been granted * auto-approve and the supplied token matches. */ export declare function checkAutoApprove(phoneId: string, token: string): Promise<boolean>; /** * Revoke an approval — called when the laptop owner runs `loopsy phone * revoke <id>` so a forgotten phone loses both its phone_secret AND its * auto-approve token in one step. */ export declare function revokeAutoApprove(phoneId: string): Promise<void>; //# sourceMappingURL=auto-approve.d.ts.map