Done in https://github.com/badbundle/vault-app/pull/643 (merged as d0f7e169).
Lock screen:
- After Face ID, Touch ID or the passcode, and only if a password is set, a secure App Lock Password field appears. It uses
.secretTextInput(.verbatim)and has a VoiceOver label. - A wrong password shakes the field, or fades it with Reduce Motion, and plays the error haptic.
- During a delay, the field is disabled and shows "Try again in N minutes". It never shows an attempt count.
- Real and duress passwords get identical feedback (C2).
Settings:
- An App Lock Password row appears under App Lock, only while App Lock is on. It opens a sheet to set, change or turn off the password.
- Setting it needs device authentication first. It then warns that a forgotten password can't be reset, even with Face ID or the passcode (C4), and that the way out is erasing the vault and restoring a backup. It shows the last backup date.
- Rules: at least 8 characters, not only numbers, plus a confirmation. The screen explains why: the file can be guessed offline.
- Changing or turning off the password needs the current one, and wrong attempts count toward the delay.
- The App Lock toggle is disabled while a password is set.
- There's room for one more action, VAULT-23's.
Protocol: AppLockPasswordService (@MainActor, in VaultFeed), with FakeAppLockPasswordService for previews and tests. VAULT-46's unlock service maps onto it one to one.
Gating: VaultRoot passes passwordService: nil, so none of this is reachable in a release until the storage side is wired in after VAULT-47/48.
Shared change: the lock screen's overlay window now becomes key while the password field shows, so the keyboard appears straight away.
Tests:
- View model and service tests against the fake.
- Light and dark snapshots of password entry (normal, wrong, delayed), setup, change and turn off.
- The full flow was driven in the simulator against the fake.