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.
Passwordless (Magic Link) Login
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 theregisterNewUserWithEmail
method fromAuthManager
.sendMagicLink(email: String) async throws
: Calls thesendMagicLink
method fromAuthManager
.signInWithEmail(email: String, password: String) async throws -> AppUser
: Calls thesignInWithEmail
method fromAuthManager
.
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.
Authentication Related Extensions and Events
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.
Magic Link Process
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
.User Interaction: The user receives an email with the magic link and upon clicking it, the default browser attempts to open the associated URL.
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.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. ThehandleIncomingURL
method internally callsgetSessionFromUrl(url:)
inAuthManager
which communicates with the GoTrue service, validating the token and creating a new session.Session Establishment: Once the token is validated and the session is created, the
currentSession
inAuthManager
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 theCFBundleURLTypes
key.