import 'dart:convert'; import 'dart:developer'; import 'package:equatable/equatable.dart'; class AuthToken extends Equatable { final String accessToken; final DateTime expiresAt; const AuthToken({ required this.accessToken, required this.expiresAt, }); factory AuthToken.fromJson(Map json) { return AuthToken( accessToken: json['token'], expiresAt: _decodeExpiryFromToken(json['token']), ); } static DateTime _decodeExpiryFromToken(String token) { try { final parts = token.split('.'); if (parts.length != 3) { throw Exception('Invalid JWT'); } final payload = parts[1]; // Pad the payload if necessary String normalized = base64Url.normalize(payload); final payloadMap = json.decode(utf8.decode(base64Url.decode(normalized))); if (payloadMap is! Map || !payloadMap.containsKey('exp')) { throw Exception('Invalid payload'); } final exp = payloadMap['exp']; return DateTime.fromMillisecondsSinceEpoch(exp * 1000); } catch (e) { // Fallback: 1 hour from now if decoding fails log(e.toString()); return DateTime.now().add(const Duration(hours: 1)); } } bool get isExpired => DateTime.now().isAfter(expiresAt); @override List get props => [accessToken, expiresAt]; }