import 'dart:convert'; /// Decodes a JWT token payload without verifying signature. /// Returns the decoded claims or an empty map on failure. Map decodeJwtPayload(String token) { try { final parts = token.split('.'); if (parts.length != 3) return {}; // Normalize base64url to standard base64. final payload = base64Url.normalize(parts[1]); final decoded = utf8.decode(base64Url.decode(payload)); return json.decode(decoded) as Map; } catch (_) { return {}; } } /// Returns the role claim from a JWT token. Defaults to 'user'. String jwtRole(String? token) { if (token == null || token.isEmpty) return 'user'; final claims = decodeJwtPayload(token); return claims['role'] as String? ?? 'user'; } /// Returns true if the JWT token contains role == 'admin'. bool jwtIsAdmin(String? token) => jwtRole(token) == 'admin'; /// Returns username claim from JWT token, if present. String? jwtUsername(String? token) { if (token == null || token.isEmpty) return null; final claims = decodeJwtPayload(token); final value = claims['username']?.toString().trim(); if (value == null || value.isEmpty) return null; return value; } /// Returns user id claim from JWT token, if present. int? jwtUserId(String? token) { if (token == null || token.isEmpty) return null; final claims = decodeJwtPayload(token); final raw = claims['sub'] ?? claims['userId'] ?? claims['id']; if (raw is num) return raw.toInt(); if (raw is String) return int.tryParse(raw); return null; }