3cf874ab69
AuthController is an AsyncNotifier holding the currently-logged-in User. server_url, session_token, current_user all live in flutter_secure_storage. ServerUrlScreen probes /healthz before saving the URL so we don't store a bogus base.
57 lines
1.8 KiB
Dart
57 lines
1.8 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
|
|
import '../models/user.dart';
|
|
|
|
const _kServerUrl = 'server_url';
|
|
const _kSessionToken = 'session_token';
|
|
const _kCurrentUser = 'current_user';
|
|
|
|
final secureStorageProvider = Provider<FlutterSecureStorage>(
|
|
(ref) => const FlutterSecureStorage(),
|
|
);
|
|
|
|
final serverUrlProvider = FutureProvider<String?>((ref) async {
|
|
return ref.watch(secureStorageProvider).read(key: _kServerUrl);
|
|
});
|
|
|
|
final sessionTokenProvider = FutureProvider<String?>((ref) async {
|
|
return ref.watch(secureStorageProvider).read(key: _kSessionToken);
|
|
});
|
|
|
|
class AuthController extends AsyncNotifier<User?> {
|
|
late FlutterSecureStorage _storage;
|
|
|
|
@override
|
|
Future<User?> build() async {
|
|
_storage = ref.watch(secureStorageProvider);
|
|
final raw = await _storage.read(key: _kCurrentUser);
|
|
if (raw == null) return null;
|
|
return User.fromJson(jsonDecode(raw) as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<void> setServerUrl(String url) async {
|
|
await _storage.write(key: _kServerUrl, value: url);
|
|
ref.invalidate(serverUrlProvider);
|
|
}
|
|
|
|
Future<void> setSession({required String token, required String userJson}) async {
|
|
await _storage.write(key: _kSessionToken, value: token);
|
|
await _storage.write(key: _kCurrentUser, value: userJson);
|
|
ref.invalidate(sessionTokenProvider);
|
|
state = AsyncData(User.fromJson(jsonDecode(userJson) as Map<String, dynamic>));
|
|
}
|
|
|
|
Future<void> clearSession() async {
|
|
await _storage.delete(key: _kSessionToken);
|
|
await _storage.delete(key: _kCurrentUser);
|
|
ref.invalidate(sessionTokenProvider);
|
|
state = const AsyncData(null);
|
|
}
|
|
}
|
|
|
|
final authControllerProvider =
|
|
AsyncNotifierProvider<AuthController, User?>(AuthController.new);
|