feat(auth): add comprehensive authentication system with 2FA support

- Add new auth module with captcha, login, logout, register, and email verification endpoints
- Implement two-factor authentication with TOTP enable, disable, verify, and backup codes regeneration
- Create RSA public key endpoint for secure password encryption
- Add user profile management with get current user and email retrieval
- Integrate OpenAPI documentation for all authentication endpoints
- Implement password reset functionality with email verification flow
- Add comprehensive API response structures with proper error handling
- Configure all auth routes under /api/v1/auth scope with proper tagging
This commit is contained in:
zhenyi
2026-06-07 18:09:38 +08:00
parent 2bb5834167
commit 0d3b53f7a0
24 changed files with 816 additions and 10 deletions
+34
View File
@@ -0,0 +1,34 @@
use actix_web::{HttpResponse, web};
use crate::api::response::{ApiEmptyResponse, ApiErrorResponse};
use crate::error::AppError;
use crate::service::AppService;
use crate::service::auth::email::EmailVerifyRequest;
#[utoipa::path(
post,
path = "/api/v1/auth/email/verify",
tag = "Auth",
operation_id = "authVerifyEmailChange",
summary = "Confirm email change",
description = "Complete an email change using the token from the confirmation email. The endpoint checks again whether the target email is already taken, then marks old emails as unverified and inserts the new verified primary email in a transaction.",
request_body(
content = EmailVerifyRequest,
description = "Email change confirmation token.",
content_type = "application/json"
),
responses(
(status = 200, description = "Email changed successfully.", body = ApiEmptyResponse),
(status = 400, description = "The token is empty.", body = ApiErrorResponse),
(status = 404, description = "The token is invalid or expired.", body = ApiErrorResponse),
(status = 409, description = "The target email was taken by another account before confirmation.", body = ApiErrorResponse),
(status = 500, description = "Database transaction failed.", body = ApiErrorResponse)
)
)]
pub async fn handle(
service: web::Data<AppService>,
params: web::Json<EmailVerifyRequest>,
) -> Result<HttpResponse, AppError> {
service.auth.auth_email_verify(params.into_inner()).await?;
Ok(HttpResponse::Ok().json(ApiEmptyResponse::ok("email verified")))
}