fix(login): prevent eventual consistency issues on /password/change, missing permissions (#11371)

Closes #11345 

# Which Problems Are Solved

When changing password, users could have run into a race condition /
eventual consistency issue which resulted in:

- Verification failures in `sendPassword`
- The user receiving a `couldNotCreateSession` or
`couldNotCreateSessionForUser` error despite providing a valid password.
 
# How the Problems Are Solved

- Previously, `checkSessionAndSetPassword` was fired without await,
causing the code to proceed immediately to
`sendPassword`. This resulted in `sendPassword` trying to verify the
user's session with the new password before the password update had
actually completed on the server.
- Now the password change call is executed by the login service user
only, ommitting eventual `membership not found (AUTHZ-cdgFk)` errors
from the API by using the user session itself. The login checks for a
recent password change (within 5 minutes) as well to ensure session
freshness.
This commit is contained in:
Max Peintner
2026-01-20 09:15:13 +00:00
committed by GitHub
parent 8c0d6c6817
commit 00481bd2dc
3 changed files with 21 additions and 114 deletions
@@ -51,25 +51,24 @@ export function ChangePasswordForm({ passwordComplexitySettings, sessionId, logi
async function submitChange(values: Inputs) {
setLoading(true);
const changeResponse = checkSessionAndSetPassword({
const changeResponse = await checkSessionAndSetPassword({
sessionId,
password: values.password,
})
.catch(() => {
setError(t("change.errors.couldNotChangePassword"));
return;
})
.finally(() => {
setLoading(false);
});
}).catch(() => {
setError(t("change.errors.couldNotChangePassword"));
setLoading(false);
return;
});
if (changeResponse && "error" in changeResponse && changeResponse.error) {
setError(typeof changeResponse.error === "string" ? changeResponse.error : t("change.errors.unknownError"));
setLoading(false);
return;
}
if (!changeResponse) {
setError(t("change.errors.couldNotChangePassword"));
setLoading(false);
return;
}