1
This commit is contained in:
@@ -65,7 +65,7 @@ pub async fn password_entry(
|
||||
fn map_password_entry_error(error: PasswordEntryError) -> AppError {
|
||||
match error {
|
||||
PasswordEntryError::InvalidUsername => AppError::from_status(StatusCode::BAD_REQUEST)
|
||||
.with_message("用户名只允许 3 到 24 位字母、数字、下划线")
|
||||
.with_message("手机号格式不正确")
|
||||
.with_details(json!({
|
||||
"field": "username",
|
||||
})),
|
||||
@@ -80,10 +80,10 @@ fn map_password_entry_error(error: PasswordEntryError) -> AppError {
|
||||
"field": "username",
|
||||
})),
|
||||
PasswordEntryError::InvalidCredentials => {
|
||||
AppError::from_status(StatusCode::UNAUTHORIZED).with_message("用户名或密码错误")
|
||||
AppError::from_status(StatusCode::UNAUTHORIZED).with_message("手机号或密码错误")
|
||||
}
|
||||
PasswordEntryError::UserNotFound => {
|
||||
AppError::from_status(StatusCode::UNAUTHORIZED).with_message("用户名或密码错误")
|
||||
AppError::from_status(StatusCode::UNAUTHORIZED).with_message("手机号或密码错误")
|
||||
}
|
||||
PasswordEntryError::Store(_) | PasswordEntryError::PasswordHash(_) => {
|
||||
AppError::from_status(StatusCode::INTERNAL_SERVER_ERROR).with_message(error.to_string())
|
||||
|
||||
@@ -475,24 +475,25 @@ impl PasswordEntryService {
|
||||
&self,
|
||||
input: PasswordEntryInput,
|
||||
) -> Result<PasswordEntryResult, PasswordEntryError> {
|
||||
let username = normalize_username(&input.username)?;
|
||||
validate_password(&input.password)?;
|
||||
|
||||
if let Some(existing_user) = self.store.find_by_username(&username)? {
|
||||
if !existing_user.password_login_enabled {
|
||||
// 登录面板现在固定使用手机号作为密码登录标识;先走手机号索引,
|
||||
// 再保留历史用户名路径给开发游客和旧测试数据使用。
|
||||
if let Ok(normalized_phone) = normalize_mainland_china_phone_number(&input.username) {
|
||||
let Some(existing_user) = self
|
||||
.store
|
||||
.find_by_phone_number_for_password(&normalized_phone.e164)?
|
||||
else {
|
||||
return Err(PasswordEntryError::InvalidCredentials);
|
||||
}
|
||||
let is_valid = verify_password(&existing_user.password_hash, &input.password)
|
||||
.await
|
||||
.map_err(|error| PasswordEntryError::PasswordHash(error.to_string()))?;
|
||||
if !is_valid {
|
||||
return Err(PasswordEntryError::InvalidCredentials);
|
||||
}
|
||||
};
|
||||
|
||||
return Ok(PasswordEntryResult {
|
||||
user: existing_user.user,
|
||||
created: false,
|
||||
});
|
||||
return verify_stored_password_user(existing_user, &input.password).await;
|
||||
}
|
||||
|
||||
let username = normalize_username(&input.username)?;
|
||||
|
||||
if let Some(existing_user) = self.store.find_by_username(&username)? {
|
||||
return verify_stored_password_user(existing_user, &input.password).await;
|
||||
}
|
||||
|
||||
Err(PasswordEntryError::InvalidCredentials)
|
||||
@@ -1292,6 +1293,24 @@ impl InMemoryAuthStore {
|
||||
.cloned())
|
||||
}
|
||||
|
||||
fn find_by_phone_number_for_password(
|
||||
&self,
|
||||
phone_number: &str,
|
||||
) -> Result<Option<StoredPasswordUser>, PasswordEntryError> {
|
||||
let state = self
|
||||
.inner
|
||||
.lock()
|
||||
.map_err(|_| PasswordEntryError::Store("用户仓储锁已中毒".to_string()))?;
|
||||
let Some(user_id) = state.phone_to_user_id.get(phone_number) else {
|
||||
return Ok(None);
|
||||
};
|
||||
Ok(state
|
||||
.users_by_username
|
||||
.values()
|
||||
.find(|stored_user| stored_user.user.id == *user_id)
|
||||
.cloned())
|
||||
}
|
||||
|
||||
fn create_phone_user(
|
||||
&self,
|
||||
phone_number: PhoneNumberSnapshot,
|
||||
@@ -2220,6 +2239,27 @@ fn validate_password(password: &str) -> Result<(), PasswordEntryError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn verify_stored_password_user(
|
||||
existing_user: StoredPasswordUser,
|
||||
password: &str,
|
||||
) -> Result<PasswordEntryResult, PasswordEntryError> {
|
||||
if !existing_user.password_login_enabled {
|
||||
return Err(PasswordEntryError::InvalidCredentials);
|
||||
}
|
||||
|
||||
let is_valid = verify_password(&existing_user.password_hash, password)
|
||||
.await
|
||||
.map_err(|error| PasswordEntryError::PasswordHash(error.to_string()))?;
|
||||
if !is_valid {
|
||||
return Err(PasswordEntryError::InvalidCredentials);
|
||||
}
|
||||
|
||||
Ok(PasswordEntryResult {
|
||||
user: existing_user.user,
|
||||
created: false,
|
||||
})
|
||||
}
|
||||
|
||||
fn verify_sms_code_format(verify_code: &str) -> Result<(), PhoneAuthError> {
|
||||
let verify_code = verify_code.trim();
|
||||
if verify_code.len() != SMS_CODE_LENGTH
|
||||
|
||||
Reference in New Issue
Block a user