import 'package:jwt_decoder/jwt_decoder.dart'; import 'package:logging/logging.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:shared_models/jwt.dart'; import 'package:shared_preferences/shared_preferences.dart'; part 'auth.g.dart'; final logger = Logger('provider/auth'); @riverpod class JwtNotifier extends _$JwtNotifier { @override Future<JWTBody?> build() async { if (!await SharedPreferencesAsync().containsKey('jwt')) { logger.fine('No JWT saved to client'); return null; } final jwtString = await SharedPreferencesAsync().getString('jwt'); if (jwtString == null) { logger.fine('Saved JWT came back null, removing key'); SharedPreferencesAsync().remove('jwt'); return null; } final payload = JwtDecoder.tryDecode(jwtString); if (payload == null) { logger.fine('Failed to decode JWT, removing key.'); SharedPreferencesAsync().remove('jwt'); return null; } try { final body = JWTBody.fromJson(payload); return body; } catch (e) { logger.shout('Failed to parse JWT payload to JWTBody, something is wrong:', e, StackTrace.current); return null; } } Future<void> setJwt(String jwt) async { final payload = JwtDecoder.tryDecode(jwt); if (payload == null) { logger.info('Tried to set JWT token that did not decode to payload'); state = AsyncValue.error('JWT set to invalid token', StackTrace.current); return; } logger.fine('Saving jwt token to shared prefs'); await SharedPreferencesAsync().setString('jwt', jwt); try { final jwtBody = JWTBody.fromJson(payload); state = AsyncValue.data(jwtBody); } catch (e) { state = AsyncError(e, StackTrace.current); } } }