From 06e3ea48fb4aba7bf45189dbd4c25cde257341a6 Mon Sep 17 00:00:00 2001 From: Dani B Date: Wed, 28 Jan 2026 09:14:37 -0500 Subject: [PATCH] feat(01-02): create AuthRepository interface - Abstract AuthRepository class defines all authentication operations - Core methods: signUp, signIn, signOut, resetPassword, getCurrentUser - Stream-based auth state changes with authStateChanges() - Profile management: updateProfile, sendEmailVerification - Security features: changePassword, deleteAccount, refreshSession - OAuth support: signInWithOAuth, signInAnonymously - Comprehensive documentation with exception specifications --- .../domain/repositories/auth_repository.dart | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 lib/features/authentication/domain/repositories/auth_repository.dart diff --git a/lib/features/authentication/domain/repositories/auth_repository.dart b/lib/features/authentication/domain/repositories/auth_repository.dart new file mode 100644 index 0000000..c097659 --- /dev/null +++ b/lib/features/authentication/domain/repositories/auth_repository.dart @@ -0,0 +1,185 @@ +import '../../data/models/auth_user.dart'; +import '../../../core/errors/auth_exceptions.dart'; + +/// Authentication repository interface defining all authentication operations. +/// +/// This abstract class provides a clean interface for authentication operations +/// following clean architecture principles. It abstracts away the implementation +/// details of the authentication provider (Supabase) while providing a +/// consistent API for the rest of the application. +/// +/// Implementations should handle all authentication state management, +/// error scenarios, and session persistence automatically. +abstract class AuthRepository { + /// Registers a new user with email and password + /// + /// [email] - User's email address for registration + /// [password] - User's password for registration + /// + /// Returns the newly created [AuthUser] on successful registration + /// + /// Throws: + /// - [EmailAlreadyInUseException] if email is already registered + /// - [WeakPasswordException] if password doesn't meet requirements + /// - [NetworkException] if network connection fails + /// - [AuthException] for other authentication errors + Future signUp(String email, String password); + + /// Signs in an existing user with email and password + /// + /// [email] - User's email address + /// [password] - User's password + /// + /// Returns the authenticated [AuthUser] on successful sign in + /// + /// Throws: + /// - [InvalidCredentialsException] if email or password is incorrect + /// - [UserNotFoundException] if user doesn't exist + /// - [EmailNotVerifiedException] if user's email is not verified + /// - [NetworkException] if network connection fails + /// - [SessionExpiredException] if session cannot be established + /// - [AuthException] for other authentication errors + Future signIn(String email, String password); + + /// Signs out the currently authenticated user + /// + /// Clears the current session and updates the authentication state + /// + /// Throws: + /// - [NetworkException] if network connection fails + /// - [AuthException] if sign out fails for other reasons + Future signOut(); + + /// Sends a password reset email to the user + /// + /// [email] - User's email address for password reset + /// + /// Throws: + /// - [UserNotFoundException] if user doesn't exist + /// - [NetworkException] if network connection fails + /// - [TooManyRequestsException] if too many reset attempts + /// - [AuthException] for other authentication errors + Future resetPassword(String email); + + /// Gets the currently authenticated user + /// + /// Returns the current [AuthUser] if authenticated, null otherwise + /// + /// This method should not throw exceptions for normal authentication state + /// (like no user being signed in), but may throw for critical errors + /// + /// Throws: + /// - [NetworkException] if network connection fails + /// - [AuthException] for critical authentication system errors + Future getCurrentUser(); + + /// Stream of authentication state changes + /// + /// Emits the current [AuthUser] when authentication state changes: + /// - User signs in (emits AuthUser) + /// - User signs out (emits null) + /// - Session refreshes (emits updated AuthUser) + /// - Email verification status changes (emits updated AuthUser) + /// + /// The stream should emit the current state immediately upon subscription + /// + /// Throws: + /// - [NetworkException] if network connection fails + /// - [AuthException] for critical authentication system errors + Stream authStateChanges(); + + /// Refreshes the current authentication session + /// + /// Useful for updating user data or extending session lifetime + /// + /// Returns the updated [AuthUser] on successful refresh + /// + /// Throws: + /// - [SessionExpiredException] if session cannot be refreshed + /// - [NetworkException] if network connection fails + /// - [AuthException] for other authentication errors + Future refreshSession(); + + /// Updates the user's profile information + /// + /// [displayName] - Optional new display name for the user + /// [avatarUrl] - Optional new avatar URL for the user + /// + /// Returns the updated [AuthUser] on successful update + /// + /// Throws: + /// - [SessionExpiredException] if user is not authenticated + /// - [NetworkException] if network connection fails + /// - [AuthException] for other authentication errors + Future updateProfile({ + String? displayName, + String? avatarUrl, + }); + + /// Sends an email verification email to the current user + /// + /// Throws: + /// - [SessionExpiredException] if user is not authenticated + /// - [EmailAlreadyInUseException] if email is already verified + /// - [NetworkException] if network connection fails + /// - [TooManyRequestsException] if too many verification attempts + /// - [AuthException] for other authentication errors + Future sendEmailVerification(); + + /// Changes the user's password + /// + /// [currentPassword] - User's current password for verification + /// [newPassword] - User's new password + /// + /// Throws: + /// - [InvalidCredentialsException] if current password is incorrect + /// - [WeakPasswordException] if new password doesn't meet requirements + /// - [SessionExpiredException] if user is not authenticated + /// - [NetworkException] if network connection fails + /// - [AuthException] for other authentication errors + Future changePassword(String currentPassword, String newPassword); + + /// Deletes the user's account and all associated data + /// + /// This is a destructive operation and cannot be undone + /// + /// Throws: + /// - [SessionExpiredException] if user is not authenticated + /// - [NetworkException] if network connection fails + /// - [AuthException] for other authentication errors + Future deleteAccount(); + + /// Checks if the current user's email is verified + /// + /// Returns true if email is verified, false otherwise + /// + /// Returns null if user is not authenticated + /// + /// Throws: + /// - [NetworkException] if network connection fails + /// - [AuthException] for critical authentication system errors + Future isEmailVerified(); + + /// Signs in with an OAuth provider + /// + /// [provider] - The OAuth provider (e.g., 'google', 'github', 'apple') + /// + /// Returns the authenticated [AuthUser] on successful sign in + /// + /// Throws: + /// - [NetworkException] if network connection fails + /// - [AuthException] for other authentication errors + Future signInWithOAuth(String provider); + + /// Signs in anonymously (as a guest user) + /// + /// Creates an anonymous user session that can be upgraded to a full account later + /// + /// Returns the anonymous [AuthUser] on successful sign in + /// + /// Throws: + /// - [NetworkException] if network connection fails + /// - [AuthDisabledException] if anonymous sign in is disabled + /// - [AuthException] for other authentication errors + Future signInAnonymously(); +} \ No newline at end of file