Provide complete pass-otp viewing and copy behavior in the TOTP destination and normal entry viewer.
Scope
List storage-identified TOTP entries from the discovery catalog and open a native detail screen with issuer/account, large grouped code, countdown/progress, copy action, lock/error state, and refresh.
Request decryption only when a code/detail is opened and calculate every TOTP/HOTP value and validity window in crates/storage.
Update visible countdown/code from storage-owned results using a lifecycle-scoped coroutine; ticks, recomposition, and animations must not extend the authentication lease.
Show the same TOTP component at the top of an OTP-bearing normal entry and let storage update the catalog after an entry is decrypted/created/edited.
Support TOTP algorithms/digits/periods and HOTP behavior exactly as the shared core allows; counter-changing HOTP operations must use storage-owned atomic semantics and explicit confirmation.
Copy only the current storage-returned code through the secure clipboard adapter and clear it according to storage timeout/race rules.
Immediately remove codes on background, expiry, manual lock, entry change, or stale revision.
Do not implement Apple Watch sharing, snapshot, selection, or synchronization.
Acceptance criteria
RFC/upstream pass-otp fixtures display the exact code and transition at boundary times using fake clocks.
Code/countdown updates do not renew the lease and stop when not visible.
TOTP-bearing entry views and the TOTP destination agree and keep the cache current.
Copy is explicit, sensitive-marked, timed, and race-safe.
Kotlin never parses otpauth://, calculates OTP, mutates HOTP counters, or persists secret parameters.
Depends on TOTP discovery, the structured viewer, biometric authentication, and lifecycle security. Part of #87.
Android support update (2026-10-08)
User-directed scope: Android release and CI targets are arm64-v8a and armeabi-v7a. x86_64 Android is excluded for now. Validation for every Android milestone issue uses emulator devices only; physical-device testing and physical-device checklists are excluded. Record the limits of available ARM emulator/API images without claiming physical-device coverage.
## Goal
Provide complete pass-otp viewing and copy behavior in the TOTP destination and normal entry viewer.
## Scope
- List storage-identified TOTP entries from the discovery catalog and open a native detail screen with issuer/account, large grouped code, countdown/progress, copy action, lock/error state, and refresh.
- Request decryption only when a code/detail is opened and calculate every TOTP/HOTP value and validity window in `crates/storage`.
- Update visible countdown/code from storage-owned results using a lifecycle-scoped coroutine; ticks, recomposition, and animations must not extend the authentication lease.
- Show the same TOTP component at the top of an OTP-bearing normal entry and let storage update the catalog after an entry is decrypted/created/edited.
- Support TOTP algorithms/digits/periods and HOTP behavior exactly as the shared core allows; counter-changing HOTP operations must use storage-owned atomic semantics and explicit confirmation.
- Copy only the current storage-returned code through the secure clipboard adapter and clear it according to storage timeout/race rules.
- Immediately remove codes on background, expiry, manual lock, entry change, or stale revision.
- Do not implement Apple Watch sharing, snapshot, selection, or synchronization.
## Acceptance criteria
- RFC/upstream pass-otp fixtures display the exact code and transition at boundary times using fake clocks.
- Code/countdown updates do not renew the lease and stop when not visible.
- TOTP-bearing entry views and the TOTP destination agree and keep the cache current.
- Copy is explicit, sensitive-marked, timed, and race-safe.
- Kotlin never parses `otpauth://`, calculates OTP, mutates HOTP counters, or persists secret parameters.
Depends on TOTP discovery, the structured viewer, biometric authentication, and lifecycle security. Part of #87.
## Android support update (2026-10-08)
User-directed scope: Android release and CI targets are **arm64-v8a** and **armeabi-v7a**. x86_64 Android is excluded for now. Validation for every Android milestone issue uses emulator devices only; physical-device testing and physical-device checklists are excluded. Record the limits of available ARM emulator/API images without claiming physical-device coverage.
hugo
added this to the 06 - Implement an Android version of the software milestone 2026-08-17 19:15:15 +00:00
Implemented Android TOTP list/detail and shared OTP presentation in Rust and Kotlin.
The TOTP destination reads storage's cached catalog without decrypting entries; explicit row selection and Unlock open its detail. It presents issuer/account, large grouped code, countdown/progress, refresh, secure copy, lock/error states and compact/expanded layouts. The same component appears above fields in the normal entry viewer. Decrypt/create/edit reconcile the Rust catalog.
Rust owns algorithm/digits/period parsing, HMAC codes, grouping, countdown, absolute window validation and document revision checks. The rendered component owns its STARTED-lifecycle coroutine; scrolling it out or leaving stops decryption/countdown ticks without touching the lease or showing authentication busy UI. A cheap expiry-only Rust window check still erases hidden codes. Expired or delayed windows are masked before publication; background, expiry, lock, entry changes and stale revisions revoke presentation.
HOTP uses the existing pass-otp atomic counter/Git transaction after a separate counter confirmation. Only a committed code is shown. Refresh/copy retain that counter; declined confirmation, stale ciphertext, open editors, commit failure and overflow cannot consume a counter.
Explicit copies use the existing sensitive clipboard adapter and Rust timeout/ownership cleanup. A fresh Rust window check immediately before the OS write also rejects a code that expired during the native-to-clipboard handoff. Only nonsecret row identity/revision is saved for recreation. Android adds no Watch controls.
Validation:
Required cargo fmt/check (warnings denied), workspace clippy (warnings denied), and cargo test --workspace passed with Rust 1.97.1. The workspace socket/SSH tests required normal local process access.
Android androidVerification and release lint passed: JVM tests, architecture/ktlint/Lint gates, both ARM ABI builds, APK/AAB native/16 KB audits, dependency inventory. Final APK manifest/backup exclusions, release symbols and CycloneDX/license audits passed.
Rust RFC 6238 SHA1/SHA256/SHA512 fixtures at exact boundary times, six/eight digits and custom periods passed. Tests prove no lease renewal, cache agreement, malformed OTP diagnostics, stale revision revocation, HOTP confirmation/copy/refresh, rollback and overflow.
Real encrypted Kotlin/Rust controller fixtures passed on API 26 ARM64 and strict API 37 ARM64 with 16384-byte pages and compatibility mode disabled. They cover cached navigation without unlock, fake wall/lease clock boundaries, clipboard expiry at the handoff, read-only observations overtaken by user actions without revoking their lease, HOTP generations and lifecycle cleanup. Full native controller/editor/settings regression suite passed on strict 16 KB ARM64.
Final app regression suite reported OK (38 tests) on API 37 ARM64; opt-in interactive/strong-biometry tests remain skipped unless explicitly enabled. OTP UI tests prove unlock/copy/refresh/lock and HOTP confirm/cancel; a 300% text test verifies no digit clipping, and a component-disposal test verifies tick cancellation.
Computer use validated the actual Compose catalog/detail, locked state, large grouped code/countdown, explicit copy/lock cleanup, HOTP counter confirmation and resulting code, plus scrolling to actions at 300% text size using disposable presentation fixtures. Retained simulator app data and enrollment were preserved with install -r. Deterministic native tests use OS capability callbacks; no claim of new real-Keystore biometric coverage. Physical devices and x86_64 are excluded by milestone scope.
Reviewed the final changes against every #107 acceptance criterion. See docs/android/otp.md for behavior and evidence. Completion is recorded in the single commit referenced below.
Commit: [6a864a8](https://git.rfc1437.de/hugo/IronStorage/commit/6a864a8d7fe3bcba2d9930ba98a94e2e0fb63c0e), pushed to main.
Implemented Android TOTP list/detail and shared OTP presentation in Rust and Kotlin.
- The TOTP destination reads storage's cached catalog without decrypting entries; explicit row selection and Unlock open its detail. It presents issuer/account, large grouped code, countdown/progress, refresh, secure copy, lock/error states and compact/expanded layouts. The same component appears above fields in the normal entry viewer. Decrypt/create/edit reconcile the Rust catalog.
- Rust owns algorithm/digits/period parsing, HMAC codes, grouping, countdown, absolute window validation and document revision checks. The rendered component owns its STARTED-lifecycle coroutine; scrolling it out or leaving stops decryption/countdown ticks without touching the lease or showing authentication busy UI. A cheap expiry-only Rust window check still erases hidden codes. Expired or delayed windows are masked before publication; background, expiry, lock, entry changes and stale revisions revoke presentation.
- HOTP uses the existing pass-otp atomic counter/Git transaction after a separate counter confirmation. Only a committed code is shown. Refresh/copy retain that counter; declined confirmation, stale ciphertext, open editors, commit failure and overflow cannot consume a counter.
- Explicit copies use the existing sensitive clipboard adapter and Rust timeout/ownership cleanup. A fresh Rust window check immediately before the OS write also rejects a code that expired during the native-to-clipboard handoff. Only nonsecret row identity/revision is saved for recreation. Android adds no Watch controls.
Validation:
- Required cargo fmt/check (warnings denied), workspace clippy (warnings denied), and cargo test --workspace passed with Rust 1.97.1. The workspace socket/SSH tests required normal local process access.
- Android androidVerification and release lint passed: JVM tests, architecture/ktlint/Lint gates, both ARM ABI builds, APK/AAB native/16 KB audits, dependency inventory. Final APK manifest/backup exclusions, release symbols and CycloneDX/license audits passed.
- Rust RFC 6238 SHA1/SHA256/SHA512 fixtures at exact boundary times, six/eight digits and custom periods passed. Tests prove no lease renewal, cache agreement, malformed OTP diagnostics, stale revision revocation, HOTP confirmation/copy/refresh, rollback and overflow.
- Real encrypted Kotlin/Rust controller fixtures passed on API 26 ARM64 and strict API 37 ARM64 with 16384-byte pages and compatibility mode disabled. They cover cached navigation without unlock, fake wall/lease clock boundaries, clipboard expiry at the handoff, read-only observations overtaken by user actions without revoking their lease, HOTP generations and lifecycle cleanup. Full native controller/editor/settings regression suite passed on strict 16 KB ARM64.
- Final app regression suite reported OK (38 tests) on API 37 ARM64; opt-in interactive/strong-biometry tests remain skipped unless explicitly enabled. OTP UI tests prove unlock/copy/refresh/lock and HOTP confirm/cancel; a 300% text test verifies no digit clipping, and a component-disposal test verifies tick cancellation.
- Computer use validated the actual Compose catalog/detail, locked state, large grouped code/countdown, explicit copy/lock cleanup, HOTP counter confirmation and resulting code, plus scrolling to actions at 300% text size using disposable presentation fixtures. Retained simulator app data and enrollment were preserved with install -r. Deterministic native tests use OS capability callbacks; no claim of new real-Keystore biometric coverage. Physical devices and x86_64 are excluded by milestone scope.
Reviewed the final changes against every #107 acceptance criterion. See docs/android/otp.md for behavior and evidence. Completion is recorded in the single commit referenced below.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Provide complete pass-otp viewing and copy behavior in the TOTP destination and normal entry viewer.
Scope
crates/storage.Acceptance criteria
otpauth://, calculates OTP, mutates HOTP counters, or persists secret parameters.Depends on TOTP discovery, the structured viewer, biometric authentication, and lifecycle security. Part of #87.
Android support update (2026-10-08)
User-directed scope: Android release and CI targets are arm64-v8a and armeabi-v7a. x86_64 Android is excluded for now. Validation for every Android milestone issue uses emulator devices only; physical-device testing and physical-device checklists are excluded. Record the limits of available ARM emulator/API images without claiming physical-device coverage.
Commit: 6a864a8, pushed to main.
Implemented Android TOTP list/detail and shared OTP presentation in Rust and Kotlin.
Validation:
Reviewed the final changes against every #107 acceptance criterion. See docs/android/otp.md for behavior and evidence. Completion is recorded in the single commit referenced below.