feat(auth): add change password API and frontend page
Backend: - Add ChangePasswordReq DTO with validation (current + new password) - Add AuthService::change_password() method with credential verification, password rehash, and token revocation - Add POST /api/v1/auth/change-password endpoint with utoipa annotation Frontend: - Add changePassword() API function in auth.ts - Add ChangePassword.tsx page with form validation and confirmation - Add "修改密码" tab in Settings page After password change, all refresh tokens are revoked and the user is redirected to the login page.
This commit is contained in:
@@ -26,6 +26,15 @@ pub struct RefreshReq {
|
||||
pub refresh_token: String,
|
||||
}
|
||||
|
||||
/// 修改密码请求
|
||||
#[derive(Debug, Deserialize, Validate, ToSchema)]
|
||||
pub struct ChangePasswordReq {
|
||||
#[validate(length(min = 1, message = "当前密码不能为空"))]
|
||||
pub current_password: String,
|
||||
#[validate(length(min = 6, max = 128, message = "新密码长度需在6-128之间"))]
|
||||
pub new_password: String,
|
||||
}
|
||||
|
||||
// --- User DTOs ---
|
||||
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
@@ -234,6 +243,42 @@ mod tests {
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_password_req_valid() {
|
||||
let req = ChangePasswordReq {
|
||||
current_password: "oldPassword123".to_string(),
|
||||
new_password: "newPassword456".to_string(),
|
||||
};
|
||||
assert!(req.validate().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_password_req_empty_current_fails() {
|
||||
let req = ChangePasswordReq {
|
||||
current_password: "".to_string(),
|
||||
new_password: "newPassword456".to_string(),
|
||||
};
|
||||
assert!(req.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_password_req_short_new_fails() {
|
||||
let req = ChangePasswordReq {
|
||||
current_password: "oldPassword123".to_string(),
|
||||
new_password: "12345".to_string(), // min 6
|
||||
};
|
||||
assert!(req.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn change_password_req_long_new_fails() {
|
||||
let req = ChangePasswordReq {
|
||||
current_password: "oldPassword123".to_string(),
|
||||
new_password: "a".repeat(129), // max 128
|
||||
};
|
||||
assert!(req.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn login_req_empty_password_fails() {
|
||||
let req = LoginReq {
|
||||
|
||||
Reference in New Issue
Block a user