dca717be10
- Replace workspace_id parameter with Workspace object reference in all workspace service methods - Remove redundant find_workspace_by_id calls that were duplicated in each method - Update all method signatures across approval, audit, billing, branding, core, settings and stats modules - Modify SQL queries to bind ws.id instead of separate workspace_id parameter - Add Workspace import to all affected modules - Adjust method calls in API handlers to pass workspace object instead of id - Consolidate workspace retrieval logic to single location per operation flow
55 lines
2.3 KiB
Rust
55 lines
2.3 KiB
Rust
use actix_web::{HttpResponse, web};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::api::response::{ApiErrorResponse, ApiResponse};
|
|
use crate::error::AppError;
|
|
use crate::service::AppService;
|
|
use crate::session::Session;
|
|
|
|
#[derive(Debug, Clone, Deserialize, Serialize, utoipa::ToSchema)]
|
|
pub struct Regenerate2FABackupCodesRequest {
|
|
/// Current account password encrypted with the session RSA public key.
|
|
pub password: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, utoipa::ToSchema)]
|
|
pub struct Regenerate2FABackupCodesResponse {
|
|
/// Newly generated one-time backup codes. Old backup codes become invalid.
|
|
pub backup_codes: Vec<String>,
|
|
}
|
|
|
|
#[utoipa::path(
|
|
post,
|
|
path = "/api/v1/auth/2fa/backup-codes/regenerate",
|
|
tag = "Auth",
|
|
operation_id = "authRegenerateTwoFactorBackupCodes",
|
|
summary = "Regenerate 2FA backup codes",
|
|
description = "After verifying the current password, generate a new set of backup codes for a user with 2FA enabled and replace the old backup codes. password must be encrypted with the current session RSA public key. Backup codes are returned in plaintext only once in this response; clients must prompt users to store them securely.",
|
|
request_body(
|
|
content = Regenerate2FABackupCodesRequest,
|
|
description = "The current account password encrypted with RSA.",
|
|
content_type = "application/json"
|
|
),
|
|
responses(
|
|
(status = 200, description = "Backup codes have been regenerated; old backup codes are immediately invalidated.", body = ApiResponse<Regenerate2FABackupCodesResponse>),
|
|
(status = 400, description = "2FA is not enabled, the password is incorrect, or RSA decryption failed.", body = ApiErrorResponse),
|
|
(status = 401, description = "The current session is not authenticated.", body = ApiErrorResponse),
|
|
(status = 500, description = "Database write or backup code hashing failed.", body = ApiErrorResponse)
|
|
)
|
|
)]
|
|
pub async fn handle(
|
|
service: web::Data<AppService>,
|
|
session: Session,
|
|
params: web::Json<Regenerate2FABackupCodesRequest>,
|
|
) -> Result<HttpResponse, AppError> {
|
|
let backup_codes = service
|
|
.auth
|
|
.auth_2fa_regenerate_backup_codes(&session, params.into_inner().password)
|
|
.await?;
|
|
Ok(
|
|
HttpResponse::Ok().json(ApiResponse::new(Regenerate2FABackupCodesResponse {
|
|
backup_codes,
|
|
})),
|
|
)
|
|
}
|