|
| 1 | +# Magic Link Authentication for LIFT Frontend |
| 2 | + |
| 3 | +This document explains the Magic Link authentication workflow implemented in the LIFT frontend application, detailing the processes, components, and backend requirements. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Magic Link authentication is a passwordless authentication method where users receive a unique, time-limited URL (the "magic link") via email. Clicking this link authenticates the user without requiring them to remember or enter a password. This approach enhances security while simplifying the user experience. |
| 8 | + |
| 9 | +## Frontend Implementation |
| 10 | + |
| 11 | +### Components Structure |
| 12 | + |
| 13 | +The LIFT frontend uses the following components for Magic Link authentication: |
| 14 | + |
| 15 | +1. **AuthProvider** (`AuthProvider.tsx`) |
| 16 | + |
| 17 | + - Context provider that manages authentication state |
| 18 | + - Exposes methods for requesting magic links, verifying authentication, and signing out |
| 19 | + - Handles session persistence |
| 20 | + |
| 21 | +2. **AuthContext** (`AuthContext.ts`) |
| 22 | + |
| 23 | + - Defines the shape of authentication context |
| 24 | + - Provides access to authentication state and methods |
| 25 | + |
| 26 | +3. **MagicLinkForm** (`MagicLinkForm.tsx`) |
| 27 | + |
| 28 | + - UI component for requesting a magic link |
| 29 | + - Handles email validation |
| 30 | + - Shows success feedback to users |
| 31 | + |
| 32 | +4. **LoginPage** (`LoginPage.tsx`) |
| 33 | + |
| 34 | + - Container for the authentication flow |
| 35 | + - Handles token verification from URL |
| 36 | + - Implements profile completion after authentication |
| 37 | + |
| 38 | +5. **authApi.ts** |
| 39 | + |
| 40 | + - API client for interacting with the authentication endpoints |
| 41 | + - Implements both mock and real API services |
| 42 | + - Handles token verification logic |
| 43 | + |
| 44 | +6. **authUtils.ts** |
| 45 | + - Utility functions for extracting and verifying tokens from URL |
| 46 | + - Manages URL cleanup after verification |
| 47 | + |
| 48 | +### Authentication Flow |
| 49 | + |
| 50 | +The Magic Link authentication flow in the LIFT frontend consists of the following steps: |
| 51 | + |
| 52 | +1. **Request Magic Link** |
| 53 | + |
| 54 | + - User enters their email in the `MagicLinkForm` |
| 55 | + - Email is validated for format correctness |
| 56 | + - API request is sent to the backend via `requestMagicLink` function |
| 57 | + - User is shown confirmation that the email has been sent |
| 58 | + |
| 59 | +2. **Email Receipt and Link Click** |
| 60 | + |
| 61 | + - User receives the Magic Link email |
| 62 | + - Email contains a unique URL with a token parameter |
| 63 | + - User clicks the link, opening the application with the token in the URL |
| 64 | + |
| 65 | +3. **Token Verification** |
| 66 | + |
| 67 | + - `LoginPage` component detects the token in the URL |
| 68 | + - `handleMagicLinkVerification` function is called to verify the token |
| 69 | + - API request is sent to the backend via `verifyMagicLink` function |
| 70 | + - URL is cleaned up by removing the token |
| 71 | + |
| 72 | +4. **Authentication State Update** |
| 73 | + |
| 74 | + - Upon successful verification, `AuthProvider` updates the authentication state |
| 75 | + - User information is stored in the auth context |
| 76 | + - Components subscribed to the auth context are notified of the change |
| 77 | + |
| 78 | +5. **Profile Completion** |
| 79 | + |
| 80 | + - After authentication, user is prompted to complete their profile |
| 81 | + - Basic information is collected (name, manager's name) |
| 82 | + - Information is stored in the application state |
| 83 | + |
| 84 | +6. **Session Management** |
| 85 | + - Session is maintained through cookies (when using real API) |
| 86 | + - `AuthProvider` checks for existing sessions on load |
| 87 | + - Handles sign out process when requested |
| 88 | + |
| 89 | +## Backend Requirements |
| 90 | + |
| 91 | +For the Magic Link authentication to work with a real backend, the following API endpoints and behaviors are required: |
| 92 | + |
| 93 | +### 1. Request Magic Link Endpoint |
| 94 | + |
| 95 | +- **URL**: `/auth/signin/magic-link` |
| 96 | +- **Method**: POST |
| 97 | +- **Content-Type**: application/json |
| 98 | +- **Credentials**: include |
| 99 | +- **Request Body**: |
| 100 | + ```json |
| 101 | + { |
| 102 | + |
| 103 | + "callbackURL": "/" // Optional, path to redirect after authentication (root path in this app) |
| 104 | + } |
| 105 | + ``` |
| 106 | +- **Expected Response**: |
| 107 | + |
| 108 | + - Success: HTTP 200 with confirmation message |
| 109 | + - Error: Appropriate HTTP error code with message |
| 110 | + |
| 111 | +- **Backend Behavior**: |
| 112 | + - Generate a secure, time-limited token (typically 5-10 minutes) |
| 113 | + - Associate token with the provided email |
| 114 | + - Send an email to the user containing a link to the application with the token as a URL parameter |
| 115 | + - The email link should be formatted as: `https://your-app-url.com?token=GENERATED_TOKEN` |
| 116 | + - Note: While the frontend code uses `/main` in some places, the actual app structure routes to the root path `/` after authentication, as shown in the App.tsx component |
| 117 | + |
| 118 | +### 2. Verify Token Endpoint |
| 119 | + |
| 120 | +- **URL**: `/auth/verify` |
| 121 | +- **Method**: GET |
| 122 | +- **Content-Type**: application/json |
| 123 | +- **Credentials**: include |
| 124 | +- **Query Parameters**: |
| 125 | + - `token`: The token to verify |
| 126 | +- **Expected Response**: |
| 127 | + |
| 128 | + - Success: HTTP 200 with user data: |
| 129 | + ```json |
| 130 | + { |
| 131 | + "user": { |
| 132 | + "id": "user_id_string", |
| 133 | + |
| 134 | + "username": "optional_username" |
| 135 | + } |
| 136 | + } |
| 137 | + ``` |
| 138 | + - Error: Appropriate HTTP error code with message |
| 139 | + |
| 140 | +- **Backend Behavior**: |
| 141 | + - Validate the token (check expiration, integrity) |
| 142 | + - If valid, create or retrieve the user associated with the email |
| 143 | + - Set authentication cookies or session information |
| 144 | + - Return user data |
| 145 | + |
| 146 | +### 3. Get Current User Endpoint |
| 147 | + |
| 148 | +- **URL**: `/auth/user` |
| 149 | +- **Method**: GET |
| 150 | +- **Content-Type**: application/json |
| 151 | +- **Credentials**: include |
| 152 | +- **Expected Response**: |
| 153 | + |
| 154 | + - Success: HTTP 200 with user data: |
| 155 | + ```json |
| 156 | + { |
| 157 | + "user": { |
| 158 | + "id": "user_id_string", |
| 159 | + |
| 160 | + "username": "optional_username" |
| 161 | + } |
| 162 | + } |
| 163 | + ``` |
| 164 | + - Not authenticated: HTTP 401 or 404 |
| 165 | + |
| 166 | +- **Backend Behavior**: |
| 167 | + - Check for valid session or authentication cookies |
| 168 | + - If authenticated, return the current user's data |
| 169 | + - Otherwise, indicate that no user is authenticated |
| 170 | + |
| 171 | +### 4. Sign Out Endpoint |
| 172 | + |
| 173 | +- **URL**: `/auth/signout` |
| 174 | +- **Method**: POST |
| 175 | +- **Content-Type**: application/json |
| 176 | +- **Credentials**: include |
| 177 | +- **Expected Response**: |
| 178 | + |
| 179 | + - Success: HTTP 200 with confirmation |
| 180 | + - Error: Appropriate HTTP error code |
| 181 | + |
| 182 | +- **Backend Behavior**: |
| 183 | + - Clear authentication cookies or invalidate the session |
| 184 | + - Perform any necessary cleanup |
| 185 | + |
| 186 | +## Security Considerations |
| 187 | + |
| 188 | +1. **Token Security**: |
| 189 | + |
| 190 | + - Tokens should be cryptographically secure and time-limited (typically 5-10 minutes) |
| 191 | + - Tokens should be single-use and invalidated after use |
| 192 | + - Token validation should include protection against replay attacks |
| 193 | + |
| 194 | +2. **Email Security**: |
| 195 | + |
| 196 | + - Email sending should be configured with proper SPF, DKIM, and DMARC to prevent spoofing |
| 197 | + - Emails should clearly identify the sender and purpose |
| 198 | + |
| 199 | +3. **Session Management**: |
| 200 | + |
| 201 | + - Use secure, HTTP-only cookies for session management |
| 202 | + - Implement CSRF protection for API requests |
| 203 | + - Set appropriate expiration for sessions |
| 204 | + |
| 205 | +4. **Rate Limiting**: |
| 206 | + - Implement rate limiting on the magic link request endpoint to prevent abuse |
| 207 | + - Consider IP-based and email-based rate limiting |
| 208 | + |
| 209 | +## Development and Testing |
| 210 | + |
| 211 | +The LIFT frontend includes a mock authentication service for development purposes. To use it: |
| 212 | + |
| 213 | +1. Set the environment variable `VITE_USE_MOCK_AUTH=true` in your `.env.development` file |
| 214 | +2. When testing, any email will work for requesting a magic link |
| 215 | +3. The mock service simulates the entire authentication flow without requiring a backend |
| 216 | + |
| 217 | +## Troubleshooting |
| 218 | + |
| 219 | +Common issues with Magic Link authentication: |
| 220 | + |
| 221 | +1. **Magic link emails not receiving**: Check spam folders, email deliverability settings |
| 222 | +2. **Token expiration**: Ensure users know tokens expire quickly and may need to request a new one |
| 223 | +3. **Cross-device usage**: If a user opens the magic link on a different device than requested, ensure the auth state is properly managed |
| 224 | + |
| 225 | +## Conclusion |
| 226 | + |
| 227 | +Magic Link authentication provides a secure and user-friendly authentication method for the LIFT application. The passwordless approach removes friction from the login process while maintaining high security standards. |
| 228 | + |
| 229 | +When implementing a backend for this system, ensure all the required endpoints are properly secured and follow the expected request/response formats described in this document. |
0 commit comments