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:
@@ -71,10 +71,7 @@ impl SettingService {
|
||||
/// If a record with the same (scope, scope_id, key) exists and is not
|
||||
/// soft-deleted, it will be updated. Otherwise a new record is inserted.
|
||||
pub async fn set(
|
||||
key: &str,
|
||||
scope: &str,
|
||||
scope_id: &Option<Uuid>,
|
||||
value: serde_json::Value,
|
||||
params: crate::dto::SetSettingParams,
|
||||
tenant_id: Uuid,
|
||||
operator_id: Uuid,
|
||||
db: &sea_orm::DatabaseConnection,
|
||||
@@ -83,9 +80,9 @@ impl SettingService {
|
||||
// Look for an existing non-deleted record
|
||||
let existing = setting::Entity::find()
|
||||
.filter(setting::Column::TenantId.eq(tenant_id))
|
||||
.filter(setting::Column::Scope.eq(scope))
|
||||
.filter(setting::Column::ScopeId.eq(*scope_id))
|
||||
.filter(setting::Column::SettingKey.eq(key))
|
||||
.filter(setting::Column::Scope.eq(¶ms.scope))
|
||||
.filter(setting::Column::ScopeId.eq(params.scope_id))
|
||||
.filter(setting::Column::SettingKey.eq(¶ms.key))
|
||||
.filter(setting::Column::DeletedAt.is_null())
|
||||
.one(db)
|
||||
.await
|
||||
@@ -94,7 +91,7 @@ impl SettingService {
|
||||
if let Some(model) = existing {
|
||||
// Update existing record
|
||||
let mut active: setting::ActiveModel = model.into();
|
||||
active.setting_value = Set(value.clone());
|
||||
active.setting_value = Set(params.value.clone());
|
||||
active.updated_at = Set(Utc::now());
|
||||
active.updated_by = Set(operator_id);
|
||||
|
||||
@@ -108,8 +105,8 @@ impl SettingService {
|
||||
tenant_id,
|
||||
serde_json::json!({
|
||||
"setting_id": updated.id,
|
||||
"key": key,
|
||||
"scope": scope,
|
||||
"key": params.key,
|
||||
"scope": params.scope,
|
||||
}),
|
||||
));
|
||||
|
||||
@@ -121,10 +118,10 @@ impl SettingService {
|
||||
let model = setting::ActiveModel {
|
||||
id: Set(id),
|
||||
tenant_id: Set(tenant_id),
|
||||
scope: Set(scope.to_string()),
|
||||
scope_id: Set(*scope_id),
|
||||
setting_key: Set(key.to_string()),
|
||||
setting_value: Set(value),
|
||||
scope: Set(params.scope.clone()),
|
||||
scope_id: Set(params.scope_id),
|
||||
setting_key: Set(params.key.clone()),
|
||||
setting_value: Set(params.value),
|
||||
created_at: Set(now),
|
||||
updated_at: Set(now),
|
||||
created_by: Set(operator_id),
|
||||
@@ -142,8 +139,8 @@ impl SettingService {
|
||||
tenant_id,
|
||||
serde_json::json!({
|
||||
"setting_id": id,
|
||||
"key": key,
|
||||
"scope": scope,
|
||||
"key": params.key,
|
||||
"scope": params.scope,
|
||||
}),
|
||||
));
|
||||
|
||||
@@ -171,7 +168,7 @@ impl SettingService {
|
||||
.await
|
||||
.map_err(|e| ConfigError::Validation(e.to_string()))?;
|
||||
|
||||
let page_index = pagination.page.unwrap_or(1).saturating_sub(1) as u64;
|
||||
let page_index = pagination.page.unwrap_or(1).saturating_sub(1);
|
||||
let models = paginator
|
||||
.fetch_page(page_index)
|
||||
.await
|
||||
@@ -248,7 +245,7 @@ impl SettingService {
|
||||
/// Returns a list of (scope, scope_id) tuples to try in order.
|
||||
fn fallback_chain(
|
||||
scope: &str,
|
||||
scope_id: &Option<Uuid>,
|
||||
_scope_id: &Option<Uuid>,
|
||||
tenant_id: Uuid,
|
||||
) -> ConfigResult<Vec<(String, Option<Uuid>)>> {
|
||||
match scope {
|
||||
|
||||
Reference in New Issue
Block a user