feat(02): PIN security and reauth - #44
Open
tpaulshippy wants to merge 7 commits into
Open
Conversation
Implements the backend half of docs/roadmap/02-pin-security-and-reauth.md: - UserAccount: pin_hash + lockout fields replace plaintext integer pin (0039 adds fields, 0040 hashes legacy pins, 0041 drops the column). - GET /api/user now returns hasPin/cost/timezone and never exposes the PIN or its hash. - POST /api/user validates 4-8 digit PINs; changes require currentPin plus a valid X-Parent-Reauth session; first set needs neither. - New POST /api/auth/reauthenticate verifies the PIN and returns a 15-minute signed parent capability token; wrong attempts report remainingAttempts, with 423 lockout after 5 failures for 15 minutes. - Teen-delegated tokens are always denied reauthentication (403). - Bot/profile writes and account deletion require the reauth header; reads stay open for kid paths. - seed_e2e_pin_reauth management command for Detox e2e runs. Tests: bots/tests/test_pin_reauth.py (hash-at-rest, redaction, reauth success/failure/lockout/unlock, teen denial, mutation gating, legacy-pin data migration). Refs: docs/roadmap/02-pin-security-and-reauth.md
Implements the frontend half of docs/roadmap/02-pin-security-and-reauth.md: - pinStorage.ts: no more plaintext @user_pin (legacy key is scrubbed on login); caches only the hasPin flag plus an in-memory parent session token/expiry from POST /auth/reauthenticate. - apiClient.ts: automatically sends X-Parent-Reauth on unsafe methods when a parent session exists. - PinWrapper.tsx: numeric keypad calls the real reauthenticate endpoint, surfaces remaining attempts and lockout errors, and re-locks via an AppState foreground check when the session expires. - setPin.tsx: current/new/confirm fields, 4-8 digit validation, error surfacing; change requires current PIN per API contract. - settings.tsx: blocking "Set a PIN to protect parent controls" card replaces the open menu when hasPin is false; PinWrapper now gates the whole screen including the usage bar; uses new cost/hasPin fields. - login.tsx: removes the client-side cached-PIN gate and dead attemptReauthWithPin token flow; refreshes the hasPin flag instead. - testIDs added for all new interactive elements (+ drawer navigation). - Fixes pre-existing typecheck errors in mocks/tests so tsc is green. Tests: pinStorage, account API and PinWrapper suites added. Refs: docs/roadmap/02-pin-security-and-reauth.md
Adds front/e2e/02-pin-reauth.e2e.js modeled on chatImageUpload.e2e.js: drives the keypad gate, remaining-attempts messaging, successful unlock, Set Pin confirm validation, and server-side lockout against a seeded backend (seed_e2e_pin_reauth; header comment documents seeding, env, and the run command). Adds a testID to the shared header back button so the flow can reach the drawer. Refs: docs/roadmap/02-pin-security-and-reauth.md
- Backend: remove unused PIN_LOCKOUT_MINUTES import, fix I001 ordering - Frontend: add jest globals to eslint config
tpaulshippy
pushed a commit
that referenced
this pull request
Aug 26, 2026
Screenshot now shows the Set PIN screen with New PIN and Confirm fields.
Screenshot now shows the Set PIN screen with New PIN and Confirm fields.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap 02: PIN Security & Reauth
Implements #54.
What changed
POST /api/auth/reauthenticatereturning time-limited parent session token,ParentReauthRequiredpermission on mutationsX-Parent-Reauthheader on unsafe methods, lockout display, PIN set/change flowsEvidence
https://github.com/tpaulshippy/bots/raw/feature/roadmap-02-pin-reauth/evidence/pr44-pin-reauth.mp4