diff --git a/src/main/java/com/danielagapov/spawn/auth/api/AuthController.java b/src/main/java/com/danielagapov/spawn/auth/api/AuthController.java index 4dec9e26..0051fdba 100644 --- a/src/main/java/com/danielagapov/spawn/auth/api/AuthController.java +++ b/src/main/java/com/danielagapov/spawn/auth/api/AuthController.java @@ -240,7 +240,7 @@ public ResponseEntity registerViaOAuth(@Valid @RequestBody OAuthRegistrationD logger.info("OAuth registration succeeded via graceful handling"); return ResponseEntity.ok().headers(headers).body(gracefulUser); } else { - logger.warn("Graceful handling returned null - attempting final fallback check"); + logger.warn("Graceful handling returned null - attempting final fallback check. Email: " + registration.getEmail() + ", provider: " + registration.getProvider()); // Final fallback: try to sign in the user if they already exist try { diff --git a/src/main/java/com/danielagapov/spawn/auth/internal/services/AppleOAuthStrategy.java b/src/main/java/com/danielagapov/spawn/auth/internal/services/AppleOAuthStrategy.java index 687e7fc9..1042e935 100644 --- a/src/main/java/com/danielagapov/spawn/auth/internal/services/AppleOAuthStrategy.java +++ b/src/main/java/com/danielagapov/spawn/auth/internal/services/AppleOAuthStrategy.java @@ -65,7 +65,7 @@ public String verifyIdToken(String idToken) { // Check token expiration before verification if (decodedJWT.getExpiresAt() != null && decodedJWT.getExpiresAt().before(new java.util.Date())) { - logger.error("Apple ID token has expired"); + logger.error("Apple ID token has expired. Expiration: " + decodedJWT.getExpiresAt() + ", Current time: " + new java.util.Date()); throw new TokenExpiredException("Apple ID token has expired, please sign in again"); } diff --git a/src/main/java/com/danielagapov/spawn/auth/internal/services/AuthService.java b/src/main/java/com/danielagapov/spawn/auth/internal/services/AuthService.java index 2b3163d1..e2c510fa 100644 --- a/src/main/java/com/danielagapov/spawn/auth/internal/services/AuthService.java +++ b/src/main/java/com/danielagapov/spawn/auth/internal/services/AuthService.java @@ -132,7 +132,7 @@ public boolean verifyEmail(String token) { logger.info("Email verified successfully for user: " + LoggingUtils.formatUserInfo(user)); return true; } - logger.warn("Invalid email verification token received"); + logger.warn("Invalid email verification token received. Token prefix: " + (token != null ? token.substring(0, Math.min(20, token.length())) + "..." : "null")); return false; } catch (Exception e) { logger.error("Error during email verification: " + e.getMessage()); @@ -432,7 +432,7 @@ public AuthResponseDTO handleOAuthRegistrationGracefully(OAuthRegistrationDTO re } } catch (InterruptedException ie) { Thread.currentThread().interrupt(); - logger.warn("Interrupted while waiting to check for concurrent user creation"); + logger.warn("Interrupted while waiting to check for concurrent user creation: " + ie.getMessage()); } catch (Exception recheckEx) { logger.warn("Error during concurrent user re-check: " + recheckEx.getMessage()); } diff --git a/src/main/java/com/danielagapov/spawn/auth/internal/services/GoogleOAuthStrategy.java b/src/main/java/com/danielagapov/spawn/auth/internal/services/GoogleOAuthStrategy.java index 186d60f0..cf7af4a4 100644 --- a/src/main/java/com/danielagapov/spawn/auth/internal/services/GoogleOAuthStrategy.java +++ b/src/main/java/com/danielagapov/spawn/auth/internal/services/GoogleOAuthStrategy.java @@ -54,10 +54,16 @@ public String verifyIdToken(String idToken) { // Use retry helper for token verification return RetryHelper.executeOAuthWithRetry(() -> { try { + GoogleIdToken googleIdToken = null; // Verify the token - GoogleIdToken googleIdToken = verifier.verify(idToken); + try { + googleIdToken = verifier.verify(idToken); + } catch (Error e) { + logger.error(e.getMessage()); + } + if (googleIdToken == null) { - logger.error("Token verification failed - invalid token"); + logger.error("Token verification failed - invalid token. Token prefix: " + (idToken != null ? idToken.substring(0, Math.min(20, idToken.length())) + "..." : "null")); throw new SecurityException("Invalid Google ID token - token may be expired or malformed"); } @@ -70,7 +76,7 @@ public String verifyIdToken(String idToken) { // Check token expiration Long expiration = payload.getExpirationTimeSeconds(); if (expiration != null && expiration < System.currentTimeMillis() / 1000) { - logger.error("Token has expired"); + logger.error("Token has expired. Expiration: " + expiration + ", Current time: " + (System.currentTimeMillis() / 1000)); throw new TokenExpiredException("Google ID token has expired, please sign in again"); } @@ -78,7 +84,7 @@ public String verifyIdToken(String idToken) { // For example, verify email is verified Boolean emailVerified = payload.getEmailVerified(); if (emailVerified == null || !emailVerified) { - logger.error("Email not verified"); + logger.error("Email not verified for user ID: " + userId + ", emailVerified value: " + emailVerified); throw new SecurityException("Google account email is not verified"); } @@ -127,10 +133,10 @@ public void initializeGoogleVerifier() { .build(); logger.info("Google token verifier successfully initialized"); } else { - logger.error("Google client ID not set, token verification will fail. Set GOOGLE_CLIENT_ID in your environment."); + logger.error("Google client ID not set, token verification will fail. Set GOOGLE_CLIENT_ID in your environment. clientId value: " + (clientId == null ? "null" : "empty string")); // Create a dummy verifier that will reject all tokens this.verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new GsonFactory()).build(); - logger.warn("Created dummy verifier that will reject all tokens"); + logger.warn("Created dummy verifier that will reject all tokens - Google OAuth will not work"); } } } diff --git a/src/main/java/com/danielagapov/spawn/auth/internal/services/JWTService.java b/src/main/java/com/danielagapov/spawn/auth/internal/services/JWTService.java index 5b086ab8..afaa3489 100644 --- a/src/main/java/com/danielagapov/spawn/auth/internal/services/JWTService.java +++ b/src/main/java/com/danielagapov/spawn/auth/internal/services/JWTService.java @@ -120,12 +120,12 @@ public String refreshAccessToken(HttpServletRequest request) { try { subject = extractUsername(token); // This actually extracts the subject, which could be username or email } catch (Exception e) { - logger.error("Failed to extract subject. Invalid or expired token"); + logger.error("Failed to extract subject. Invalid or expired token: " + e.getMessage()); throw e; } if (subject == null) { - logger.warn("Token subject is null"); + logger.warn("Token subject is null. Token prefix: " + (token != null ? token.substring(0, Math.min(20, token.length())) + "..." : "null")); throw new BadTokenException(); } @@ -146,7 +146,7 @@ public String refreshAccessToken(HttpServletRequest request) { // Use username if available, otherwise use email usernameForNewToken = user.getOptionalUsername().orElse(user.getEmail()); } catch (Exception e) { - logger.error("Failed to get user by email: " + subject); + logger.error("Failed to get user by email: " + subject + ": " + e.getMessage()); throw new BadTokenException(); } } @@ -161,7 +161,7 @@ public String refreshAccessToken(HttpServletRequest request) { String newAccessToken = generateAccessToken(usernameForNewToken); return newAccessToken; } else { - logger.warn("Expired token found"); + logger.warn("Expired or invalid token type found for subject: " + subject); throw new BadTokenException(); } } @@ -269,7 +269,7 @@ private boolean isTokenNonExpired(String token) { try { return !extractClaim(token, Claims::getExpiration).before(new Date()); } catch (ExpiredJwtException e) { - logger.warn("Token has expired"); + logger.warn("Token has expired: " + e.getMessage()); return false; } catch (Exception e) { logger.warn("Error checking token expiration: " + e.getMessage()); diff --git a/src/main/java/com/danielagapov/spawn/auth/internal/services/OAuthService.java b/src/main/java/com/danielagapov/spawn/auth/internal/services/OAuthService.java index 9c538e65..8707b160 100644 --- a/src/main/java/com/danielagapov/spawn/auth/internal/services/OAuthService.java +++ b/src/main/java/com/danielagapov/spawn/auth/internal/services/OAuthService.java @@ -101,7 +101,7 @@ public BaseUserDTO makeUser(UserDTO user, String externalUserId, byte[] profileP return UserMapper.toDTO(existingUser); } } catch (BaseNotFoundException e) { - logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in makeUser."); + logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in makeUser: " + e.getMessage()); // Attempt to repair the data inconsistency gracefully try { @@ -216,7 +216,7 @@ public Optional getUserIfExistsbyExternalId(String externalUser throw new IncorrectProviderException("The email: " + email + " is already associated to a " + providerName + " account. Please login through " + providerName + " instead"); } } catch (BaseNotFoundException e) { - logger.warn("User email exists but no mapping found - checking for data inconsistency and attempting cleanup."); + logger.warn("User email exists but no mapping found - checking for data inconsistency and attempting cleanup: " + e.getMessage()); // Get the user by email to check their status try { @@ -231,7 +231,7 @@ public Optional getUserIfExistsbyExternalId(String externalUser logger.info("Orphaned user deleted. Treating as no user found to allow fresh registration."); return Optional.empty(); } else { - logger.warn("Active user exists without OAuth mapping - possible data corruption. Manual intervention may be required."); + logger.warn("Active user exists without OAuth mapping - possible data corruption. Manual intervention may be required. Email: " + email + ", User ID: " + orphanedUser.getId()); return Optional.empty(); } } catch (Exception cleanupEx) { @@ -265,7 +265,7 @@ public BaseUserDTO createUserFromOAuth(UserCreationDTO userCreationDTO, String i logger.info("Making new user: " + newUser.getUsername()); return makeUser(newUser, userId, userCreationDTO.getProfilePictureData(), provider); } else { - logger.error("Missing required authentication parameters"); + logger.error("Missing required authentication parameters. idToken is null: " + (idToken == null) + ", provider: " + provider); throw new IllegalArgumentException("Either a valid ID token or external user ID with provider must be provided"); } } catch (SecurityException e) { @@ -397,7 +397,7 @@ private String checkOAuthRegistrationWithLock(String email, String externalUserI throw new IncorrectProviderException("Email already exists for a " + providerName + " account. Please login through " + providerName + " instead"); } } catch (BaseNotFoundException e) { - logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in registration flow."); + logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in registration flow: " + e.getMessage()); // Attempt to repair the data inconsistency gracefully try { @@ -476,7 +476,7 @@ private void createAndSaveMappingWithLock(User user, String externalUserId, OAut logger.info("Mapping already exists for the same user, no action needed"); return; } else { - logger.warn("Mapping exists for different user. This indicates a race condition or data inconsistency."); + logger.warn("Mapping exists for different user. This indicates a race condition or data inconsistency. External ID: " + externalUserId + ", existing user: " + existing.getUser().getId() + ", new user: " + user.getId()); // Check if the existing mapping points to a deleted/non-existent user try { @@ -488,7 +488,7 @@ private void createAndSaveMappingWithLock(User user, String externalUserId, OAut externalIdMapRepository.delete(existing); externalIdMapRepository.flush(); // Ensure deletion is committed before proceeding } else { - logger.error("Mapping exists for a different valid user. Cannot proceed with mapping creation."); + logger.error("Mapping exists for a different valid user. Cannot proceed with mapping creation. External ID: " + externalUserId + ", existing user: " + existingMappedUser.getId() + ", new user: " + user.getId()); throw new RuntimeException("OAuth mapping conflict: External ID already mapped to a different active user"); } } catch (Exception checkEx) { diff --git a/src/main/java/com/danielagapov/spawn/shared/config/JWTFilterConfig.java b/src/main/java/com/danielagapov/spawn/shared/config/JWTFilterConfig.java index 9e900706..f3eefea3 100644 --- a/src/main/java/com/danielagapov/spawn/shared/config/JWTFilterConfig.java +++ b/src/main/java/com/danielagapov/spawn/shared/config/JWTFilterConfig.java @@ -75,7 +75,7 @@ protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServlet */ SecurityContextHolder.getContext().setAuthentication(token); } else { - logger.warn("Invalid token, user is not authenticated"); + logger.warn("Invalid token, user is not authenticated. Username: " + username); } } catch (UsernameNotFoundException e) { // Try loading by email if username lookup failed (for OAuth users with email-based tokens) @@ -86,10 +86,10 @@ protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServlet token.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(token); } else { - logger.warn("Invalid token, user is not authenticated"); + logger.warn("Invalid token, user is not authenticated. Email/username: " + username); } } catch (Exception emailException) { - logger.warn("User not found by username or email: " + username); + logger.warn("User not found by username or email: " + username + ": " + emailException.getMessage()); } } catch (Exception e) { logger.error("Error during authentication: " + e.getMessage());