Implement session persistence and retrieval in AuthService
epic-email-password-login-auth-logic-task-004 — Add getSession() and restoreSession() methods to AuthService. On successful sign-in, persist session tokens via the AuthRepository. On app launch, attempt silent session restoration from secure storage before showing the login screen. Ensures peer mentors are not prompted to log in between consecutive activity registration sessions.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 3 - 413 tasks
Can start after Tier 2 completes
Implementation Notes
Supabase Flutter SDK v2+ has built-in session persistence via supabase.auth.onAuthStateChange stream — check if this already handles token storage before reimplementing. If the SDK persists tokens internally, AuthRepository only needs to subscribe to onAuthStateChange and expose the current session as a Riverpod stream. Avoid duplicating storage logic if Supabase handles it. For the restoreSession path: use a GoRouter redirect or a top-level Consumer that listens to sessionStateProvider.
On iOS, test with a device lock/unlock cycle to confirm keychain accessibility settings work correctly. Add a //TODO comment if Supabase SDK storage behavior changes in a future version.
Testing Requirements
Unit tests with mocked FlutterSecureStorage and MockSupabaseClient: (1) Verify signIn success triggers a write to secure storage with correct keys. (2) Verify restoreSession() reads tokens and calls supabase.auth.recoverSession(). (3) Verify restoreSession() returns false when storage is empty. (4) Verify restoreSession() returns false when recoverSession throws (expired token).
(5) Verify signOut() deletes all auth keys from secure storage. Widget test: confirm app shows home screen (not login) when restoreSession() returns true. Use flutter_test, mocktail.
Supabase GoTrue returns HTTP error codes and string messages that may change between SDK versions. Incorrect or incomplete mapping could cause the wrong user-facing message to be shown (e.g., showing a generic error instead of a specific credential error), violating the plain-language feedback acceptance criteria and potentially exposing security-sensitive information.
Mitigation & Contingency
Mitigation: Pin the supabase_flutter SDK to a specific minor version in pubspec.yaml. Write integration tests that mock the Supabase HTTP layer and assert each error code maps to the correct domain exception. Document the mapping table as a constant in AuthService.
Contingency: If an unrecognized error code is received at runtime, catch it as an UnknownAuthException and display a generic safe message. Alert via crash reporting for triage and SDK update.
If the user taps the sign-in button multiple times rapidly, concurrent authentication requests could result in race conditions: duplicate network calls, out-of-order state emissions, or multiple session tokens being written to secure storage.
Mitigation & Contingency
Mitigation: Use bloc concurrency transformer (droppable or restartable) to ensure only one authentication event is processed at a time. The BLoC should guard against submission while in LoginLoading state.
Contingency: Add a UI-level disable on the submit button when loading state is active as a secondary guard independent of BLoC concurrency control.