aboutsummaryrefslogtreecommitdiff
path: root/source/util
Commit message (Collapse)AuthorAgeFilesLines
* fix(import): splitting pasted otpauth:// links runs no character loopcirakg2 days1-0/+27
| | | | | | | | | | OtpAuth.splitUris/firstWord looped over every character in one event, so pasting about 100 links tripped the watchdog (the UI fixture imports Aegis JSON, so it never ran this path). They now use native searches only. New make watchdog case uris_100 (13,576 characters, twice per event) trips on the old code and passes now. fr70: make lint, make test, make watchdog pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(pin): the work after a PIN and the change queue run in stepscirakg2 days3-12/+494
| | | | | | | | | | | | | | | | | | | | | | | | After a correct or new PIN, promoting pending entries and applying waiting "Require PIN" changes ran in the event of the last PBKDF2 step; 16 waiting changes tripped the watchdog on the Forerunner 70. ChangeQueue.LockJob now does it in steps while the PIN screen shows "Checking...", saves what it did to the results and refreshes the glance after Set PIN too. The list title decrypted every waiting change at each start. Queue items are now [action, box] (aad OTPW-Q-2 + action code), so they are counted without decrypting; 0.9.0 items are still read. A replacement is checked when it arrives and its material is sealed apart (qm.<n>). Large buffers are wiped and UTF-8-checked in pieces (Jobs.Wiper, Bytes.utf8Prefix, SealedBox.openKeep/sealKeep). "Phone changes" reads behind "Reading...", and Confirm all / Reject all act only on the changes shown. Storage full no longer stops the app at the PIN. Found by the review of b8addc8/096b5a4 and a new make watchdog test; the diff was reviewed again and its findings fixed. fr70: make lint, make test (176), make watchdog (19 cases at two steps per event), make screenshots pass; list_locked and list_reset goldens show "Results ready (menu)". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(ui): second UI scenario, and the fixes it foundcirakg3 days1-5/+26
| | | | | | | | | | | | | | | | | | | A second UI-test build (uitest-extra.jungle) covers the legacy PIN and the forced new PIN, Change and Reset PIN, a queued Require PIN, UPC-A, Code 39, the code error screen, the encoding progress, auto-lock on a barcode, the light theme and the glance without a code; the main flow adds the Steam and Library details and the menu's text screens. Fixed from what it found: Entry IDs tripped the watchdog with 110 entries; auto-lock didn't close a locked barcode; a queued Require PIN showed "Confirm in menu"; locked barcodes lacked the padlock; the PIN keypad's bottom row, the Reset PIN question, text-screen bottoms, the glance title and the light-theme warning colour. Goldens approved on all seven watches; only the Forerunner 70 was re-verified after the version bump. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(build): add make watchdog, the glance memory budget and the glance ↵cirakg8 days1-0/+215
| | | | | | | | | | | | | | | screenshot - make watchdog (in make ci): a stress build encodes, packs, turns into runs and draws the largest code of every 2D symbology at two steps per event on the Forerunner 255S and 70; it fails on a watchdog trip, and the last code left on the screen must decode (bitmap path on the 70). - make memtest checks the glance (DIAG glance, budget 70 % of 64 KB). - screenshots.sh launches the app again after the flow and compares the glance with the favourite's code (glance_code.png on 7 watches); the About goldens show 0.8.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(glance): show the favourite code in the glance (opt-in)cirakg8 days4-2/+18
| | | | | | | | | | | | | | | With "Show the favourite code in the glance" on, the glance shows the code of the first favourite TOTP or Steam entry without the PIN, with a countdown bar. The glance can't open the vault, so the About scan seals that entry under "g" (device key, aad OTPW-GL-1) after every change, and removes it when the option is off or no entry qualifies; the glance also reads the option itself. HKDF moves to its own module so the glance loads only the crypto it needs (37 % of its 64 KB). Manage entry gains "Mark as favourite (glance)" and "Remove favourite", queued for locked entries like the other changes. Lines are inset on round screens so the Instinct 3's curved glance corner doesn't cut them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(codes): bound every 2D encoding step under the watchdog; draw large ↵cirakg8 days1-5/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | codes from runs M6's step sizes were estimates, only exercised with small codes. With the largest inputs the app accepts, every 2D encoder tripped the watchdog on the Forerunner 255S (and the biggest steps were far over the 768 KB watches' limit), so a large code added from the phone would have stopped the app during settings processing at every start. - QR: resumable segmentation, Reed-Solomon, interleaving, function patterns and final mask; mask scoring on rows and columns packed 16 modules per word (same penalties, checked against the per-module rules). - Reed-Solomon: resumable field tables and generator, encoder shifting with native slice. - Data Matrix, Aztec, PDF417: resumable encodation, stuffing, compaction, placement and build; Data Matrix's grid as a byte array (90 KB -> 35 KB); PDF417 refuses text that can't fit the screen before compacting. - Cache format 2 with 16-bit sizes (wide PDF417 was cached wrong); packing in steps; codes drawn as runs, and from a bitmap painted in steps when a frame can't draw all runs. - The job runner does two steps per tick on 768 KB watches; gen_products --check verifies each product's watchdogCount fits that. - CodeView renews full brightness (AMOLED) or the backlight (MIP) for up to a minute from its single ticker; a tap restarts the minute. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(settings): apply the Import form from the phone and show resultscirakg9 days1-0/+27
| | | | | | | | Import group in the app settings; the processor runs after the first frame and on settings changes, clears the fields, writes the status, remembers form hashes and opens the results screen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(import): parse otpauth URIs and unencrypted Aegis JSON in resumable stepscirakg9 days1-0/+56
| | | | | | | | | | Streaming JSON tokenizer with depth and length limits and native skipping of long strings; Aegis reader for database versions 1-3 with groups and encrypted-export detection; otpauth parser with ';' separators and Steam; import job with Replace mode, duplicate and replacement checks, a sealed multi-part buffer and a report. Google Authenticator exports deferred. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(ui): add the list, OTP detail, PIN entry, menu, info screens and glancecirakg9 days3-1/+86
| | | | | | | | | | | | List with live codes and countdowns, adaptive rows and lazy headers; OTP detail with ring or bar, next code and HOTP next; PIN keypad or button selector with create, unlock, change, lockout display and pending promotion; native menu; glance with the entry count; self-test after the first frame; option properties with defaults. Codes are computed one per timer event, apart from drawing, for the watchdog. A UI-test build (uitest.jungle) starts with fake entries, PIN 123456 and a frozen clock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(storage): add the encrypted vault, PIN keys, lockout, session and ↵cirakg10 days1-0/+60
| | | | | | | | | | | | | | migrations Records are one ByteArray each: a readable TLV header plus an encrypt-then-MAC box whose aad binds the entry ID and the header. The device key seals unlocked entries and pending items; a random master key, wrapped under a PBKDF2 PIN key, seals locked ones. Wrong PINs are counted before the check, with delays on the trusted clock and an uptime fallback. Bytes.toUtf8 validates UTF-8 first, because the native conversion crashes on invalid input. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(crypto): add SHA-512, HMAC, PBKDF2, HKDF, AES-256 records and self-testcirakg10 days3-0/+228
| | | | | | | | | | | | | | | | - Sha512: FIPS 180-4 in Monkey C (no native SHA-512), rotations inlined with precomputed masks; constants derived from the primes, not typed. - Hmac: RFC 2104 over SHA-1/256/512 (native HMAC only supports SHA-256). - Kdf: resumable PBKDF2-HMAC-SHA256 job with calibration bounds (2,000-200,000 iterations) and HKDF-SHA256. - Aes: CBC with PKCS#7 over the native cipher; AES-256 chosen. - SealedBox: encrypt-then-MAC records (HKDF-split keys, length-prefixed aad, constant-time tag check before decryption). - SelfTest: known-answer tests for every primitive at start-up. - Bytes (wipe, constant-time equal), Clock (2038-safe widening, trusted clock), Jobs (bounded steps against the watchdog, timer runner). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(app): add minimal watch app with smoke test and per-size iconscirakg10 days1-0/+50
The M0 placeholder app: AppBase entry point, home screen with name and version, debug-only diagnostics (start-up time, memory) and a unit test that runs in the headless simulator. Builds with strict type checking and zero warnings for all 72 products; icons.jungle gives every product a launcher icon of its exact size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>