# Data Model: Update Authentication Flow for MFA with garth ## Key Entities ### GarthToken Secure authentication tokens (OAuth1 and OAuth2) used for Garmin Connect API access **Attributes:** - `id`: Unique identifier for the token record - `user_id`: Identifier of the user this token represents - `access_token`: The OAuth2 access token value - `refresh_token`: The OAuth2 refresh token value - `oauth1_token`: The OAuth1 token data (dictionary format as used by garth) - `token_type`: Type of token (usually "Bearer") - `expires_in`: Time until expiration in seconds - `scope`: Permissions associated with this token - `created_at`: Timestamp when token was created - `last_used_at`: Timestamp of last usage - `mfa_verified`: Boolean indicating if MFA was completed for this token session - `is_active`: Boolean indicating if token is currently valid/useable - `device_uuid`: UUID of the device where authentication originated (for security) **Relationships:** - Belongs to one User (via user_id foreign key) ### MFAChallenge Represents a multi-factor authentication request with type, expiration time, and validation status **Attributes:** - `id`: Unique identifier for the MFA challenge - `user_id`: Identifier of the user requesting authentication - `session_id`: Session identifier linking to the authentication attempt - `challenge_type`: Type of MFA challenge (push, sms, email) - `challenge_reference`: Reference identifier from Garmin's MFA service - `sent_to`: Destination where MFA was sent (phone number, email address) - `status`: Current status (pending, completed, expired, failed) - `attempts_count`: Number of attempts made to validate this challenge - `expires_at`: Timestamp when the challenge expires - `completed_at`: Timestamp when the challenge was completed (if applicable) - `created_at`: Timestamp when challenge was initiated ### UserSession Represents an authenticated user session with associated garth tokens and permissions **Attributes:** - `id`: Unique session identifier - `user_id`: Identifier of the authenticated user - `session_token`: Secure session token for internal use - `garth_token_id`: Reference to the associated GarthToken - `is_mfa_complete`: Boolean indicating if MFA has been completed for this session - `mfa_completed_at`: Timestamp when MFA was completed (if applicable) - `created_at`: Timestamp when the session was created - `last_activity_at`: Timestamp of last activity with this session - `expires_at`: Timestamp when the session expires - `ip_address`: IP address from which the session was created - `user_agent`: User agent string of the client that created the session **Relationships:** - Belongs to one User (via user_id foreign key) - References one GarthToken (via garth_token_id foreign key) ## Relationships 1. **User** 1 → * **GarthToken**: A user can have multiple tokens over time (rotation, refresh, etc.) 2. **User** 1 → * **MFAChallenge**: A user can have multiple MFA challenges (one per auth attempt) 3. **User** 1 → * **UserSession**: A user can have multiple concurrent sessions 4. **UserSession** 1 → 1 **GarthToken**: Each session is associated with one active token ## Validation Rules From Functional Requirements: - **FR-005**: garth tokens must be stored securely with appropriate encryption in CentralDB - **FR-006**: Tokens must be validated for existence and validity before reuse - **FR-007**: Expired tokens must be refreshed automatically when possible, or fail gracefully - **FR-008**: MFA challenges must have clear status and expiration times to prevent abuse - **FR-009**: MFA challenge types must be properly distinguished and handled ## State Transitions ### MFAChallenge Status Transitions - `pending` → `completed` (when correct MFA code is provided) - `pending` → `expired` (when challenge exceeds expiration time) - `pending` → `failed` (when too many incorrect attempts are made) - `completed` → `expired` (after successful authentication has been used sufficiently) ### UserSession States - Active session remains valid until `expires_at` timestamp - Session can be invalidated early by user logout or security monitoring - Session tokens should be invalidated when associated garth tokens are refreshed ## Security Considerations - GarthToken records should be encrypted at rest in the database - MFAChallenge attempts should be rate-limited to prevent brute force attacks - Session tokens should use cryptographically secure random generation - Token refresh mechanisms should follow OAuth2 best practices - Device identification should be used to detect suspicious authentication patterns