trackslash
VAULT-17 P2

Backup password status disappears when you revisit the Backups page

0
All issues

Description

After you set a backup password, the Backups page shows "Backup Password Set". Leave the Backups page and come back, and that row is gone, so it looks as though no password is set. The status should survive leaving the page, relaunching the app, and locking and unlocking.

Likely cause (confirm on a device first; the simulator may not enforce user presence the same way):

  • Right after saving, VaultDataModel.store(backupPassword:) sets backupPasswordStatus to .set directly.
  • Every later visit re-reads it with loadBackupPasswordStatus(), called from .task in BackupHomeView.
  • That reads the keychain item's attributes through SecureStorageImpl.attributes(key:), with interaction not allowed.
  • The password is stored with .userPresence, so on a device that read probably fails with errSecInteractionNotAllowed.
  • The status then drops to .unknown, and BackupPasswordStatusRow hides itself.

Possible fix:

  • When the password is stored, record a non-secret "password set" marker with its date, somewhere that can be read without authentication. Read the status from that marker. The password itself stays behind user presence.
  • Fill in the marker for passwords set before this change, e.g. whenever the password is loaded after authentication. Keep it in step wherever the password is removed.
  • Within a session, don't let a failed read turn a known .set back into .unknown.

The Backup Password sheet's "Current password set …" label uses the same status, so check it too. Add tests that cover coming back to the page after setting a password.

Sub-issues

0

Linked issues

0

GitHub

0

No branches or pull requests linked.

Comments

1
Bradley

Fixed in https://github.com/badbundle/vault-app/pull/610 (merged as 09adf477).

Cause: the simulator didn't reproduce the bug, even with Face ID enrolled, so the cause isn't confirmed. The fix no longer depends on reading the password item's attributes.

How the status is kept now:

  • When a password is set, a non-secret keychain record, backupPasswordMetadata (stored with storeSilent, so no Face ID), notes that it's set and when. The status is read from that record.
  • Older passwords: they get a record the next time the password is loaded after authentication, from Export, Auto-Backup or Restore. It has no date if the attributes can't be read.
  • No password: the record is removed when loading finds no password.
  • Failed reads: a failed read keeps the status that was already known instead of dropping to unknown.

Delete All Data: deleteVault() doesn't remove the backup password, so the record stays consistent with it.

Tests: new store and data-model tests use a fake keychain whose attribute read throws, as a device would. They cover revisiting the page, relaunching, backgrounding, changing the password, and passwords set before this change.