feat(auth): add biometric authentication support#897
Draft
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Implement biometric authentication (Face ID/Touch ID) for session protection following the Auth0 CredentialsManager pattern. Features include: - Configurable policies: .default, .always, .session(timeout:), .appLifecycle - Flat API: enableBiometrics(), disableBiometrics(), biometricsAvailability() - Automatic integration: session() automatically requires biometrics when enabled - Internal withBiometrics() helper for protecting sensitive operations - Full Swift 6/Sendable conformance - Platform support: iOS, macOS, tvOS, watchOS, visionOS Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add mock implementations for BiometricStorage and BiometricSession to support testing. Update test files to use conditional compilation for biometric dependencies. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Move all biometric-related files into Sources/Auth/Biometrics/ and extract AuthClient biometric extension into its own file for better organization. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The BiometricStorage.live() was eagerly loading settings during initialization, which accessed Dependencies before they were fully set up. Changed to lazy loading that defers settings retrieval until first access. Also added comprehensive tests for the biometrics feature covering: - BiometricStorage enable/disable with all policy types - BiometricSession recording, reset, and policy evaluation - BiometricAuthenticator mock behavior - withBiometrics helper function - AuthClient biometrics extension methods - BiometricError and BiometricPolicy types Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Created AppLifecycle enum in Internal/ that provides cross-platform notification names for app lifecycle events (active, resign active, background, foreground). This consolidates the platform-specific conditional compilation logic that was duplicated in AuthClient and BiometricSession. - AuthClient now uses AppLifecycle notification names with Combine - BiometricSession uses AppLifecycle.observeBackgroundTransitions() - Removed ~70 lines of duplicated platform-specific code Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removed 18 tests that were just testing mock implementations: - BiometricStorage.mock tests - BiometricSession inline mock tests - BiometricAuthenticator.mock tests Kept 17 tests that test real code: - withBiometrics function tests (with injected dependencies) - AuthClient extension tests (with injected dependencies) - BiometricError, BiometricPolicy, BiometricEvaluationPolicy type tests Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive biometrics examples to the Examples app: - BiometricsExample.swift: Standalone example demonstrating all biometrics features including availability check, policy configuration, session access testing, and enable/disable flows - ProfileView: Add biometrics configuration to the Security section, allowing users to enable/disable biometrics after login - AuthExamplesView: Add navigation link to biometrics example Also change BiometricPolicy from Equatable to Hashable for SwiftUI Picker compatibility. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove BIOMETRICS_ENABLED and BIOMETRICS_DISABLED events from AuthChangeEvent as biometric state changes are local-only and don't need to be part of the auth state change stream. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove redundant error cases from BiometricError and BiometricUnavailableReason: - Remove notEnabled from BiometricError (handled differently) - Remove biometryNotEnrolled, biometryLockout, other from BiometricUnavailableReason (these are covered by notAvailable or other error paths) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove tests for removed error cases to match the simplified BiometricError and BiometricUnavailableReason enums. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
cfd5f44 to
92821b3
Compare
Contributor
|
This caught my eye and is a valued addition. This made it much easier to implement stable Face ID authentication in my iOS app using the Supabase-swift SDK. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add biometric authentication (Face ID/Touch ID) support to the Auth module. Features include configurable policies (.default, .always, .session(timeout:), .appLifecycle), automatic integration with session retrieval, and full Swift 6/Sendable conformance.
Usage
Policies:
.default- Authenticate on first access only.always- Authenticate every time.session(timeoutInSeconds:)- Authenticate after timeout expires.appLifecycle- Authenticate when returning from backgroundChanges
Test Plan
🤖 Generated with Claude Code