Skip to content

Biometric auth by Claude#718

Open
softartdev wants to merge 11 commits intodevfrom
claude/biometric-authentication-mzvIQ
Open

Biometric auth by Claude#718
softartdev wants to merge 11 commits intodevfrom
claude/biometric-authentication-mzvIQ

Conversation

@softartdev
Copy link
Copy Markdown
Owner

@softartdev softartdev commented Apr 27, 2026

Summary
This Pull Request (PR) reorganizes and renames several modules and files in the project, introduces biometric authentication capabilities, adjusts resources for internationalization, and updates dependencies.
Main Changes
Module Renaming and Reorganization:
ui:shared renamed to core:ui.
ui:test renamed to core:test:ui.
ui:test-jvm renamed to core:test:jvm.
core:test renamed to core:test:common.
Biometric Authentication Implementation:
Added multiplatform support for biometric encryption and decryption.
Created platform-specific implementations for Android and iOS in the BiometricInteractor.
Integrated biometric sign-in into the app, including enabling/disabling biometric options in Settings and sign-in screens.
Code Refactoring:
Updated resources, test tags, and paths to match the renamed modules.
Adjusted Koin modules in uiModules to support the new biometric feature.
Resource Updates:
New strings for biometric-related features in English and Russian.
Adjustments to existing localized strings for usability.
Testing Enhancements:
Added test cases for biometric sign-in scenarios.
Updated multiplatform test structure to align with the renamed test modules.
Dependency Updates:
Minor version upgrades for several dependencies, including Kotlin and Compose-related libraries.
Introduced androidx.biometric to support biometric authentication.

Adds biometric sign-in (Touch ID / Face ID on iOS, BiometricPrompt on
Android) for unlocking the SQLCipher-encrypted database. Users enable it
from Settings; on next launch the SignIn screen offers a "Use biometric"
button that retrieves the password from OS-secured storage after a
successful biometric prompt.

Architecture:
- Common: expect class BiometricInteractor with BiometricResult /
  DecryptedPasswordResult sealed types (mirrors LocaleInteractor's
  expect/actual pattern in core/presentation).
- Android: BiometricPrompt + Android Keystore. Password is encrypted
  with an AES-GCM key marked setUserAuthenticationRequired(true) and
  setInvalidatedByBiometricEnrollment(true), then stored in plain
  SharedPreferences. Cipher is unlocked via BiometricPrompt.CryptoObject
  so decryption literally requires a fresh biometric scan. MainActivity
  attaches itself to a small BiometricActivityHolder for prompt access.
- iOS: LAContext + Keychain Services with kSecAccessControlBiometryCurrentSet
  on a generic-password Keychain item. Item invalidates on biometric
  re-enrollment.
- JVM/Web get no-op stubs so the multiplatform build stays green.

Settings flow: a ChangeBiometric(true) action navigates to the new
BiometricEnrollDialog where the user re-types the password, then
encryptAndStorePassword runs the biometric prompt. Disabling clears the
stored ciphertext. Whenever the DB password changes via Change/Enter/
Confirm ViewModels, any stored biometric password is cleared and a
snackbar tells the user to re-enable in Settings.

Tests: SignInViewModelTest gets two new biometric paths; existing
ViewModel tests are updated to pass the new mock BiometricInteractor.

https://claude.ai/code/session_01AHoV8HEQJ86WRccDv4i6hK
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@softartdev softartdev changed the base branch from master to dev April 28, 2026 09:05
@softartdev softartdev changed the title Bump faraday from 1.10.3 to 1.10.5 in /app/iosApp Biometric auth by Claude Apr 28, 2026
softartdev and others added 10 commits April 28, 2026 17:29
…ntations

- Refactor `BiometricInteractor` on iOS to improve type safety with explicit `CFTypeRef` and `OSStatus` handling, and simplify `memScoped` logic.
- Update `BiometricInteractor` on Android to utilize `SharedPreferences.edit` KTX extension, add detailed logging for Keystore failures, and refactor cipher initialization.
- Optimize `BiometricEnrollViewModel` state updates to use single `update` blocks and named arguments for better readability.
- Simplify `SignInScreen` and `BiometricEnrollDialog` by resolving string resources directly within the UI components and streamlining action passing.
- Switch iOS project configuration from manual to automatic code signing and remove platform-specific development team overrides.
- Refactor Android Koin dependency injection to use `singleOf` for `BiometricInteractor`.
- Add documentation/TODOs regarding the removal of Compose-specific `AutofillManager` dependencies from presentation ViewModels.
- Clean up unused methods, such as `BiometricEnrollResult.hideError()`, and improve formatting across the presentation and UI modules.
- Update iOS user interface state and workspace configuration.
- Refactor `BiometricInteractor` on Android to use `Application.ActivityLifecycleCallbacks` for automatic activity tracking, eliminating the manual `BiometricActivityHolder`.
- Consolidate `SignInViewModel` UI state into a single `SignInResult` data class, replacing separate flows for result and visibility with atomic state updates.
- Update `SignInScreen` and related tests to utilize the unified state model.
- Downgrade `androidx.biometric` to `1.1.0` for stability and set `minSdk` to 23 in `CONTRIBUTING.md`.
- Add `USE_FINGERPRINT` permission to `AndroidManifest.xml` and remove manual `configChanges` handling for `MainActivity`.
- Expand `CONTRIBUTING.md` with detailed coding standards for named arguments, state management, and Composable patterns.
- Switch iOS project configuration to use automatic code signing.
- Ensure `BiometricInteractor` operations are explicitly dispatched to the main thread when interacting with UI components.
- Refactor `SignInResult` from a data class with an enum-based state to a sealed interface hierarchy for improved type safety and state handling.
- Update `SignInViewModel` and `SignInScreen` to utilize the new sealed structure and implement a `setState` helper for atomic updates.
- Extract `CurrentActivityProvider` into a standalone internal class, utilizing `WeakReference` to prevent potential memory leaks of the host `FragmentActivity`.
- Enhance error handling in `BiometricEnrollViewModel` to extract and display specific error messages from `BiometricResult`.
- Remove the deprecated `USE_FINGERPRINT` permission from the Android manifest.
- Introduce a `dispose()` method in `BiometricInteractor` for explicit lifecycle management and cleaner test execution.
- Update `SignInViewModelTest` to align assertions with the new sealed state model.
- Refactor `SignInResult` from a sealed interface to a data class containing a nested `State` interface. This separates the primary UI state (Form, Progress, Error) from the `biometricVisible` flag.
- Update `SignInViewModel` to use `MutableStateFlow.update()` for state transitions, ensuring atomic updates to the sign-in state and biometric visibility.
- Adjust `SignInScreen` and `SignInViewModelTest` to access the nested state property within the new `SignInResult` model.
- Enhance `CurrentActivityProvider` to capture `FragmentActivity` references during `onActivityCreated` and `onActivityStarted`, in addition to `onActivityResumed`.
- Modify `CurrentActivityProvider` to only clear the activity reference during `onActivityDestroyed`, ensuring a stable host for components like `BiometricPrompt` during transient lifecycle changes.
- Remove the internal helper `setState` function in `SignInViewModel` in favor of standard `StateFlow` update patterns.
Move BiometricInteractor (expect/actuals), BiometricResult, DecryptedPasswordResult,
and CurrentActivityProvider to feature:biometric:domain; move BiometricEnrollViewModel,
BiometricEnrollResult, and BiometricEnrollAction to feature:biometric:presentation.
Update core:presentation and core:ui build files and module READMEs accordingly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…spend

- Replace `SharedPreferences` with `androidx.datastore.preferences` in `BiometricInteractor.android.kt` for more robust data handling.
- Update `hasStoredPassword()` and `clearStoredPassword()` to `suspend` functions across common and platform-specific implementations.
- Add `androidx.datastore` dependency to `libs.versions.toml` and include it in the `biometric:domain` module.
- Update `SettingsViewModelTest`, `ChangeViewModelTest`, `ConfirmViewModelTest`, and `EnterViewModelTest` to handle the new `suspend` method signatures.
- Enhance error logging in `SignInViewModel` to capture specific `BiometricResult.Error` messages.
- Update `SignInScreen` Compose preview to include the `biometricVisible` parameter.
- Replace `CurrentActivityProvider` with a Compose-friendly `BiometricPlatformWrapper` pattern to provide the Android host `FragmentActivity`.
- Introduce `rememberBiometricPlatformWrapper()` expect/actual function to capture the platform host context from the UI layer.
- Refactor `BiometricInteractor` to accept `BiometricPlatformWrapper` in encryption and decryption methods.
- Introduce `BiometricCredentialsStore` on Android to encapsulate DataStore Preferences logic for storing encrypted credentials.
- Refine `DecryptedPasswordResult` domain model to explicitly distinguish between `Cancelled`, `Unavailable`, and `Failure` states.
- Update `SignInViewModel` and `BiometricEnrollViewModel` to handle the new platform wrapper and result states.
- Refactor `SignInViewModel` to utilize `SnackbarInteractor` for displaying biometric authentication errors.
- Update project documentation to reflect the new two-layer protection architecture (Android Keystore + DataStore) and the activity provider pattern.
- Update unit tests for `SignInViewModel` to reflect dependency and action changes.
…ion handling

- Update `SignInAction.OnBiometricClick` and `BiometricEnrollAction.OnEnrollClick` to require a non-nullable `BiometricPlatformWrapper`.
- Remove redundant null checks and logging for `BiometricPlatformWrapper` in `SignInViewModel` and `BiometricEnrollViewModel`.
- Refactor `SignInScreen` and `BiometricEnrollDialog` to instantiate the biometric wrapper locally and pass it directly through the UI action flow.
- Simplify the Android implementation of `rememberBiometricPlatformWrapper` using a direct cast to `FragmentActivity`.
- Clean up `onAction` lambda references in the UI layer by using function references where possible.
- Update `rememberBiometricPlatformWrapper` to use the `remember` composable across all platforms (Android, JVM, iOS, and WasmJs).
- Prevent unnecessary re-instantiation of `BiometricPlatformWrapper` during recompositions.
- Key the `remember` block on Android using the current `FragmentActivity` to ensure the wrapper stays in sync with the host activity.
- Add biometric authentication status to the platform feature compatibility table.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants