# 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:

```json
{
  "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/retrievePassword` and `@ApiEncrypt`.
- Add method-level `@SaIgnore` so a logged-out user can recover their password.
- Validate required fields and the existing password length rule before invoking the service.
- Do not read `LoginHelper` or rely on a token.

## Service Behavior

Add a shared `ISysUserService.resetPasswordByVerificationCode(username, code, password)` operation:

1. Detect email, mobile number, or account name and query the matching active user record.
2. Read `GlobalConstants.CAPTCHA_CODE_KEY + username` from Redis.
3. Reject missing/expired and mismatched codes without updating the database.
4. BCrypt-hash the new password and update only the matched user ID.
5. 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: `ServiceException` handled 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.
