2.4 KiB
App Forgot Password Design
Goal
Make POST /app/v1/retrievePassword a secure unauthenticated password recovery endpoint based on an account identifier, verification code, and new password.
Request Contract
The encrypted JSON request contains:
{
"username": "phone, email, or account name",
"code": "123456",
"password": "new password"
}
For backward compatibility, userName is accepted as an alias of username, and smsCode is accepted as an alias of code.
Endpoint Behavior
- Preserve
POST /app/v1/retrievePasswordand@ApiEncrypt. - Add method-level
@SaIgnoreso a logged-out user can recover their password. - Validate required fields and the existing password length rule before invoking the service.
- Do not read
LoginHelperor rely on a token.
Service Behavior
Add a shared ISysUserService.resetPasswordByVerificationCode(username, code, password) operation:
- Detect email, mobile number, or account name and query the matching active user record.
- Read
GlobalConstants.CAPTCHA_CODE_KEY + usernamefrom Redis. - Reject missing/expired and mismatched codes without updating the database.
- BCrypt-hash the new password and update only the matched user ID.
- Delete the verification code only after a successful database update so it cannot be replayed.
The existing /auth/forgot service delegates to the same operation to avoid two conflicting reset implementations.
Verification Code Delivery
Keep GET /resource/code?username=.... For a mobile number or email, send directly as before. For an account name, load the account and send to its bound mobile number, otherwise its bound email, while storing the code under the original account-name cache key. Do not return the generated code to the client.
Error Handling
- Missing account: user-facing account-not-registered error.
- Missing Redis code: existing
CaptchaExpireException. - Wrong code: user-facing invalid-code error.
- Failed database update:
ServiceExceptionhandled by the global exception handler.
Testing
- Controller test proves recovery works without login state and delegates all three values.
- System service tests cover success, wrong code, expired code, account lookup, BCrypt hashing, and one-time code deletion.
- Captcha controller test covers account-name delivery to a bound contact with the original username as cache key.
- Run focused tests, then
water-app,water-admin, and relevant reactor tests.