logs
Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions

This commit is contained in:
Dmitry 2025-12-12 00:38:21 +03:00
parent 5a3d7ada22
commit 215854e461
3 changed files with 54 additions and 6 deletions

View file

@ -159,7 +159,9 @@ class AdminAuthApiV2 {
} }
// Generate JWT token using JwtService (same as regular auth) // Generate JWT token using JwtService (same as regular auth)
print('[ADMIN AUTH] Generating tokens for admin user ${user.id}');
final tokens = await _jwtService.generateTokens(user); final tokens = await _jwtService.generateTokens(user);
print('[ADMIN AUTH] Generated access token, length: ${tokens.accessToken.length}');
return _json({ return _json({
'success': true, 'success': true,

View file

@ -112,9 +112,28 @@ Middleware authorizeV2(UserManager userManager, JwtService jwtService) {
} }
final token = authHeader.substring(7); // Remove "Bearer " prefix final token = authHeader.substring(7); // Remove "Bearer " prefix
// Debug logging for admin endpoints
if (normalizedPath.startsWith('/admin/')) {
print('[AUTH DEBUG] Verifying token for path: $normalizedPath');
print('[AUTH DEBUG] Token length: ${token.length}');
print('[AUTH DEBUG] Token preview: ${token.length > 50 ? token.substring(0, 50) + "..." : token}');
}
final userId = jwtService.verifyAccessToken(token); final userId = jwtService.verifyAccessToken(token);
if (userId == null) { if (userId == null) {
// Additional debug info for admin endpoints
if (normalizedPath.startsWith('/admin/')) {
print('[AUTH DEBUG] Token verification failed for path: $normalizedPath');
// Try to extract payload to see what's wrong
try {
final payload = jwtService.extractPayload(token);
print('[AUTH DEBUG] Extracted payload: $payload');
} catch (e) {
print('[AUTH DEBUG] Could not extract payload: $e');
}
}
return Response( return Response(
401, 401,
headers: {'Content-Type': 'application/json'}, headers: {'Content-Type': 'application/json'},

View file

@ -47,6 +47,10 @@ class JwtService {
final accessToken = _createSimpleJwt(accessTokenPayload); final accessToken = _createSimpleJwt(accessTokenPayload);
final refreshToken = _createSimpleJwt(refreshTokenPayload); final refreshToken = _createSimpleJwt(refreshTokenPayload);
print('[JWT DEBUG] Generated access token for user ${user.id}');
print('[JWT DEBUG] Access token payload: $accessTokenPayload');
print('[JWT DEBUG] Access token length: ${accessToken.length}');
// Store refresh token for invalidation // Store refresh token for invalidation
final userId = user.id; final userId = user.id;
if (userId == null) { if (userId == null) {
@ -66,24 +70,38 @@ class JwtService {
String? verifyAccessToken(String token) { String? verifyAccessToken(String token) {
try { try {
final payload = _verifySimpleJwt(token); final payload = _verifySimpleJwt(token);
if (payload == null) return null; if (payload == null) {
print('[JWT DEBUG] Token verification failed: payload is null');
return null;
}
print('[JWT DEBUG] Token payload: $payload');
// Check if token is expired // Check if token is expired
final exp = payload['exp'] as int?; final exp = payload['exp'] as int?;
if (exp != null) { if (exp != null) {
final expiryTime = DateTime.fromMillisecondsSinceEpoch(exp * 1000); final expiryTime = DateTime.fromMillisecondsSinceEpoch(exp * 1000);
if (DateTime.now().isAfter(expiryTime)) { final now = DateTime.now();
print('[JWT DEBUG] Token expiry: $expiryTime, now: $now, expired: ${now.isAfter(expiryTime)}');
if (now.isAfter(expiryTime)) {
print('[JWT DEBUG] Token is expired');
return null; return null;
} }
} }
// Check token type // Check token type
if (payload['type'] != 'access') { final tokenType = payload['type'];
print('[JWT DEBUG] Token type: $tokenType');
if (tokenType != 'access') {
print('[JWT DEBUG] Token type mismatch: expected "access", got "$tokenType"');
return null; return null;
} }
return payload['userId']?.toString(); final userId = payload['userId']?.toString();
print('[JWT DEBUG] Extracted userId: $userId');
return userId;
} catch (e) { } catch (e) {
print('[JWT DEBUG] Token verification exception: $e');
return null; return null;
} }
} }
@ -143,7 +161,10 @@ class JwtService {
Map<String, dynamic>? _verifySimpleJwt(String token) { Map<String, dynamic>? _verifySimpleJwt(String token) {
try { try {
final parts = token.split('.'); final parts = token.split('.');
if (parts.length != 3) return null; if (parts.length != 3) {
print('[JWT DEBUG] Invalid token format: expected 3 parts, got ${parts.length}');
return null;
}
final headerB64 = parts[0]; final headerB64 = parts[0];
final payloadB64 = parts[1]; final payloadB64 = parts[1];
@ -156,13 +177,19 @@ class JwtService {
final expectedSignatureB64 = base64UrlEncode(expectedSignature); final expectedSignatureB64 = base64UrlEncode(expectedSignature);
if (signatureB64 != expectedSignatureB64) { if (signatureB64 != expectedSignatureB64) {
print('[JWT DEBUG] Invalid signature');
print('[JWT DEBUG] Expected: $expectedSignatureB64');
print('[JWT DEBUG] Got: $signatureB64');
return null; // Invalid signature return null; // Invalid signature
} }
// Decode payload // Decode payload
final payloadJson = utf8.decode(base64Url.decode(payloadB64)); final payloadJson = utf8.decode(base64Url.decode(payloadB64));
return jsonDecode(payloadJson) as Map<String, dynamic>; final payload = jsonDecode(payloadJson) as Map<String, dynamic>;
print('[JWT DEBUG] Decoded payload: $payload');
return payload;
} catch (e) { } catch (e) {
print('[JWT DEBUG] Exception during token verification: $e');
return null; return null;
} }
} }