refactor(auth): route AppLockViewModel/AccountSetupViewModel logging through AppLog (#324) #326

Closed
opened 2026-07-05 00:49:18 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-07-05 00:49:18 +00:00 (Migrated from github.com)

Part of #324 (strangler-migrate debug logging to AppLog).

Sequencing: PARALLEL with the other migration areas, after the Seam ticket merges
(needs AppLog.w(tag, msg, throwable) / AppLog.d(tag, msg, throwable)). Touches only
ui/lock + ui/accountsetup, so no file collision with sibling areas.

Scope (files)

  • app/src/main/kotlin/org/libremail/ui/lock/AppLockViewModel.kt — 9 raw Log.w sites.
  • app/src/main/kotlin/org/libremail/ui/accountsetup/AccountSetupViewModel.kt — 1 raw Log.d.
  • Tests: app/src/test/.../ui/lock/AppLockViewModelTest.kt,
    app/src/test/.../ui/accountsetup/AccountSetupViewModelTest.kt (both currently
    mockkStatic(Log::class) — rewrite to assert the buffer instead).

Migrate these call sites (all -> org.libremail.reporting.AppLog; drop import android.util.Log)

AppLockViewModel.kt (TAG unchanged):

  • :201 Log.w(TAG, "encrypted cache passphrase unrecoverable; clearing cache") -> AppLog.w(TAG, same) — no throwable.
  • :243 Log.w(TAG, "arming auth seal failed", e) -> AppLog.w(TAG, msg, e).
  • :252 Log.w(TAG, "auth-sealed passphrase present but key was deleted; cache unrecoverable") -> AppLog.w(TAG, msg).
  • :259 Log.w(TAG, "auth-bound key permanently invalidated", e) -> AppLog.w(TAG, msg, e).
  • :262 Log.w(TAG, "auth window elapsed before unwrap; will retry", e) -> AppLog.w(TAG, msg, e).
  • :271 Log.w(TAG, "unexpected failure unwrapping auth-sealed passphrase; will retry", e) -> AppLog.w(TAG, msg, e).
  • :305 Log.w(TAG, "re-sync enqueue not confirmed within timeout; restarting anyway", e) -> AppLog.w(TAG, msg, e).
  • :307 Log.w(TAG, "re-sync enqueue failed; restarting anyway", e) -> AppLog.w(TAG, msg, e).
  • :310 Log.w(TAG, "interrupted awaiting re-sync enqueue; restarting anyway", e) -> AppLog.w(TAG, msg, e).

AccountSetupViewModel.kt:

  • :76 Log.d(TAG, "Outlook sign-in failed after redirect", e) -> AppLog.d(TAG, msg, e).
    Update the :74-75 comment: AppLog.d still records to the buffer in release (the
    buffer.record line is not stripped by the -assumenosideeffects Log.d rule), so the
    breadcrumb now reaches a report; only the Logcat mirror is stripped. The throwable may carry
    the email/token in its message -> the Seam StackTraceScrubber redacts it on buffer-record.

New breadcrumbs (auth-seal transitions — currently silent)

  • AppLockViewModel.onAuthenticated success (UnlockResult.OK): AppLog.i(TAG, "auth seal unlocked; cache readable").
  • AppLockViewModel.clearCacheAndRestart: AppLog.w(TAG, "clearing encrypted cache and restarting (disableAppLock=$disableAppLock)").
  • AppLockViewModel.onForeground: AppLog.i(TAG, "app-lock foreground decision: $action") (the LockAction enum is non-PII).
  • AccountSetupViewModel success branch: AppLog.i(TAG, "Outlook account added") (NO email).

PII

None of these messages carry PII (keystore/auth exceptions, enum names). Do not add the
account email; if an account must be referenced use accountLogRef(account.id) from the Seam.

Test expectation (unit)

  • Rewrite both ViewModel tests to AppLog.install(RingLogBuffer()) (real buffer) instead of
    mockkStatic(Log::class), then assert buffer.snapshot() captured the expected
    breadcrumb(s) by level + message substring (e.g. the unlock/clearing encrypted cache
    lines). Removing the Log mock removes import android.util.Log from these tests, which the
    guard-rule ticket requires.
  • Add a no-PII assertion: drive a failing Outlook sign-in with a known test email and
    assert no buffer line contains that address.
  • Per repo DoD, extend the existing lock/account-setup E2E to exercise a failure path and
    (where a report surface is reachable) assert the breadcrumb is present and PII-free.

Parallelism: parallel with DB/keystore, connectivity/send, sync-engine, stragglers — after Seam.

Part of #324 (strangler-migrate debug logging to AppLog). **Sequencing: PARALLEL** with the other migration areas, **after the Seam ticket merges** (needs `AppLog.w(tag, msg, throwable)` / `AppLog.d(tag, msg, throwable)`). Touches only `ui/lock` + `ui/accountsetup`, so no file collision with sibling areas. ## Scope (files) - `app/src/main/kotlin/org/libremail/ui/lock/AppLockViewModel.kt` — 9 raw `Log.w` sites. - `app/src/main/kotlin/org/libremail/ui/accountsetup/AccountSetupViewModel.kt` — 1 raw `Log.d`. - Tests: `app/src/test/.../ui/lock/AppLockViewModelTest.kt`, `app/src/test/.../ui/accountsetup/AccountSetupViewModelTest.kt` (both currently `mockkStatic(Log::class)` — rewrite to assert the buffer instead). ## Migrate these call sites (all -> `org.libremail.reporting.AppLog`; drop `import android.util.Log`) `AppLockViewModel.kt` (TAG unchanged): - `:201` `Log.w(TAG, "encrypted cache passphrase unrecoverable; clearing cache")` -> `AppLog.w(TAG, same)` — no throwable. - `:243` `Log.w(TAG, "arming auth seal failed", e)` -> `AppLog.w(TAG, msg, e)`. - `:252` `Log.w(TAG, "auth-sealed passphrase present but key was deleted; cache unrecoverable")` -> `AppLog.w(TAG, msg)`. - `:259` `Log.w(TAG, "auth-bound key permanently invalidated", e)` -> `AppLog.w(TAG, msg, e)`. - `:262` `Log.w(TAG, "auth window elapsed before unwrap; will retry", e)` -> `AppLog.w(TAG, msg, e)`. - `:271` `Log.w(TAG, "unexpected failure unwrapping auth-sealed passphrase; will retry", e)` -> `AppLog.w(TAG, msg, e)`. - `:305` `Log.w(TAG, "re-sync enqueue not confirmed within timeout; restarting anyway", e)` -> `AppLog.w(TAG, msg, e)`. - `:307` `Log.w(TAG, "re-sync enqueue failed; restarting anyway", e)` -> `AppLog.w(TAG, msg, e)`. - `:310` `Log.w(TAG, "interrupted awaiting re-sync enqueue; restarting anyway", e)` -> `AppLog.w(TAG, msg, e)`. `AccountSetupViewModel.kt`: - `:76` `Log.d(TAG, "Outlook sign-in failed after redirect", e)` -> `AppLog.d(TAG, msg, e)`. Update the `:74-75` comment: `AppLog.d` still records to the **buffer** in release (the `buffer.record` line is not stripped by the `-assumenosideeffects` Log.d rule), so the breadcrumb now reaches a report; only the Logcat mirror is stripped. The throwable may carry the email/token in its message -> the Seam `StackTraceScrubber` redacts it on buffer-record. ## New breadcrumbs (auth-seal transitions — currently silent) - `AppLockViewModel.onAuthenticated` success (`UnlockResult.OK`): `AppLog.i(TAG, "auth seal unlocked; cache readable")`. - `AppLockViewModel.clearCacheAndRestart`: `AppLog.w(TAG, "clearing encrypted cache and restarting (disableAppLock=$disableAppLock)")`. - `AppLockViewModel.onForeground`: `AppLog.i(TAG, "app-lock foreground decision: $action")` (the `LockAction` enum is non-PII). - `AccountSetupViewModel` success branch: `AppLog.i(TAG, "Outlook account added")` (NO email). ## PII None of these messages carry PII (keystore/auth exceptions, enum names). Do **not** add the account email; if an account must be referenced use `accountLogRef(account.id)` from the Seam. ## Test expectation (unit) - Rewrite both ViewModel tests to `AppLog.install(RingLogBuffer())` (real buffer) instead of `mockkStatic(Log::class)`, then assert `buffer.snapshot()` captured the expected breadcrumb(s) by level + message substring (e.g. the unlock/`clearing encrypted cache` lines). Removing the `Log` mock removes `import android.util.Log` from these tests, which the guard-rule ticket requires. - Add a **no-PII** assertion: drive a failing Outlook sign-in with a known test email and assert no buffer line contains that address. - Per repo DoD, extend the existing lock/account-setup E2E to exercise a failure path and (where a report surface is reachable) assert the breadcrumb is present and PII-free. **Parallelism:** parallel with DB/keystore, connectivity/send, sync-engine, stragglers — after Seam.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#326