Skip to content

Commit 50e0a03

Browse files
committed
feat(i18n): add default message fallbacks for missing translations
Improve i18n handling by providing sensible default messages when translations are missing. This prevents raw message keys from being displayed to users when message bundles are incomplete. Changes: - UserAPI: Add default messages to all getMessage() calls - UserActionController: Use getValue() instead of name()/toString() for consistent message key generation from TokenValidationResult - GlobalMessageControllerAdvice: Use messageKey as fallback when no translation is found
1 parent f3009e3 commit 50e0a03

3 files changed

Lines changed: 11 additions & 10 deletions

File tree

src/main/java/com/digitalsanctuary/spring/user/api/UserAPI.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public ResponseEntity<JSONResponse> updateUserAccount(@AuthenticationPrincipal D
162162

163163
logAuditEvent("ProfileUpdate", "Success", "User profile updated", user, request);
164164

165-
return buildSuccessResponse(messages.getMessage("message.update-user.success", null, locale), null);
165+
return buildSuccessResponse(messages.getMessage("message.update-user.success", null, "Profile updated successfully", locale), null);
166166
}
167167

168168
/**
@@ -206,7 +206,7 @@ public ResponseEntity<JSONResponse> savePassword(@Valid @RequestBody SavePasswor
206206
// are not a concern. Constant-time comparison is only needed when comparing
207207
// against stored credentials, which is handled by Spring's PasswordEncoder.
208208
if (!savePasswordDto.getNewPassword().equals(savePasswordDto.getConfirmPassword())) {
209-
return buildErrorResponse(messages.getMessage("message.password.mismatch", null, locale), 1,
209+
return buildErrorResponse(messages.getMessage("message.password.mismatch", null, "Passwords do not match", locale), 1,
210210
HttpStatus.BAD_REQUEST);
211211
}
212212

@@ -216,14 +216,14 @@ public ResponseEntity<JSONResponse> savePassword(@Valid @RequestBody SavePasswor
216216

217217
if (tokenResult != UserService.TokenValidationResult.VALID) {
218218
String messageKey = "auth.message." + tokenResult.getValue();
219-
return buildErrorResponse(messages.getMessage(messageKey, null, locale), 2, HttpStatus.BAD_REQUEST);
219+
return buildErrorResponse(messages.getMessage(messageKey, null, "Invalid or expired token", locale), 2, HttpStatus.BAD_REQUEST);
220220
}
221221

222222
// Get user by token
223223
Optional<User> userOptional = userService.getUserByPasswordResetToken(savePasswordDto.getToken());
224224

225225
if (userOptional.isEmpty()) {
226-
return buildErrorResponse(messages.getMessage("auth.message.invalid", null, locale), 3,
226+
return buildErrorResponse(messages.getMessage("auth.message.invalid", null, "Invalid token", locale), 3,
227227
HttpStatus.BAD_REQUEST);
228228
}
229229

@@ -246,7 +246,7 @@ public ResponseEntity<JSONResponse> savePassword(@Valid @RequestBody SavePasswor
246246

247247
logAuditEvent("PasswordReset", "Success", "Password reset completed", user, request);
248248

249-
return buildSuccessResponse(messages.getMessage("message.reset-password.success", null, locale),
249+
return buildSuccessResponse(messages.getMessage("message.reset-password.success", null, "Password has been reset successfully", locale),
250250
"/user/login.html");
251251

252252
} catch (Exception ex) {
@@ -298,10 +298,10 @@ public ResponseEntity<JSONResponse> updatePassword(@AuthenticationPrincipal DSUs
298298
userService.changeUserPassword(user, passwordDto.getNewPassword());
299299
logAuditEvent("PasswordUpdate", "Success", "User password updated", user, request);
300300

301-
return buildSuccessResponse(messages.getMessage("message.update-password.success", null, locale), null);
301+
return buildSuccessResponse(messages.getMessage("message.update-password.success", null, "Password updated successfully", locale), null);
302302
} catch (InvalidOldPasswordException ex) {
303303
logAuditEvent("PasswordUpdate", "Failure", "Invalid old password", user, request);
304-
return buildErrorResponse(messages.getMessage("message.update-password.invalid-old", null, locale), 1,
304+
return buildErrorResponse(messages.getMessage("message.update-password.invalid-old", null, "Invalid old password", locale), 1,
305305
HttpStatus.BAD_REQUEST);
306306
} catch (Exception ex) {
307307
log.error("Unexpected error during password update.", ex);

src/main/java/com/digitalsanctuary/spring/user/controller/UserActionController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public ModelAndView showChangePasswordPage(final HttpServletRequest request, fin
9292
String redirectString = "redirect:" + forgotPasswordChangeURI;
9393
return new ModelAndView(redirectString, model);
9494
} else {
95-
String messageKey = AUTH_MESSAGE_PREFIX + result.name().toLowerCase();
95+
String messageKey = AUTH_MESSAGE_PREFIX + result.getValue();
9696
model.addAttribute("messageKey", messageKey);
9797
return new ModelAndView("redirect:/index.html", model);
9898
}
@@ -137,7 +137,7 @@ public ModelAndView confirmRegistration(final HttpServletRequest request, final
137137
return new ModelAndView(redirectString, model);
138138
}
139139

140-
model.addAttribute("messageKey", AUTH_MESSAGE_PREFIX + result.toString());
140+
model.addAttribute("messageKey", AUTH_MESSAGE_PREFIX + result.getValue());
141141
model.addAttribute("expired", result == TokenValidationResult.EXPIRED);
142142
model.addAttribute("token", token);
143143
log.debug("UserAPI.confirmRegistration: failed. Token not found or expired.");

src/main/java/com/digitalsanctuary/spring/user/web/GlobalMessageControllerAdvice.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public void addMessageFromKey(WebRequest request, org.springframework.ui.Model m
3939
String messageKey = request.getParameter("messageKey");
4040
if (messageKey != null) {
4141
Locale locale = request.getLocale();
42-
String message = messages.getMessage(messageKey, null, locale);
42+
// Use the messageKey itself as the default if no translation is found
43+
String message = messages.getMessage(messageKey, null, messageKey, locale);
4344
model.addAttribute("message", message);
4445
}
4546
}

0 commit comments

Comments
 (0)