-
-
Notifications
You must be signed in to change notification settings - Fork 243
Add support for passkeys #1430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for passkeys #1430
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds comprehensive passkey authentication support to BookPlayer, allowing users to register and sign in without requiring an Apple ID. The implementation includes email verification, passkey creation/management, and Watch app credential transfer.
Changes:
- Added passkey authentication flow with email verification
- Implemented Watch app credential transfer from iPhone
- Extended networking layer with PATCH method and enhanced error handling
Reviewed changes
Copilot reviewed 55 out of 56 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| PasskeyModels.swift | New models for passkey authentication, email verification, and credential management |
| PasskeyService.swift | Core passkey service implementing registration and authentication using AuthenticationServices |
| PasskeyAPI.swift | API endpoints for passkey operations |
| AccountService.swift | Added passkey login handling and credential transfer methods |
| NetworkClient.swift | Enhanced error handling with error codes and ISO8601 date decoding |
| NetworkUtils.swift | Added PATCH HTTP method support |
| WatchConnectivityService.swift | Added auth transfer request from Watch to iPhone |
| PhoneWatchConnectivityService.swift | Handles auth transfer requests from Watch |
| PasskeyRegistrationView.swift | UI flow for passkey registration with email verification |
| EmailVerificationView.swift | Email verification code input screen |
| LoginView.swift | Updated to include passkey registration option |
| AccountPasskeySectionView.swift | Account settings section for managing passkeys |
| PrimaryButton.swift | Reusable primary button component |
| Localizable.strings (all languages) | New localization strings for passkey features |
| BookPlayer.entitlements | Added associated domains for webcredentials |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let email = accountService.getAccount()?.email | ||
| try await passkeyService.addPasskeyToAccount(deviceName: deviceName, email: email!) |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Force unwrapping the email with '!' is unsafe. If the account's email is nil, this will crash the app. Consider adding proper error handling or using optional binding to safely unwrap the email value.
| let email = accountService.getAccount()?.email | |
| try await passkeyService.addPasskeyToAccount(deviceName: deviceName, email: email!) | |
| guard let email = accountService.getAccount()?.email else { | |
| return | |
| } | |
| try await passkeyService.addPasskeyToAccount(deviceName: deviceName, email: email) |
| let registrationRequest = platformProvider.createCredentialRegistrationRequest( | ||
| challenge: challengeData, | ||
| name: userName, | ||
| userID: userId.data(using: .utf8)! |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Force unwrapping 'userId.data(using: .utf8)' is unsafe. While UTF-8 encoding rarely fails for valid strings, this could theoretically crash if the string contains invalid characters. Consider using optional binding or providing a fallback value.
| guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, | ||
| let window = windowScene.windows.first | ||
| else { | ||
| fatalError("No window available for passkey presentation") |
Copilot
AI
Jan 17, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using 'fatalError' in production code is problematic. If no window is available, the app will crash. Consider throwing an error instead or returning a default window, allowing for more graceful error handling.
| fatalError("No window available for passkey presentation") | |
| assertionFailure("No window available for passkey presentation; using a fallback window.") | |
| return UIWindow(frame: UIScreen.main.bounds) |
Purpose
This will allow registering for an account without the need of an apple id