fix: address Phase 1-2 audit findings

- CORS: replace permissive() with configurable whitelist (default.toml)
- Auth store: synchronously restore state at creation to eliminate
  flash-of-login-page on refresh
- MainLayout: menu highlight now tracks current route via useLocation
- Add extractErrorMessage() utility to reduce repeated error parsing
- Fix all clippy warnings across 4 crates (erp-auth, erp-config,
  erp-workflow, erp-message): remove unnecessary casts, use div_ceil,
  collapse nested ifs, reduce function arguments with DTOs
This commit is contained in:
iven
2026-04-11 12:36:34 +08:00
parent 5c899e6f4a
commit 3a05523d23
35 changed files with 283 additions and 187 deletions

View File

@@ -1,6 +1,7 @@
use axum::Extension;
use axum::extract::{FromRef, Path, Query, State};
use axum::response::Json;
use validator::Validate;
use erp_core::error::AppError;
use erp_core::rbac::require_permission;
@@ -28,7 +29,7 @@ where
let page = pagination.page.unwrap_or(1);
let page_size = pagination.limit();
let total_pages = (total + page_size - 1) / page_size;
let total_pages = total.div_ceil(page_size);
Ok(Json(ApiResponse::ok(PaginatedResponse {
data: tasks,
@@ -56,7 +57,7 @@ where
let page = pagination.page.unwrap_or(1);
let page_size = pagination.limit();
let total_pages = (total + page_size - 1) / page_size;
let total_pages = total.div_ceil(page_size);
Ok(Json(ApiResponse::ok(PaginatedResponse {
data: tasks,
@@ -79,6 +80,7 @@ where
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "workflow:approve")?;
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
let resp = TaskService::complete(
id,
@@ -105,6 +107,7 @@ where
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "workflow:delegate")?;
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
let resp =
TaskService::delegate(id, ctx.tenant_id, ctx.user_id, &req, &state.db).await?;