Skip to content

Conversation

@harsh62
Copy link
Member

@harsh62 harsh62 commented Nov 14, 2025

Issue #, if available:
#95

Description of changes:

This pull request introduces support for flexible authentication flows in the Authenticator component, allowing for multiple authentication factors and user-driven selection. It adds new steps and states to handle passkey creation, confirmation password, and factor selection, while refactoring the codebase to accommodate these new flows.

Authentication Flow & Factor Selection Enhancements:

  • Added a new AuthenticationFlow model (AuthenticationFlow.swift) and integrated it throughout the Authenticator and AuthenticatorState to support both password-only and user-choice authentication flows.
  • Introduced the AuthFactor model (AuthFactor.swift) representing various authentication factors (password, email OTP, SMS OTP, WebAuthn/passkey), with utilities for sorting, selection, and conversion to Amplify types.
  • Updated the AuthenticatorStep and Step enums to include new steps for selecting authentication factors, confirming password, prompting to create a passkey, and handling passkey creation.

View and State Integration:

  • Extended the Authenticator generic to accept new content views for sign-in factor selection, confirm password, passkey prompts, and passkey creation, and wired these into the main view logic.
  • Added a signInState property and updated view logic to support new sign-in flows and state transitions.

Internal State and Credentials:

  • Updated Credentials to track the currently selected authentication factor, enabling detection of changes and proper flow restarts.

Package Resource Handling:

  • Registered the Resources directory as a processed resource in the package manifest to support new assets if needed.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@harsh62 harsh62 requested a review from a team as a code owner November 14, 2025 13:13
@codecov
Copy link

codecov bot commented Nov 14, 2025

Codecov Report

❌ Patch coverage is 88.26087% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.67%. Comparing base (839cd90) to head (22c6c77).

Files with missing lines Patch % Lines
Sources/Authenticator/Models/Internal/Step.swift 0.00% 14 Missing ⚠️
.../Authenticator/States/AuthenticatorBaseState.swift 87.38% 14 Missing ⚠️
...henticator/States/PromptToCreatePasskeyState.swift 81.81% 8 Missing ⚠️
...enticator/States/SignInSelectAuthFactorState.swift 93.26% 7 Missing ⚠️
...ces/Authenticator/States/PasskeyCreatedState.swift 81.81% 6 Missing ⚠️
...henticator/States/SignInConfirmPasswordState.swift 89.28% 3 Missing ⚠️
Sources/Authenticator/Models/AuthFactor.swift 95.34% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #110      +/-   ##
==========================================
+ Coverage   44.39%   51.67%   +7.27%     
==========================================
  Files          44       50       +6     
  Lines        2462     2394      -68     
==========================================
+ Hits         1093     1237     +144     
+ Misses       1369     1157     -212     
Flag Coverage Δ
Authenticator 51.67% <88.26%> (+7.27%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@harsh62 harsh62 requested a review from Copilot December 4, 2025 19:16
Copilot finished reviewing on behalf of harsh62 December 4, 2025 19:18
Copy link

Copilot AI left a 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 pull request adds passwordless authentication support to the Authenticator library, introducing new authentication flows including WebAuthn/passkeys, email OTP, and SMS OTP as alternatives to traditional password-based authentication.

Key Changes

  • Adds support for multi-factor authentication selection with new SignInSelectAuthFactorView and related states
  • Implements dynamic password field visibility based on authentication flow (password-only vs. user-choice flows)
  • Introduces passkey creation prompts and management screens for WebAuthn support

Reviewed changes

Copilot reviewed 48 out of 55 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
SignInView.swift Updated to conditionally show password field based on authentication flow
SignInSelectAuthFactorView.swift New view for selecting authentication factors (password, email OTP, SMS OTP, WebAuthn)
TextField.swift, PasswordField.swift, PhoneNumberField.swift Fixed accessibility modifier application
AuthenticationService.swift Added @retroactive conformance to ObservableObject
SignInStateTests.swift Added comprehensive tests for password flow and auth factor translation
SignInSelectAuthFactorStateTests.swift New test suite for auth factor selection and re-selection flows
SignUpStateTests.swift Updated tests for authentication flow validation logic
MockAuthenticationService.swift Enhanced with multi-step flow support for passwordless testing
PasskeyPromptTests.swift, ContinueSignInWithFirstFactorSelectionTests.swift New UI tests for passkey flows

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

Comment on lines 66 to 71
using: { [weak state] value in
guard let state = state else { return nil }

// Password is always required when shown (both password flow and userChoice with password preferred)
return FieldValidators.required(value)
}
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

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

The validator closure captures state weakly with [weak state] but never checks if state is nil before using it. When state is nil, this returns nil instead of performing validation, which could allow invalid input.

Change to:

using: { [weak state] value in
    guard let state = state else { 
        // If state is deallocated, apply required validation as default
        return FieldValidators.required(value)
    }
    
    // Password is always required when shown
    return FieldValidators.required(value)
}

Copilot uses AI. Check for mistakes.
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.

1 participant