Features

Authentication Flow

Authentication Flow Documentation

Overview

The authentication flow in ShipThatApp provides multiple methods for user authentication, including email and password login, magic link, and Sign in with Apple. The flow is managed primarily by the AuthManager class, which interfaces with the GoTrue authentication service. The app also utilizes SignInViewModel to handle form validation and provide feedback to users during the authentication process.

AuthManager Service

AuthManager is the single source of truth for authentication-related activities in the application. It is implemented as a singleton instance, ensuring there's one consistent state of authentication across the application.

Initialization

AuthManager is initialized with the required parameters for the GoTrue service:

let client = SupabaseClient(supabaseURL: URL(string: "<YOUR_SUPABASE_URL>")!, supabaseKey: "<YOUR_SUPABASE_KEY>")

Replace <YOUR_SUPABASE_URL> and <YOUR_SUPABASE_KEY> with your Supabase project credentials.

Registration (Sign Up)

Method: registerNewUserWithEmail(email: String, password: String) async throws -> AppUser

This method allows registering a new user with an email and password. On a successful registration, a new user session is returned.

Email and Password Login

Method: signInWithEmail(email: String, password: String) async throws -> AppUser

This method allows users to sign in using an email and a password. It throws an error if sign-in fails.

Method: sendMagicLink(email: String) async throws

This method sends a magic link to the provided email. Users can then sign in by clicking the link without the need for a password.

Sign in with Apple

Method: signInWithApple(idToken: String) async throws -> AppUser

For Apple's authentication integration, this method signs in the user using a token received from the Apple sign-in process.

User Session Management

  • Method: getCurrentSession() async throws -> AppUser

    Fetches the current session from the client (if any) and updates the currentSession property.

  • Method: getSessionFromUrl(url: URL) async throws -> AppUser

    Handles the URL callback after a magic link sign-in and extracts the user session details from it.

  • Method: updateCurrentSession() async

    Called upon app launch or when the authentication state is likely to have changed. It ensures the currentSession property reflects the most current user session.

Signing Out

Method: signOut() async throws

Signs out the user by invalidating the current session and resetting the currentSession property to nil.

SignInViewModel

SignInViewModel handles the UI logic for signing in. It uses the form methods provided by AuthManager and presents the relevant form state to the user.

Properties

  • errorText: A string that stores the error message to be displayed if the form validation fails.

Methods

  • isFormValid(email: String, password: String) -> Bool: Validates the login form inputs based on email and password strength criteria.
  • registerNewUserWithEmail(email: String, password: String) async throws -> AppUser: Calls the registerNewUserWithEmail method from AuthManager.
  • sendMagicLink(email: String) async throws: Calls the sendMagicLink method from AuthManager.
  • signInWithEmail(email: String, password: String) async throws -> AppUser: Calls the signInWithEmail method from AuthManager.

Authentication Flow in User Interface

SignInView

Displays the primary sign-in interface that allows users to use Apple sign-in or choose other sign-in options (email/password login or magic link).

Users attempting to sign in with Apple are processed through AppleButton, a view component that handles interaction with Apple's authentication system.

SignInOptions

A separate view for users selecting email/password or magic link. It communicates with SignInViewModel to process user input and call the respective authentication methods.

RegistrationView

For new user registration, this view captures user details such as email and password and interacts with SignInViewModel to perform the sign-up process.

The app implements extensions for SwiftUI's View and String, adding useful methods such as .isValidEmail() to perform input validations more effectively.

Event Handling

The auth flow includes handling for deep-link events, triggered by the magic link flow. The magic link authentication is handled using .onOpenURL within LandingView:

.onOpenURL { incomingURL in
    handleIncomingURL(incomingURL)
}

The modifier observes the application for any URL schemes that are directed to the app. When ShipThatApp is opened via a URL that matches the app's URL scheme, the link is passed to the handleIncomingURL method.

  1. Magic Link Generation: When invoking sendMagicLink, AuthManager generates a URL with a unique token and sends it to the user's email. This URL contains a callback to the app's custom URL scheme, which may look something like: shipthatapp://login-callback?token=unique_token.

  2. User Interaction: The user receives an email with the magic link and upon clicking it, the default browser attempts to open the associated URL.

  3. URL Scheme Matching: If the app's URL scheme is correctly configured in the app's Info.plist file, iOS recognizes the scheme and launches the app, passing the URL to the .onOpenURL modifier.

  4. Handling the URL: a. The URL is checked within the handleIncomingURL method to confirm it's a valid login callback. b. If valid, the unique token from the URL is used to authenticate the user. c. The handleIncomingURL method internally calls getSessionFromUrl(url:) in AuthManager which communicates with the GoTrue service, validating the token and creating a new session.

  5. Session Establishment: Once the token is validated and the session is created, the currentSession in AuthManager is updated with the user's session information. The app then handles this updated state to display appropriate content to the user (for instance, transitioning to a user's home screen).

Security Considerations

  • The URL handling process should securely validate the incoming URL to ensure it's expected and originates from a trusted source.
  • Tokens embedded within magic link URLs should be securely generated and short-lived to reduce the risk of token capture and replay attacks.

Application Configuration

  • The custom URL scheme needs to be registered in the app's Info.plist under the CFBundleURLTypes key.
Previous
Splash Screen