Skip to content

Conversation

@russellwheatley
Copy link
Member

@russellwheatley russellwheatley commented Nov 21, 2025

Closes #741

After pressing "delete account" (I trimmed about 1 minute of initial part of video because I left a debugger on which stopped alert popping up immediately):

email-link-reauth.mp4

Email Link Reauthentication Support

Overview

Adds comprehensive email link reauthentication support, allowing users who signed in with email link (passwordless) to reauthenticate for sensitive operations without needing to remember or set a password.


AuthService API Changes

Modified Methods

sendEmailSignInLink(email:isReauth:)

  • Added optional isReauth: Bool = false parameter
  • When isReauth: true, stores email for reauthentication flow instead of sign-in
  • Backward compatible (defaults to false for existing sign-in behavior)

handleSignInLink(url:)

  • Now automatically routes to either sign-in or reauthentication based on internal state
  • Determines flow using isReauthenticating flag
  • Single method handles both use cases without breaking changes

signOut()

  • Now clears email link reauthentication state (emailLinkReauth, isReauthenticating)

New Internal Properties

@AppStorage("is-email-link") private var isEmailLinkSignIn: Bool = false
@AppStorage("email-link-reauth") private var emailLinkReauth: String?
@AppStorage("is-reauthenticating") private var isReauthenticating: Bool = false

  • Tracks sign-in method to differentiate email/password from email link
  • Stores reauthentication context separately from sign-in context

AuthServiceError Changes

New Error Case

case emailLinkReauthenticationRequired(context: EmailLinkReauthContext)#### New Context Type

public struct EmailLinkReauthContext: Equatable {
  public let email: String
  public var displayMessage: String {
    "Please check your email to verify your identity"
  }
}

Updated Enum

public enum ReauthenticationType: Equatable {
  case oauth(OAuthReauthContext)
  case email(EmailReauthContext)
  case emailLink(EmailLinkReauthContext)  // New
  case phone(PhoneReauthContext)
}

Default Views Changes

New View

EmailLinkReauthView

  • Displays "Check Your Email" UI after sending verification link
  • Automatically sends email on appear
  • Includes "Resend Email" functionality
  • Handles incoming URL via .onOpenURL
  • Matches design pattern of EmailReauthView and PhoneReauthView

Updated Views

ReauthenticationCoordinator

  • Added showingEmailLinkReauth and showingEmailLinkReauthAlert state
  • Added confirmEmailLinkReauth() method
  • Routes .emailLink reauth context to appropriate UI

ReauthenticationModifier

  • Added alert for email link reauthentication confirmation
  • Added sheet presentation for EmailLinkReauthView
  • Alert message: "We'll send a verification link to [email]. Tap the link to continue."

ReauthenticationHelpers.swift

  • Updated withReauthenticationIfNeeded to handle emailLinkReauthenticationRequired error

Behavior

  1. Sign-in tracking: When user signs in with email link, isEmailLinkSignIn flag is set to true
  2. Reauthentication detection: When sensitive operation requires reauth, checks isEmailLinkSignIn flag
  3. Throws appropriate error: emailLinkReauthenticationRequired for email link users, emailReauthenticationRequired for email/password users
  4. Automatic flow: Default views automatically present alert → send email → show "Check Email" sheet → handle URL → complete operation
  5. Custom views: Developers can catch error and implement custom flow using existing methods with isReauth: true parameter

@russellwheatley russellwheatley merged commit 7dbf7a1 into development Nov 21, 2025
5 checks passed
@russellwheatley russellwheatley deleted the email-link-sign-in-reauth branch November 21, 2025 12:46
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