Skip to content

Commit 47cd4ac

Browse files
authored
Merge pull request #453 from Daggerpov/api-changes-for-mobile-improvements
Api changes for mobile improvements
2 parents 27b227f + 053734d commit 47cd4ac

7 files changed

Lines changed: 31 additions & 25 deletions

File tree

src/main/java/com/danielagapov/spawn/auth/api/AuthController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public ResponseEntity<?> registerViaOAuth(@Valid @RequestBody OAuthRegistrationD
240240
logger.info("OAuth registration succeeded via graceful handling");
241241
return ResponseEntity.ok().headers(headers).body(gracefulUser);
242242
} else {
243-
logger.warn("Graceful handling returned null - attempting final fallback check");
243+
logger.warn("Graceful handling returned null - attempting final fallback check. Email: " + registration.getEmail() + ", provider: " + registration.getProvider());
244244

245245
// Final fallback: try to sign in the user if they already exist
246246
try {

src/main/java/com/danielagapov/spawn/auth/internal/services/AppleOAuthStrategy.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public String verifyIdToken(String idToken) {
6565

6666
// Check token expiration before verification
6767
if (decodedJWT.getExpiresAt() != null && decodedJWT.getExpiresAt().before(new java.util.Date())) {
68-
logger.error("Apple ID token has expired");
68+
logger.error("Apple ID token has expired. Expiration: " + decodedJWT.getExpiresAt() + ", Current time: " + new java.util.Date());
6969
throw new TokenExpiredException("Apple ID token has expired, please sign in again");
7070
}
7171

src/main/java/com/danielagapov/spawn/auth/internal/services/AuthService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public boolean verifyEmail(String token) {
132132
logger.info("Email verified successfully for user: " + LoggingUtils.formatUserInfo(user));
133133
return true;
134134
}
135-
logger.warn("Invalid email verification token received");
135+
logger.warn("Invalid email verification token received. Token prefix: " + (token != null ? token.substring(0, Math.min(20, token.length())) + "..." : "null"));
136136
return false;
137137
} catch (Exception e) {
138138
logger.error("Error during email verification: " + e.getMessage());
@@ -432,7 +432,7 @@ public AuthResponseDTO handleOAuthRegistrationGracefully(OAuthRegistrationDTO re
432432
}
433433
} catch (InterruptedException ie) {
434434
Thread.currentThread().interrupt();
435-
logger.warn("Interrupted while waiting to check for concurrent user creation");
435+
logger.warn("Interrupted while waiting to check for concurrent user creation: " + ie.getMessage());
436436
} catch (Exception recheckEx) {
437437
logger.warn("Error during concurrent user re-check: " + recheckEx.getMessage());
438438
}

src/main/java/com/danielagapov/spawn/auth/internal/services/GoogleOAuthStrategy.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,16 @@ public String verifyIdToken(String idToken) {
5454
// Use retry helper for token verification
5555
return RetryHelper.executeOAuthWithRetry(() -> {
5656
try {
57+
GoogleIdToken googleIdToken = null;
5758
// Verify the token
58-
GoogleIdToken googleIdToken = verifier.verify(idToken);
59+
try {
60+
googleIdToken = verifier.verify(idToken);
61+
} catch (Error e) {
62+
logger.error(e.getMessage());
63+
}
64+
5965
if (googleIdToken == null) {
60-
logger.error("Token verification failed - invalid token");
66+
logger.error("Token verification failed - invalid token. Token prefix: " + (idToken != null ? idToken.substring(0, Math.min(20, idToken.length())) + "..." : "null"));
6167
throw new SecurityException("Invalid Google ID token - token may be expired or malformed");
6268
}
6369

@@ -70,15 +76,15 @@ public String verifyIdToken(String idToken) {
7076
// Check token expiration
7177
Long expiration = payload.getExpirationTimeSeconds();
7278
if (expiration != null && expiration < System.currentTimeMillis() / 1000) {
73-
logger.error("Token has expired");
79+
logger.error("Token has expired. Expiration: " + expiration + ", Current time: " + (System.currentTimeMillis() / 1000));
7480
throw new TokenExpiredException("Google ID token has expired, please sign in again");
7581
}
7682

7783
// Verify additional claims if needed
7884
// For example, verify email is verified
7985
Boolean emailVerified = payload.getEmailVerified();
8086
if (emailVerified == null || !emailVerified) {
81-
logger.error("Email not verified");
87+
logger.error("Email not verified for user ID: " + userId + ", emailVerified value: " + emailVerified);
8288
throw new SecurityException("Google account email is not verified");
8389
}
8490

@@ -127,10 +133,10 @@ public void initializeGoogleVerifier() {
127133
.build();
128134
logger.info("Google token verifier successfully initialized");
129135
} else {
130-
logger.error("Google client ID not set, token verification will fail. Set GOOGLE_CLIENT_ID in your environment.");
136+
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"));
131137
// Create a dummy verifier that will reject all tokens
132138
this.verifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new GsonFactory()).build();
133-
logger.warn("Created dummy verifier that will reject all tokens");
139+
logger.warn("Created dummy verifier that will reject all tokens - Google OAuth will not work");
134140
}
135141
}
136142
}

src/main/java/com/danielagapov/spawn/auth/internal/services/JWTService.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,12 @@ public String refreshAccessToken(HttpServletRequest request) {
120120
try {
121121
subject = extractUsername(token); // This actually extracts the subject, which could be username or email
122122
} catch (Exception e) {
123-
logger.error("Failed to extract subject. Invalid or expired token");
123+
logger.error("Failed to extract subject. Invalid or expired token: " + e.getMessage());
124124
throw e;
125125
}
126126

127127
if (subject == null) {
128-
logger.warn("Token subject is null");
128+
logger.warn("Token subject is null. Token prefix: " + (token != null ? token.substring(0, Math.min(20, token.length())) + "..." : "null"));
129129
throw new BadTokenException();
130130
}
131131

@@ -146,7 +146,7 @@ public String refreshAccessToken(HttpServletRequest request) {
146146
// Use username if available, otherwise use email
147147
usernameForNewToken = user.getOptionalUsername().orElse(user.getEmail());
148148
} catch (Exception e) {
149-
logger.error("Failed to get user by email: " + subject);
149+
logger.error("Failed to get user by email: " + subject + ": " + e.getMessage());
150150
throw new BadTokenException();
151151
}
152152
}
@@ -161,7 +161,7 @@ public String refreshAccessToken(HttpServletRequest request) {
161161
String newAccessToken = generateAccessToken(usernameForNewToken);
162162
return newAccessToken;
163163
} else {
164-
logger.warn("Expired token found");
164+
logger.warn("Expired or invalid token type found for subject: " + subject);
165165
throw new BadTokenException();
166166
}
167167
}
@@ -269,7 +269,7 @@ private boolean isTokenNonExpired(String token) {
269269
try {
270270
return !extractClaim(token, Claims::getExpiration).before(new Date());
271271
} catch (ExpiredJwtException e) {
272-
logger.warn("Token has expired");
272+
logger.warn("Token has expired: " + e.getMessage());
273273
return false;
274274
} catch (Exception e) {
275275
logger.warn("Error checking token expiration: " + e.getMessage());

src/main/java/com/danielagapov/spawn/auth/internal/services/OAuthService.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public BaseUserDTO makeUser(UserDTO user, String externalUserId, byte[] profileP
101101
return UserMapper.toDTO(existingUser);
102102
}
103103
} catch (BaseNotFoundException e) {
104-
logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in makeUser.");
104+
logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in makeUser: " + e.getMessage());
105105

106106
// Attempt to repair the data inconsistency gracefully
107107
try {
@@ -216,7 +216,7 @@ public Optional<AuthResponseDTO> getUserIfExistsbyExternalId(String externalUser
216216
throw new IncorrectProviderException("The email: " + email + " is already associated to a " + providerName + " account. Please login through " + providerName + " instead");
217217
}
218218
} catch (BaseNotFoundException e) {
219-
logger.warn("User email exists but no mapping found - checking for data inconsistency and attempting cleanup.");
219+
logger.warn("User email exists but no mapping found - checking for data inconsistency and attempting cleanup: " + e.getMessage());
220220

221221
// Get the user by email to check their status
222222
try {
@@ -231,7 +231,7 @@ public Optional<AuthResponseDTO> getUserIfExistsbyExternalId(String externalUser
231231
logger.info("Orphaned user deleted. Treating as no user found to allow fresh registration.");
232232
return Optional.empty();
233233
} else {
234-
logger.warn("Active user exists without OAuth mapping - possible data corruption. Manual intervention may be required.");
234+
logger.warn("Active user exists without OAuth mapping - possible data corruption. Manual intervention may be required. Email: " + email + ", User ID: " + orphanedUser.getId());
235235
return Optional.empty();
236236
}
237237
} catch (Exception cleanupEx) {
@@ -265,7 +265,7 @@ public BaseUserDTO createUserFromOAuth(UserCreationDTO userCreationDTO, String i
265265
logger.info("Making new user: " + newUser.getUsername());
266266
return makeUser(newUser, userId, userCreationDTO.getProfilePictureData(), provider);
267267
} else {
268-
logger.error("Missing required authentication parameters");
268+
logger.error("Missing required authentication parameters. idToken is null: " + (idToken == null) + ", provider: " + provider);
269269
throw new IllegalArgumentException("Either a valid ID token or external user ID with provider must be provided");
270270
}
271271
} catch (SecurityException e) {
@@ -397,7 +397,7 @@ private String checkOAuthRegistrationWithLock(String email, String externalUserI
397397
throw new IncorrectProviderException("Email already exists for a " + providerName + " account. Please login through " + providerName + " instead");
398398
}
399399
} catch (BaseNotFoundException e) {
400-
logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in registration flow.");
400+
logger.warn("User email exists but no mapping found - this may be due to data inconsistency. Attempting graceful repair in registration flow: " + e.getMessage());
401401

402402
// Attempt to repair the data inconsistency gracefully
403403
try {
@@ -476,7 +476,7 @@ private void createAndSaveMappingWithLock(User user, String externalUserId, OAut
476476
logger.info("Mapping already exists for the same user, no action needed");
477477
return;
478478
} else {
479-
logger.warn("Mapping exists for different user. This indicates a race condition or data inconsistency.");
479+
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());
480480

481481
// Check if the existing mapping points to a deleted/non-existent user
482482
try {
@@ -488,7 +488,7 @@ private void createAndSaveMappingWithLock(User user, String externalUserId, OAut
488488
externalIdMapRepository.delete(existing);
489489
externalIdMapRepository.flush(); // Ensure deletion is committed before proceeding
490490
} else {
491-
logger.error("Mapping exists for a different valid user. Cannot proceed with mapping creation.");
491+
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());
492492
throw new RuntimeException("OAuth mapping conflict: External ID already mapped to a different active user");
493493
}
494494
} catch (Exception checkEx) {

src/main/java/com/danielagapov/spawn/shared/config/JWTFilterConfig.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected void doFilterInternal(HttpServletRequest request, @NonNull HttpServlet
7575
*/
7676
SecurityContextHolder.getContext().setAuthentication(token);
7777
} else {
78-
logger.warn("Invalid token, user is not authenticated");
78+
logger.warn("Invalid token, user is not authenticated. Username: " + username);
7979
}
8080
} catch (UsernameNotFoundException e) {
8181
// 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
8686
token.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
8787
SecurityContextHolder.getContext().setAuthentication(token);
8888
} else {
89-
logger.warn("Invalid token, user is not authenticated");
89+
logger.warn("Invalid token, user is not authenticated. Email/username: " + username);
9090
}
9191
} catch (Exception emailException) {
92-
logger.warn("User not found by username or email: " + username);
92+
logger.warn("User not found by username or email: " + username + ": " + emailException.getMessage());
9393
}
9494
} catch (Exception e) {
9595
logger.error("Error during authentication: " + e.getMessage());

0 commit comments

Comments
 (0)