Skip to content

App Configurable Auto lock - #905

Merged
piyalbasu merged 33 commits into
mainfrom
lf-add-auto-lock
Jul 7, 2026
Merged

piyalbasu merged 33 commits into
mainfrom
lf-add-auto-lock

Conversation

@leofelix077

@leofelix077 leofelix077 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Closes #627

Adds a configurable Auto-Lock to Settings → Security, so users decide how quickly the wallet re-locks itself: 1 minute, 5 minutes, 15 minutes, 30 minutes, 1 hour, 6 hours, 12 hours, or 24 hours (default 12h). This is the exact same option set and default as the Freighter extension (VALID_AUTO_LOCK_TIMEOUT_MINUTES, DEFAULT_AUTO_LOCK_TIMEOUT_MINUTES=720), so the two platforms behave identically. After the chosen time the user is asked for their password (or biometrics) again

It locks on inactive time, either on background or in the foreground without any actions. Tracking is done via gestures, presses and navigation.

The lock itself is a soft lock: the screen you were on stays mounted underneath a lock overlay, so after unlocking you land back exactly where you were instead of getting bounced to a reloaded home screen.

There are two independent timers. The soft auto-lock above governs how soon the wallet re-locks (fast unlock — the persisted key is reused, so you resume where you were). The hash-key hard-expiry (HASH_KEY_EXPIRATION_MS) is a separate, coarser security backstop that caps how long derived key material may live in secure storage before it's discarded and you get a full re-authentication from your password — regardless of the soft-lock preset. This backstop is set to 72h: because it's anchored at sign-in and checked before the soft timer, it must exceed the largest preset (24h) or that preset's fast-unlock path could never run. 72h (3x the max preset) gives enough headroom that even a loosely-active user on the 24h preset — whose gaps stay just under 24h, so the soft-lock never fires and never resets this clock — is unlikely to hit a surprise full re-auth. (Resolves the reviewer comment on HASH_KEY_EXPIRATION_MS; earlier iterations were 24h, then briefly 7 days.)

The hard-expiry is also hardened against clock rollback: each hash key records a generatedAt timestamp, and a key whose generatedAt is in the future (device clock moved backward below the key's creation time) is treated as expired. This prevents a rolled-back clock from keeping cached key material usable past the backstop — mirroring the soft-timer's existing future-timestamp guard. (Unlock still verifies the password on every path, so this is defense-in-depth.)

Follow-up (separate PR): re-anchor the hard expiry on background/last-activity instead of sign-in, so the two timers are commensurable and no fixed backstop value is needed.

biometric prompt only triggers when coming from background. signing is blocked until unlocked , toasts wait for loading+state to be rehydrated before deciding on showing or not to avoid false positive errors

for Added privacy, on the native layer it also adds a Privacy shield -> When app is in background, only the splash screen is shown, and on the native app switcher carousel menu, it does not show any information. When the app goes to background, it waits for the native JS layer to be ready (auth state and storage hydrated) to show again the lock screen or the home screen, avoiding exposing any info during this in-between state

📱 Tested iOS Build 1.19.26 (1781721439)

Android smoke tests:

Screen.Recording.2026-06-17.at.12.20.45.mov
Screen.Recording.2026-06-17.at.12.24.16.mov

Ios Tests:

Send flow / login with biometric / background / state preservation on reunlock / demonstration with timers

ScreenRecording_06-17-2026.14-07-55_1.mov

no timer / more lock and unlock / privacy shield preservation

ScreenRecording_06-17-2026.16-55-18_1.mov

no biometrics tests with swap and collectible flows

ScreenRecording_06-17-2026.16-59-12_1.MP4

One small addition post last build to reset the default timers on sing up / reimport

Screen.Recording.2026-06-17.at.18.06.29.mov

Checklist

PR structure

  • This PR does not mix refactoring changes with feature changes (break it down into smaller PRs if not).
  • This PR has reasonably narrow scope (break it down into smaller PRs if not).
  • This PR includes relevant before and after screenshots/videos highlighting these changes.
  • I took the time to review my own PR.

Testing

  • These changes have been tested and confirmed to work as intended on Android.
  • These changes have been tested and confirmed to work as intended on iOS.
  • I have tried to break these changes while extensively testing them.
  • This PR adds tests for the new functionality or fixes.

Release

  • This is not a breaking change.
  • This PR updates existing JSDocs when applicable.
  • This PR adds JSDocs to new functionalities.
  • I've checked with the product team if we should add metrics to these changes.
  • I've shared relevant before and after screenshots/videos highlighting these changes with the design team and they've approved the changes.

@leofelix077 leofelix077 self-assigned this Jun 16, 2026
@leofelix077 leofelix077 added wip work in progress don't review yet Work in Progress / Draft PR / Code Review adjustments being worked on labels Jun 16, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 723206ec5c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/ducks/auth.ts Outdated
Comment thread src/components/App.tsx Outdated
Comment thread src/components/LockScreenOverlay.tsx
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

iOS Simulator preview build is ready: https://github.com/stellar/freighter-mobile/releases/tag/untagged-905f7aa90c0219e6106c (SDF collaborators only — install instructions in the release description)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b7d43caee

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/ducks/auth.ts
Comment thread src/components/LockScreenOverlay.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 996b9a9c67

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/ducks/auth.ts
Comment thread src/components/LockScreenOverlay.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 820f7dbbe3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/ducks/preferences.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 14fcdc9f42

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ba81a3c341

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread ios/freighter-mobile/AppDelegate.swift

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 44f10d969a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/components/screens/HomeScreen/HomeScreen.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5cf10fd718

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/hooks/useAuthCheck.ts Outdated
Comment thread android/app/src/main/java/com/freightermobile/MainActivity.kt

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98de964087

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/ducks/auth.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8281249b68

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/hooks/useAuthCheck.ts Outdated
Comment thread src/ducks/auth.ts Outdated
Comment thread __tests__/components/screens/SettingsScreen/AutoLockTimerScreen.test.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e781e130ca

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/components/screens/LockScreen.tsx
Comment thread src/config/constants.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5fa28e85d0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/providers/ToastProvider.tsx
Copilot AI review requested due to automatic review settings July 6, 2026 17:29
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a configurable auto-lock feature to Freighter Mobile, including a “soft lock” overlay that preserves in-progress navigation state, plus native privacy shielding to prevent wallet content from appearing in the OS app switcher while backgrounded.

Changes:

  • Introduces secure-storage-backed auto-lock timer persistence + background timestamp tracking, and integrates timer evaluation into auth checks.
  • Adds a soft-lock overlay (keeps navigation tree mounted) and suppresses non-lock toasts while soft-locked; hardens signing paths against mid-await locking.
  • Adds Settings UI for selecting the auto-lock timer, i18n strings, and extensive Jest coverage across the new behaviors.

Reviewed changes

Copilot reviewed 46 out of 48 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/services/autoLock.ts New service for secure auto-lock settings, background timestamps, and hash-key TTL anchoring.
src/providers/ToastProvider.tsx Suppresses most toasts while soft-locked (allows only lock-related IDs).
src/navigators/SettingsNavigator.tsx Adds AutoLockTimerScreen route to Settings stack.
src/navigators/RootNavigator.tsx Keeps authenticated stack mounted under soft lock; hides underlying tree from accessibility while soft-locked; hydrates auto-lock timer on init.
src/i18n/locales/en/translations.json Adds English strings for Security auto-lock entry + timer screen.
src/i18n/locales/pt/translations.json Adds Portuguese strings for Security auto-lock entry + timer screen.
src/hooks/useTokenFiatConverter/index.ts Records user activity on keyboard input to avoid idle-lock during amount entry.
src/hooks/useManageTokens.ts Re-checks unlocked state before signing after async tx build.
src/hooks/useGetActiveAccount.ts Adds isWalletUnlocked guard and blocks signing when soft-locked.
src/hooks/useAuthCheck.ts Adds background/foreground auto-lock evaluation, activity tracking, and privacy-shield coordination.
src/hooks/useAppOpenBiometricsLogin.ts Removes prior app-open biometric flow (superseded by lock screen logic).
src/helpers/userActivity.ts Adds a global bridge for recording user activity from non-PanResponder inputs.
src/helpers/privacyShield.ts Adds JS wrapper for native privacy shield dismissal + visibility tracking.
src/ducks/preferences.ts Adds autoLockTimer state + secure-mirror hydration/persist with rollback behavior.
src/ducks/auth.ts Implements soft-lock state machine, timer-aware auth checks, and timer-aware hash-key TTL behavior.
src/config/routes.ts Adds settings route type for AutoLockTimerScreen.
src/config/constants.ts Adds auto-lock enums/durations/toast IDs and updates hash-key expiration semantics.
src/components/screens/SwapScreen/hooks/useSwapTransaction.ts Blocks signing if a lock engaged after swap was prepared.
src/components/screens/SettingsScreen/SecurityScreen/SecurityScreen.tsx Adds Security list item to navigate to auto-lock timer settings.
src/components/screens/SettingsScreen/SecurityScreen/AutoLockTimerScreen/index.ts New barrel export for AutoLockTimerScreen.
src/components/screens/SettingsScreen/SecurityScreen/AutoLockTimerScreen/AutoLockTimerScreen.tsx New UI for selecting auto-lock timer preset.
src/components/screens/SendScreen/screens/TransactionAmountScreen.tsx Prevents false validation errors during rehydration; adds wallet-unlocked guard before signing.
src/components/screens/SendScreen/screens/SendCollectibleReview.tsx Adds wallet-unlocked guard before signing collectible send.
src/components/screens/LockScreen.tsx Refactors into reusable LockScreenContent; implements privacy-shield-aware biometric auto-prompt logic.
src/components/Modal.tsx Auto-dismisses RN Modals on soft lock so they can’t cover the lock overlay.
src/components/LockScreenOverlay.tsx New full-screen overlay for in-process soft lock.
src/components/App.tsx Renders the soft-lock overlay above providers so it covers sheets/navigation.
jest.setup.js Mocks isWalletUnlocked and adds keyboard-controller Jest mock.
jest.config.js Adds react-native-keyboard-controller to transform ignore patterns.
ios/PrivacyShield.swift Adds iOS native module used to dismiss privacy shield from JS.
ios/PrivacyShield.m Objective-C bridge for the PrivacyShield Swift module.
ios/PrivacyShield.podspec Defines local pod for the iOS PrivacyShield module.
ios/Podfile Adds PrivacyShield local pod dependency.
ios/Podfile.lock Locks PrivacyShield pod in iOS dependencies.
ios/freighter-mobile/AppDelegate.swift Implements iOS privacy window shield and notification-driven dismissal.
android/app/src/main/java/org/stellar/freighterwallet/PrivacyShieldPackage.kt Adds Android ReactPackage for the PrivacyShield module.
android/app/src/main/java/org/stellar/freighterwallet/PrivacyShieldModule.kt Adds Android native module for hiding the privacy shield.
android/app/src/main/java/com/freightermobile/MainApplication.kt Registers PrivacyShieldPackage.
android/app/src/main/java/com/freightermobile/MainActivity.kt Implements Android privacy overlay + fallback timer; enables FLAG_SECURE.
tests/services/autoLock.test.ts Unit tests for autoLock service behavior.
tests/providers/ToastProvider.test.tsx Tests toast suppression behavior while soft-locked.
tests/hooks/useGetActiveAccountSigningGuard.test.tsx Tests signing is blocked while soft-locked / not authenticated.
tests/hooks/useAuthCheck.test.tsx Tests background/idle timer handling and interaction signals.
tests/ducks/preferences.test.ts Tests secure-mirror hydration/persist/rollback for auto-lock timer setting.
tests/ducks/auth.test.ts Extends auth duck tests to cover timer behavior and soft-lock funneling.
tests/components/screens/SettingsScreen/AutoLockTimerScreen.test.tsx Tests timer options render + selection updates store state.
tests/components/screens/LockScreen.test.tsx Tests biometric auto-prompt behavior and privacy-shield gating.
tests/components/LockScreenOverlay.test.tsx Tests overlay mounts/unmounts based on soft-lock state.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/config/constants.ts Outdated
Comment thread src/config/constants.ts
Comment thread src/config/constants.ts Outdated
Comment thread src/components/screens/SwapScreen/hooks/useSwapTransaction.ts
Comment thread src/components/screens/SendScreen/screens/TransactionAmountScreen.tsx Outdated
Comment thread src/components/screens/SendScreen/screens/SendCollectibleReview.tsx
The configurable auto-lock feature added a 24h soft-lock preset while the
pre-existing 24h hard-expiry backstop (HASH_KEY_EXPIRATION_MS) was silently
widened to 7 days so that preset's fast-unlock path stays reachable (the
hard expiry is anchored at sign-in and checked before the soft timer, so a
<=24h backstop fires first and the 24h preset could never fast-unlock).

7 days materially weakens the forced full re-auth window and matches nothing
on the extension (which has no persisted-session hard expiry at all). 48h is
the tight bound that still clears the 24h preset with headroom, restoring the
backstop close to its long-standing 24h behavior. NONE still opts out via
NEVER_EXPIRE_HASH_KEY_MS.

Follow-up (separate PR): re-anchor the hard expiry on background/last-activity
instead of sign-in so the two timers are commensurable and no fixed value is
needed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

The Send, Collectible, and Swap confirmation guards previously threw
`new Error("Wallet is locked")` when an auto-lock engaged between opening
the review sheet and signing. That had two problems flagged in review:

- Send/Collectible: the throw was caught after `setIsProcessing(true)` and
  the sheet was dismissed, but the catch never reset `isProcessing`, so the
  user was stranded on the TransactionProcessingScreen "sending" spinner
  after unlocking.
- Swap: the hard-coded English string became the error-toast title (the
  catch surfaces `error.message`), i.e. non-localized UI text.

Being locked isn't a transaction failure, so all three now abort cleanly:
reset `isProcessing` and return, skipping the failure toast/analytics path.
The user simply lands back on the review screen after unlocking. In swap the
early return (vs throw) also keeps the fire-and-forget executeSwap() from
rejecting unhandled.

Addresses review comments on TransactionAmountScreen, SendCollectibleReview,
and useSwapTransaction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

Aligns the mobile auto-lock preset set with the extension's
VALID_AUTO_LOCK_TIMEOUT_MINUTES so both platforms offer identical options:
1 min, 5 min, 15 min, 30 min, 1 hr, 6 hr, 12 hr, 24 hr (default 12h).

- Removes IMMEDIATELY (no extension equivalent; it was the only lock-on-
  background option) and its dedicated logic in useAuthCheck (background
  soft-lock branch) and getAuthStatus (the 0ms special case).
- Removes NONE (no extension equivalent) and, with it, the whole
  timer-aware hash-key TTL machinery it existed to support:
  NEVER_EXPIRE_HASH_KEY_MS, getHashKeyExpirationMs, and
  applyAutoLockTimerToHashKey. All presets now share the single 48h
  hard-expiry backstop, stamped directly at sign-in / generateHashKey, so
  setAutoLockTimer just persists the preference (+ rollback on failure).
- Adds FIVE_MINUTES and SIX_HOURS presets + en/pt translations.

Simplifies the now-unconditional timer guards in getAuthStatus and
useAuthCheck (all durations are positive) and updates the affected tests.

Addresses the reviewer comments on the auto-lock option set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

- Forgot-password unreachable while soft-locked: Modal auto-dismisses on
  soft-lock, but the lock overlay's own ForgotPasswordWarningModal used that
  same behavior, so tapping "Forgot password?" from the overlay instantly
  dismissed the warning. Added an opt-out (`dismissOnSoftLock`) and set it on
  the forgot-password modal so the reset flow stays usable while locked.

- Android accessibility leak: the overlay only set `accessibilityViewIsModal`
  (iOS). Wrapped the app tree in a SoftLockAccessibilityShield that also sets
  `accessibilityElementsHidden` (iOS) and `importantForAccessibility`
  (Android) while soft-locked, so TalkBack/VoiceOver can't traverse the
  wallet underneath the overlay.

- Private key restored under lock: signIn's background getActiveAccount().then
  set `account` without re-checking isSoftLocked, so a lock engaging during
  the slow key derivation would repopulate the private key into a LOCKED
  store. Now drops the stale load when isSoftLocked.

Addresses review comments on Modal/LockScreenOverlay and the post-unlock
account-load race.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

- Toast above the lock overlay: showToast already blocked NEW toasts while
  soft-locked, but a toast already visible when auto-lock fired stayed
  rendered (the absolute ToastContainer sits above the in-tree overlay).
  ToastProvider now tracks isSoftLocked reactively and drops non-allowlisted
  toasts from the render, so nothing lingers over the lock screen.

- setAutoLockTimer write races: rapid taps fired overlapping fire-and-forget
  mirror writes that could land out of order (mirror disagreeing with the
  latest selection), and a failed earlier write's rollback could clobber a
  newer selection. Writes are now serialized (each awaits the previous) and
  tagged, so rollback only applies when the selection is still current.

- Stale backgrounded-at write: on a fast background->foreground bounce,
  recordBackgroundedAt could resolve after getAuthStatus already cleared the
  timestamp, leaving a stale one that could later lock. The background
  handler now clears it if the app has returned to the foreground by the time
  the write lands.

Addresses the remaining lower-severity race comments (ToastProvider,
preferences, useAuthCheck).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

The 48h hard-expiry backstop used `Date.now() > expiresAt`, with no defense
against a backward clock change — rolling the device clock back below the
key's expiry kept the cached derived-key material usable past the intended
bound (the soft-timer path already guards this via getBackgroundedAt's
future-timestamp check; the hard-expiry did not, an asymmetry).

Stamp `generatedAt` when a hash key is created/refreshed and treat a key whose
generatedAt is in the future as expired, so a clock rolled back below the
key's creation time forces a full re-auth. generatedAt is optional, so keys
persisted before this change fall back to the plain expiry check. Unlock still
requires the password on every path, so this is defense-in-depth hardening,
not an auth-bypass fix.

Also normalizes a pre-existing single-quote lint error surfaced in the same
test file.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

The Test job failed on the single AboutScreen suite with
"_reactNativeDeviceInfo.getBundleId is not a function". AboutScreen's import
graph reaches helpers/isEnv, which calls getBundleId() at module load, but the
test's local react-native-device-info mock only stubbed getVersion /
getBuildNumber / hasNotch. Add getBundleId so the suite can load.

Pre-existing test-infra gap (main has the same incomplete mock); surfaced on
this branch after main was merged in. Unrelated to the auto-lock changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

At 48h (2x the 24h max preset), a loosely-active user on the 24h auto-lock
preset — one whose usage gaps stay just under 24h, so the soft-lock never
fires and never resets the sign-in-anchored hard-expiry — could hit a full
password re-auth roughly every ~2 days. 72h (3x the max preset) widens the
headroom so that pattern must persist a full three days to trip it, making a
surprise re-auth unlikely for normal 24h-preset use.

Still a stopgap for the sign-in-anchored design; the complete fix is to
re-anchor the hard-expiry on activity/foreground (tracked as a follow-up),
after which no fixed backstop value is needed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@piyalbasu
piyalbasu merged commit eac9466 into main Jul 7, 2026
34 of 35 checks passed
@piyalbasu
piyalbasu deleted the lf-add-auto-lock branch July 7, 2026 17:29
@github-actions github-actions Bot mentioned this pull request Jul 7, 2026
piyalbasu added a commit that referenced this pull request Aug 31, 2026
Under sign-in anchoring (#905), LOCKED deliberately outranked the expiry
check so routine lock-screen expiry kept the fast unlock reachable. With
the TTL re-anchored on activity, an expired key under a persisted soft
lock means 72h of genuine idleness — the exact case AC2 requires to
force the full password re-auth. getAuthStatus now reports it as
HASH_KEY_EXPIRED (consuming the stale LOCKED marker), and the signIn
fast path refuses to re-stamp an expired key, falling through to the
full rebuild. Raised by Copilot on #993.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-Lock timer screen

5 participants