Files
MoneyMgr/moneymgr_mobile/lib/providers/auth_state.dart
Pierre HUBERT 52bbcf708f
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
User can sign out of his account
2025-07-08 19:54:16 +02:00

90 lines
2.9 KiB
Dart

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/prefs.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<void> setAuthToken(ApiToken token) async {
// Attempt to use provided token
await ApiClient(
token: token,
prefs: await ref.watch(prefsProvider.future),
).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.
Future<void> logout() async {
final prefs = ref.read(prefsProvider).requireValue;
final secureStorage = ref.read(secureStorageProvider).requireValue;
await secureStorage.removeToken();
prefs.clearServerConfig();
prefs.clearAuthInfo();
ref
// Invalidate the state so the auth state will be updated to authenticated.
.invalidateSelf();
}
}
/// The possible authentication states of the app.
enum AuthState {
unknown(redirectPath: homePage, allowedPaths: [homePage]),
unauthenticated(
redirectPath: authPage,
allowedPaths: [authPage, qrAuthPath, 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<String>? 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<String>? forbiddenPaths;
}