import 'dart:convert'; import 'dart:developer'; import 'package:equatable/equatable.dart'; class AuthToken extends Equatable { final String accessToken; final DateTime expiresAt; final bool tnc; const AuthToken({ required this.accessToken, required this.expiresAt, required this.tnc, }); factory AuthToken.fromJson(Map json) { final token = json['token']; return AuthToken( accessToken: token, expiresAt: _decodeExpiryFromToken(token), // Keep existing method for expiry tnc: _decodeTncFromToken(token), // Use new method for tnc ); } 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)); } } static bool _decodeTncFromToken(String token) { try { final parts = token.split('.'); if (parts.length != 3) { throw Exception('Invalid JWT format for TNC decoding'); } final payload = parts[1]; String normalized = base64Url.normalize(payload); final payloadMap = json.decode(utf8.decode(base64Url.decode(normalized))); if (payloadMap is! Map || !payloadMap.containsKey('tnc')) { // If 'tnc' is not present in the payload, default to false return false; } // Assuming 'tnc' is directly a boolean in the JWT payload return payloadMap['tnc'] as bool; } catch (e) { log('Error decoding tnc from token: $e'); // Default to false if decoding fails or 'tnc' is not found/invalid return false; } } bool get isExpired => DateTime.now().isAfter(expiresAt); @override List get props => [accessToken, expiresAt, tnc]; }