feat(security): persist unlock lockout across restarts; keep unlock errors visible
- The failed-unlock error message now stays on screen until the next attempt / mode switch / success, instead of fading after ~3s (the reason was often gone before it could be read). - The escalating failed-attempt lockout counter + expiry are now persisted (keyed to the active wallet file) and restored once per lock-screen session, so killing and relaunching the app can no longer reset the lockout curve — a brute-force window. A forward clock change is capped; the PIN/passphrase is never stored. The verification (walletpassphrase/decrypt) path is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1673,6 +1673,7 @@ void App::switchToWallet(const std::string& walletFile, bool stopDaemonConfirmed
|
||||
pin_vault_stale_ = false; // the out-of-date mark was the previous wallet's vault
|
||||
lock_attempts_ = 0;
|
||||
lock_lockout_timer_ = 0.0f;
|
||||
lock_state_restored_ = false; // re-restore persisted lockout for the newly-active wallet
|
||||
lock_error_msg_.clear();
|
||||
lock_error_timer_ = 0.0f;
|
||||
lock_unlock_in_progress_ = false;
|
||||
@@ -7031,6 +7032,7 @@ void App::pumpSeedMigration()
|
||||
seed_migration_dest_ = std::move(dest);
|
||||
seed_migration_temp_dir_ = std::move(tmp);
|
||||
seed_migration_backed_up_ = false;
|
||||
seed_migration_understood_ = false;
|
||||
seed_migration_step_ = SeedMigrationStep::ShowSeed;
|
||||
// Persist the pending migration so a later sweep/adopt step can find the new wallet.
|
||||
if (settings_) {
|
||||
|
||||
Reference in New Issue
Block a user