import 'package:moneymgr_mobile/services/api/api_client.dart'; import 'package:moneymgr_mobile/services/api/api_token.dart'; import 'package:moneymgr_mobile/services/api/auth_api.dart'; import 'package:moneymgr_mobile/services/storage/secure_storage.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../services/router/routes_list.dart'; part 'auth_state.g.dart'; /// The current authentication state of the app. /// /// This notifier is responsible for saving/removing the token and profile info /// to the storage through the [setAuthToken] and [logout] methods. @riverpod class CurrentAuthState extends _$CurrentAuthState { @override AuthState build() { final secureStorage = ref.watch(secureStorageProvider).requireValue; final token = secureStorage.token(); return token != null ? AuthState.authenticated : AuthState.unauthenticated; } /// Attempts to authenticate with [token] and saves the token and profile info to storage. /// Will invalidate the state if success and throw an exception in case of failure Future setAuthToken(ApiToken token) async { // Attempt to use provided token await ApiClient(token: token).authInfo(); final secureStorage = ref.read(secureStorageProvider).requireValue; await secureStorage.setToken(token); ref // Invalidate the state so the auth state will be updated to authenticated. .invalidateSelf(); } /// Logs out, deletes the saved token and profile info from storage, and invalidates /// the state. void logout() { // TODO : implement logic /*final secureStorage = ref.read(secureStorageProvider).requireValue; // Delete the current [token] and [profile] from secure storage. secureStorage.remove('token'); ref // Invalidate the state so the auth state will be updated to unauthenticated. ..invalidateSelf() // Invalidate the token provider so the API service will no longer use the // previous token. ..invalidate(tokenProvider);*/ } } /// The possible authentication states of the app. enum AuthState { unknown(redirectPath: homePage, allowedPaths: [homePage]), unauthenticated( redirectPath: authPage, allowedPaths: [authPage, manualAuthPage, settingsPage], ), authenticated( redirectPath: homePage, allowedPaths: null, forbiddenPaths: [authPage, manualAuthPage], ); const AuthState({ required this.redirectPath, required this.allowedPaths, this.forbiddenPaths, }); /// The target path to redirect when the current route is not allowed in this /// auth state. final String redirectPath; /// List of paths allowed when the app is in this auth state. May be set to null if there is no /// restriction applicable final List? allowedPaths; /// List of paths not allowed when the app is in this auth state. May be set to null if there is no /// restriction applicable final List? forbiddenPaths; }