From 096b5a4d17c85fa5f87db3e72364e9c3506d1e64 Mon Sep 17 00:00:00 2001 From: cirakg Date: Sun, 25 Oct 2026 12:46:42 +0100 Subject: feat(pin): exactly 4 digits, entered on the 4th digit The keypad has no OK key; the 4th digit submits, so a tap that also arrives as START can no longer submit a partial PIN (the likely cause of "Wrong PIN" before the code opened). PINs set by earlier versions still unlock and are then replaced by a 4-digit one. Opening an entry ignores a second request from the same tap. A Require PIN sent from the phone while the watch is locked now applies at the next PIN instead of waiting for Confirm all. The linter skips .claude. Co-Authored-By: Claude Opus 5.5 --- source/storage/Vault.mc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source/storage/Vault.mc') diff --git a/source/storage/Vault.mc b/source/storage/Vault.mc index fcd973f..2890477 100644 --- a/source/storage/Vault.mc +++ b/source/storage/Vault.mc @@ -287,6 +287,11 @@ class Vault { return keyManager.hasPin(); } + // True when the PIN predates the 4-digit rule (KeyManager.isLegacyPin). + function isLegacyPin() as Boolean { + return keyManager.isLegacyPin(); + } + // Start checking a PIN: counts the attempt first (README 7.6), then // returns the derivation to run. Throws NO_PIN, LOCKED_OUT or DAMAGED. function beginUnlock(pin as ByteArray) as PinJob { @@ -313,8 +318,9 @@ class Vault { return false; } - // Start setting a PIN: the first PIN, or a new one while unlocked. - // Throws LOCKED when a PIN exists and the session is locked. + // Start setting a PIN (exactly KeyManager.PIN_DIGITS digits): the first + // PIN, or a new one while unlocked. Throws LOCKED when a PIN exists and + // the session is locked, INVALID for any other length. function beginSetPin(pin as ByteArray, iterations as Number) as PinJob { if (keyManager.hasPin() && !session.isUnlocked()) { throw new VaultError(VaultError.LOCKED, "locked"); -- cgit v1.2.3