feat(settings): redesign the PIN setup/change/remove modals onto reference design

Migrate the three PIN dialogs in App::renderPinDialogs (Set PIN / Change PIN /
Remove PIN) onto the settings-modal reference design — presentation-only, plus a
deliberate secret-hygiene addition:

- struct-form BeginOverlayDialog(OverlayDialogSpec{BlurFloat, cardWidth 420/420/400,
  idSuffix pinsetup/pinchange/pinremove}) replacing the legacy positional overload
- drop each dialog's redundant post-description Separator
- every rendered-chrome string -> TR(): titles/buttons reuse settings_set_pin /
  settings_change_pin / settings_remove_pin, the Set-PIN confirm reuses
  wiz_pin_confirm; 7 new pin_* keys added to the English source + all 8
  res/lang/*.json additively; ImGui::Text -> TextUnformatted for labels
- HARDENING: wipe the passphrase/PIN input buffers on BlurFloat dismiss
  (X/Esc/outside-click) for all three dialogs. Set PIN's wallet-passphrase buffer
  (pin_passphrase_buf_) was previously left resident on dismiss; it is now zeroed.

The vault/RPC path is byte-for-byte unchanged: the submit-time memsets, the
walletpassphrase/walletlock RPCs, vault_->store/changePin/retrieve/removeVault,
SecureVault::secureZero, and setPinEnabled/save are untouched. The pin_status_ and
toast strings inside the worker callbacks are left in English (a separate
service-layer i18n pass), to avoid editing the secret path.

Verified: build + ctest + hygiene clean; i18n complete in 8 langs with no format
specifiers; a 3-lens adversarial review (secret-hygiene / presentation-only /
ui-i18n) returned zero findings, with the presentation lens proving the vault path
diffs byte-for-byte identical against HEAD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-14 13:29:02 -05:00
parent 5bd07b0505
commit 46f7da4fac
10 changed files with 112 additions and 30 deletions

View File

@@ -874,7 +874,14 @@
"peers_upper": "PEERS",
"peers_version": "Version",
"pending": "Ausstehend",
"pin_change_desc": "Ändern Sie Ihre Entsperr-PIN. Sie benötigen Ihre aktuelle PIN und eine neue PIN.",
"pin_confirm_new_label": "Neue PIN bestätigen:",
"pin_current_label": "Aktuelle PIN:",
"pin_new_label": "Neue PIN (4-8 Ziffern):",
"pin_not_set": "PIN nicht gesetzt. Verwenden Sie das Passwort zum Entsperren.",
"pin_remove_desc": "Geben Sie Ihre aktuelle PIN ein, um das Entfernen zu bestätigen. Sie benötigen dann Ihre vollständige Passphrase zum Entsperren.",
"pin_setup_desc": "Legen Sie eine 4-8-stellige PIN für die schnelle Wallet-Entsperrung fest. Ihre Wallet-Passphrase wird mit dieser PIN verschlüsselt und lokal gespeichert.",
"pin_wallet_passphrase": "Wallet-Passphrase:",
"ping": "Ping",
"portfolio_add_entry": "Eintrag hinzufügen",
"portfolio_add_to": "Zum Portfolio hinzufügen",

View File

@@ -874,7 +874,14 @@
"peers_upper": "NODOS",
"peers_version": "Versión",
"pending": "Pendiente",
"pin_change_desc": "Cambia tu PIN de desbloqueo. Necesitas tu PIN actual y un nuevo PIN.",
"pin_confirm_new_label": "Confirmar nuevo PIN:",
"pin_current_label": "PIN actual:",
"pin_new_label": "Nuevo PIN (4-8 dígitos):",
"pin_not_set": "PIN no configurado. Use la contraseña para desbloquear.",
"pin_remove_desc": "Introduce tu PIN actual para confirmar la eliminación. Necesitarás tu frase de contraseña completa para desbloquear.",
"pin_setup_desc": "Establece un PIN de 4-8 dígitos para desbloquear el monedero rápidamente. Tu frase de contraseña se cifrará con este PIN y se almacenará localmente.",
"pin_wallet_passphrase": "Frase de contraseña del monedero:",
"ping": "Ping",
"portfolio_add_entry": "Añadir entrada",
"portfolio_add_to": "Agregar a la cartera de inversiones",

View File

@@ -874,7 +874,14 @@
"peers_upper": "PAIRS",
"peers_version": "Version",
"pending": "En attente",
"pin_change_desc": "Modifiez votre code PIN de déverrouillage. Vous avez besoin de votre code PIN actuel et d'un nouveau code PIN.",
"pin_confirm_new_label": "Confirmer le nouveau code PIN :",
"pin_current_label": "Code PIN actuel :",
"pin_new_label": "Nouveau code PIN (4 à 8 chiffres) :",
"pin_not_set": "PIN non défini. Utilisez le mot de passe pour déverrouiller.",
"pin_remove_desc": "Saisissez votre code PIN actuel pour confirmer la suppression. Vous devrez utiliser votre phrase secrète complète pour déverrouiller.",
"pin_setup_desc": "Définissez un code PIN de 4 à 8 chiffres pour déverrouiller rapidement votre portefeuille. Votre phrase secrète sera chiffrée avec ce code PIN et stockée localement.",
"pin_wallet_passphrase": "Phrase secrète du portefeuille :",
"ping": "Ping",
"portfolio_add_entry": "Ajouter une entrée",
"portfolio_add_to": "Ajouter au portefeuille",

View File

@@ -874,7 +874,14 @@
"peers_upper": "ピア",
"peers_version": "バージョン",
"pending": "保留中",
"pin_change_desc": "ロック解除PINを変更します。現在のPINと新しいPINが必要です。",
"pin_confirm_new_label": "新しいPINの確認:",
"pin_current_label": "現在のPIN:",
"pin_new_label": "新しいPIN4〜8桁:",
"pin_not_set": "PINが設定されていません。パスフレーズで解除してください。",
"pin_remove_desc": "削除を確認するには現在のPINを入力してください。ロック解除には完全なパスフレーズが必要になります。",
"pin_setup_desc": "ウォレットをすばやくロック解除するための4〜8桁のPINを設定します。ウォレットのパスフレーズはこのPINで暗号化され、ローカルに保存されます。",
"pin_wallet_passphrase": "ウォレットのパスフレーズ:",
"ping": "Ping",
"portfolio_add_entry": "エントリを追加",
"portfolio_add_to": "ポートフォリオに追加",

View File

@@ -874,7 +874,14 @@
"peers_upper": "피어",
"peers_version": "버전",
"pending": "대기 중",
"pin_change_desc": "잠금 해제 PIN을 변경합니다. 현재 PIN과 새 PIN이 필요합니다.",
"pin_confirm_new_label": "새 PIN 확인:",
"pin_current_label": "현재 PIN:",
"pin_new_label": "새 PIN(4~8자리):",
"pin_not_set": "PIN이 설정되지 않았습니다. 암호를 사용하여 잠금 해제하세요.",
"pin_remove_desc": "삭제를 확인하려면 현재 PIN을 입력하세요. 잠금 해제에는 전체 암호가 필요합니다.",
"pin_setup_desc": "지갑을 빠르게 잠금 해제할 4~8자리 PIN을 설정하세요. 지갑 암호가 이 PIN으로 암호화되어 로컬에 저장됩니다.",
"pin_wallet_passphrase": "지갑 암호:",
"ping": "Ping",
"portfolio_add_entry": "항목 추가",
"portfolio_add_to": "포트폴리오에 추가",

View File

@@ -874,7 +874,14 @@
"peers_upper": "PARES",
"peers_version": "Versão",
"pending": "Pendente",
"pin_change_desc": "Altere seu PIN de desbloqueio. Você precisa do seu PIN atual e de um novo PIN.",
"pin_confirm_new_label": "Confirmar novo PIN:",
"pin_current_label": "PIN atual:",
"pin_new_label": "Novo PIN (4 a 8 dígitos):",
"pin_not_set": "PIN não definido. Use a senha para desbloquear.",
"pin_remove_desc": "Digite seu PIN atual para confirmar a remoção. Você precisará usar sua senha completa para desbloquear.",
"pin_setup_desc": "Defina um PIN de 4 a 8 dígitos para desbloquear a carteira rapidamente. Sua senha da carteira será criptografada com este PIN e armazenada localmente.",
"pin_wallet_passphrase": "Senha da carteira:",
"ping": "Ping",
"portfolio_add_entry": "Adicionar entrada",
"portfolio_add_to": "Adicionar ao portfólio",

View File

@@ -874,7 +874,14 @@
"peers_upper": "УЗЛЫ",
"peers_version": "Версия",
"pending": "Ожидание",
"pin_change_desc": "Измените PIN-код разблокировки. Вам понадобится текущий PIN-код и новый PIN-код.",
"pin_confirm_new_label": "Подтвердите новый PIN-код:",
"pin_current_label": "Текущий PIN-код:",
"pin_new_label": "Новый PIN-код (48 цифр):",
"pin_not_set": "PIN не установлен. Используйте пароль для разблокировки.",
"pin_remove_desc": "Введите текущий PIN-код для подтверждения удаления. Для разблокировки вам понадобится полный пароль.",
"pin_setup_desc": "Установите PIN-код из 48 цифр для быстрой разблокировки кошелька. Пароль вашего кошелька будет зашифрован этим PIN-кодом и сохранён локально.",
"pin_wallet_passphrase": "Пароль кошелька:",
"ping": "Пинг",
"portfolio_add_entry": "Добавить запись",
"portfolio_add_to": "Добавить в портфель",

View File

@@ -874,7 +874,14 @@
"peers_upper": "节点",
"peers_version": "版本",
"pending": "待处理",
"pin_change_desc": "更改您的解锁 PIN 码。您需要当前 PIN 码和新 PIN 码。",
"pin_confirm_new_label": "确认新 PIN 码:",
"pin_current_label": "当前 PIN 码:",
"pin_new_label": "新 PIN 码4-8 位):",
"pin_not_set": "未设置 PIN。使用密码解锁。",
"pin_remove_desc": "输入当前 PIN 码以确认移除。解锁时您需要使用完整的密码短语。",
"pin_setup_desc": "设置一个 4-8 位 PIN 码以快速解锁钱包。您的钱包密码短语将使用此 PIN 码加密并存储在本地。",
"pin_wallet_passphrase": "钱包密码短语:",
"ping": "延迟",
"portfolio_add_entry": "添加条目",
"portfolio_add_to": "添加到投资组合",