Skip to content

fix(android/security): allow device credential for the app lock - #730

Merged
farfromrefug merged 2 commits into
mainfrom
fix/681-biometric-device-credential
Sep 14, 2026
Merged

farfromrefug merged 2 commits into
mainfrom
fix/681-biometric-device-credential

Conversation

@farfromrefug

@farfromrefug farfromrefug commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Android devices secured with a PIN/pattern/password but no enrolled biometric could never enable the app lock: available() resolves { any: true, biometrics: false } there, and the old check only looked at biometrics/touch/face (iOS-only fields). Availability now comes from any.
  • verifyBiometric is called with pinFallback: true on Android, so the system prompt allows DEVICE_CREDENTIAL alongside BIOMETRIC_STRONG — without it the plugin also fails at keystore key generation (setUserAuthenticationRequired requires an enrolled biometric). Prompt title is now translated. iOS is untouched (it already uses LAPolicy.DeviceOwnerAuthentication).
  • Enabling the lock re-checks availability and surfaces a message when no screen lock is set up; the settings error handling no longer breaks on the plugin's non-string rejections, so the toggle explains itself instead of silently reverting.
  • The availability check can no longer take down service startup (it used to reject out of Promise.all in app.ts), and the startup lock check still runs when the lock is enabled.
  • Patches @nativescript/biometrics@1.3.1: authenticating with the device credential brings another activity to the front, the JS peer of the plugin's AuthenticationCallback gets collected, and onAuthenticationSucceeded then runs on a fresh peer with default fields — it took the crypto branch and crashed on a null CryptoObject (TypeError: cannot read property 'getCipher' of null, uncaught on the main thread). The patch tracks the pending call in module scope, keeps a reference to the callback and guards the null crypto object. Worth sending upstream.
  • Reworded biometric_lock_desc (English source only) — it advertised a "PIN code" that was never actually accepted.

Testing

eslint and yarn svelte-check clean (0 errors). No unit test possible — the service pulls the NativeScript runtime and the native plugin.

Manual Android check:

  1. PIN/password-only device, no fingerprint → toggle opens the system credential prompt and enables. Reported crash on credential success is what the plugin patch addresses — needs a re-run to confirm.
  2. Device with a fingerprint → prompt still accepts the fingerprint, PIN as fallback.
  3. Device with no screen lock → toggle reverts with an explanation, app startup unaffected.
  4. Lock + auto-lock on → background/foreground prompts again.

Refs #681

available() reports biometrics:false on a secure device with no enrolled biometric, so the
lock was reported unavailable and enabling it always failed with no feedback. Use `any`,
pass pinFallback so the prompt accepts the device credential, and surface the error when no
screen lock is set up.

Refs #681

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@farfromrefug farfromrefug added the bug Something isn't working label Sep 14, 2026
The JS peer of the plugin AuthenticationCallback gets collected while the device credential
UI is in front, so onAuthenticationSucceeded ran on a fresh peer with default fields: it
took the crypto branch and crashed on a null CryptoObject. Track the pending call in module
scope, keep a reference to the callback and guard the null crypto object.

Refs #681

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@farfromrefug
farfromrefug marked this pull request as ready for review September 14, 2026 16:14
@farfromrefug
farfromrefug merged commit 86beb14 into main Sep 14, 2026
1 check passed
@farfromrefug
farfromrefug deleted the fix/681-biometric-device-credential branch September 14, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant