feat: add configurable verification and redemption codes

This commit is contained in:
237899745
2026-07-25 13:57:39 +08:00
parent d1f093685d
commit c6e96464d3
32 changed files with 2108 additions and 261 deletions

View File

@@ -3,6 +3,7 @@ use crate::api::envelope::Envelope;
use crate::error::{AppError, ErrorCode};
use crate::services::billing;
use crate::services::mail;
use crate::services::settings;
use crate::state::AppState;
use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
@@ -98,6 +99,8 @@ async fn get_profile(
.await
.map_err(|err| AppError::new(ErrorCode::Internal, "查询用户失败").with_source(err))?;
let verification_required = settings::email_verification_required(&state).await?;
Ok(Json(Envelope {
success: true,
data: UserView {
@@ -105,7 +108,7 @@ async fn get_profile(
email: user.email,
username: user.username,
role: user.role,
email_verified: user.email_verified_at.is_some(),
email_verified: user.email_verified_at.is_some() || !verification_required,
},
}))
}
@@ -165,6 +168,7 @@ async fn update_profile(
let mut next_email = user.email.clone();
let mut next_username = user.username.clone();
let mut email_changed = false;
let verification_required = settings::email_verification_required(&state).await?;
if let Some(email) = req.email.as_ref() {
let email = email.trim().to_lowercase();
@@ -192,7 +196,7 @@ async fn update_profile(
email: user.email,
username: user.username,
role: user.role,
email_verified: user.email_verified_at.is_some(),
email_verified: user.email_verified_at.is_some() || !verification_required,
},
message: "暂无更新".to_string(),
},
@@ -205,8 +209,10 @@ async fn update_profile(
.await
.map_err(|err| AppError::new(ErrorCode::Internal, "开启事务失败").with_source(err))?;
let email_verified_at = if email_changed {
let email_verified_at = if email_changed && verification_required {
None
} else if email_changed {
Some(Utc::now())
} else {
user.email_verified_at
};
@@ -231,7 +237,7 @@ async fn update_profile(
.map_err(map_unique_violation)?;
let mut verification_link: Option<String> = None;
if email_changed {
if email_changed && verification_required {
let token = generate_token();
let token_hash = sha256_hex(&token);
let expires_at = Utc::now() + Duration::hours(24);
@@ -269,7 +275,7 @@ async fn update_profile(
})?;
}
let message = if email_changed {
let message = if email_changed && verification_required {
"资料已更新,请验证新邮箱".to_string()
} else {
"资料已更新".to_string()
@@ -283,7 +289,7 @@ async fn update_profile(
email: updated.email,
username: updated.username,
role: updated.role,
email_verified: updated.email_verified_at.is_some(),
email_verified: updated.email_verified_at.is_some() || !verification_required,
},
message,
},