fix(auth): send JSON object body to /api/v1/changePassword#35440
fix(auth): send JSON object body to /api/v1/changePassword#35440
Conversation
The change-password HTTP call was stringifying the payload before passing it to HttpClient.post. HttpClient auto-sets Content-Type: text/plain for string bodies, so the backend (which declares @consumes APPLICATION_JSON) rejected the request with 415 Unsupported Media Type — silently breaking the "Change Password" button on the password recovery page. The error handler then threw "Cannot read properties of undefined (reading '0')" when reading errors[0] on the non-JSON 415 body. Pass the plain object so Angular serializes it and sets the correct Content-Type, matching sibling auth calls (recoverPassword, loginUser). Regression from PR #34165 (CoreWebService → HttpClient refactor). Closes #35269
|
Claude finished @oidacra's task in 1m 19s —— View job PR Review
The fix is correct and the approach is sound. A few things worth a second look:
|
… array
The error handler read response.error?.errors[0]?.message — the optional
chain covered .error but not .errors, so if the backend returns an error
body without an errors array (e.g. the 415 body {message: "..."}), the
handler crashes with "Cannot read properties of undefined (reading '0')".
Guard the array access too.
- Add regression tests that mount the real LoginService with HttpTestingController and verify POST /api/v1/changePassword is sent with a plain-object body (string bodies cause Content-Type: text/plain and trigger the 415 this PR fixes) and that a 415-shaped error body without an `errors` array is handled without crashing. - Fall back to response.error.message when the errors array is absent, so the user sees the backend's message instead of a blank error state.
|
Addressed in 59481e6: 1. Silent blank message on non-standard errors — Done. Added 2. No test for absent- 3. No unit test for
The natural home for this test would be 4. Deprecated |
Summary
Fixes the "Change Password" button on the Password Recovery page, which silently failed with
HTTP 415 Unsupported Media Typeand a consoleTypeError: Cannot read properties of undefined (reading '0').Root cause:
LoginService.changePasswordwas callingHttpClient.post(url, JSON.stringify({...})). When given a string body, Angular'sHttpClientauto-setsContent-Type: text/plain, but the backendResetPasswordResourcedeclares@Consumes(MediaType.APPLICATION_JSON)— so every request was rejected with 415. The error handler atreset-password.component.ts:125then crashed readingerrors[0]on the non-JSON 415 body.Fix: Pass the plain object so Angular serializes it and sets
Content-Type: application/jsonautomatically. Matches the pattern of every other auth call inLoginService(recoverPassword,loginUser,loginAs, etc.).Regression origin: PR #34165 (
df97483c4e) — theCoreWebService→HttpClientrefactor.CoreWebService.request()handled JSON headers internally; the migrated code kept theJSON.stringifybut lost the headers.Verification
Reproduced locally against
http://localhost:8080:JSON.stringify({password, token})(before){"message":"HTTP 415 Unsupported Media Type"}{password, token}(after){"errors":[{"errorCode":"reset-password-token-invalid","message":"Invalid token..."}]}The 400 response shape matches what
reset-password.component.tsexpects — no more TypeError.Closes #35269
Acceptance Criteria
POST /api/v1/changePasswordis sent withContent-Type: application/jsonTest plan
yarn nx test dotcms-ui— 2109 passingChanged files
core-web/libs/dotcms-js/src/lib/core/login.service.ts— removeJSON.stringifyon thechangePasswordbodyThis PR fixes: #35269