pub mod audit_log; pub mod menu_config; pub mod permission_inheritance; pub mod rbac; pub mod rbac_ui; pub mod security_admin; use axum::{ extract::State, response::{Html, Json}, routing::{get, post}, Router, }; use serde::{Deserialize, Serialize}; use std::sync::Arc; use crate::shared::state::AppState; pub fn configure_settings_routes() -> Router> { Router::new() .route("/api/user/storage", get(get_storage_info)) .route("/api/user/storage/connections", get(get_storage_connections)) .route("/api/user/security/2fa/status", get(get_2fa_status)) .route("/api/user/security/2fa/enable", post(enable_2fa)) .route("/api/user/security/2fa/disable", post(disable_2fa)) .route("/api/user/security/sessions", get(get_active_sessions)) .route( "/api/user/security/sessions/revoke-all", post(revoke_all_sessions), ) .route("/api/user/security/devices", get(get_trusted_devices)) .route("/api/settings/search", post(save_search_settings)) .route("/api/settings/smtp/test", post(test_smtp_connection)) .route("/api/settings/accounts/social", get(get_accounts_social)) .route("/api/settings/accounts/messaging", get(get_accounts_messaging)) .route("/api/settings/accounts/email", get(get_accounts_email)) .route("/api/settings/accounts/smtp", post(save_smtp_account)) .route("/api/ops/health", get(get_ops_health)) .route("/api/rbac/permissions", get(get_rbac_permissions)) .merge(rbac::configure_rbac_routes()) .merge(security_admin::configure_security_admin_routes()) } async fn get_accounts_social(State(_state): State>) -> Html { Html(r##"
"##.to_string()) } async fn get_accounts_messaging(State(_state): State>) -> Html { Html(r##"
"##.to_string()) } async fn get_accounts_email(State(_state): State>) -> Html { Html(r##"
"##.to_string()) } async fn save_smtp_account( State(_state): State>, Json(config): Json, ) -> Json { Json(serde_json::json!({ "success": true, "message": "SMTP configuration saved", "config": config })) } async fn get_ops_health(State(_state): State>) -> Json { Json(serde_json::json!({ "status": "healthy", "services": { "api": {"status": "up", "latency_ms": 12}, "database": {"status": "up", "latency_ms": 5}, "cache": {"status": "up", "latency_ms": 1}, "storage": {"status": "up", "latency_ms": 8} }, "timestamp": chrono::Utc::now().to_rfc3339() })) } async fn get_rbac_permissions(State(_state): State>) -> Json { Json(serde_json::json!({ "permissions": [ {"id": "read:users", "name": "Read Users", "category": "Users"}, {"id": "write:users", "name": "Write Users", "category": "Users"}, {"id": "delete:users", "name": "Delete Users", "category": "Users"}, {"id": "read:bots", "name": "Read Bots", "category": "Bots"}, {"id": "write:bots", "name": "Write Bots", "category": "Bots"}, {"id": "admin:billing", "name": "Manage Billing", "category": "Admin"}, {"id": "admin:settings", "name": "Manage Settings", "category": "Admin"} ] })) } async fn get_storage_info(State(_state): State>) -> Html { Html( r##"
2.5 GB used of 10 GB
📄 Documents 1.2 GB
🖼️ Images 800 MB
📧 Emails 500 MB
s
"## .to_string(), ) } async fn get_storage_connections(State(_state): State>) -> Html { Html( r##"

No external storage connections configured

"## .to_string(), ) } #[derive(Debug, Deserialize)] #[allow(dead_code)] struct SearchSettingsRequest { enable_fuzzy_search: Option, search_result_limit: Option, enable_ai_suggestions: Option, index_attachments: Option, search_sources: Option>, } #[derive(Debug, Serialize)] struct SearchSettingsResponse { success: bool, message: Option, error: Option, } async fn save_search_settings( State(_state): State>, Json(settings): Json, ) -> Json { // In a real implementation, save to database log::info!("Saving search settings: fuzzy={:?}, limit={:?}, ai={:?}", settings.enable_fuzzy_search, settings.search_result_limit, settings.enable_ai_suggestions ); Json(SearchSettingsResponse { success: true, message: Some("Search settings saved successfully".to_string()), error: None, }) } #[derive(Debug, Deserialize)] #[allow(dead_code)] struct SmtpTestRequest { host: String, port: i32, username: Option, password: Option, use_tls: Option, } #[derive(Debug, Serialize)] struct SmtpTestResponse { success: bool, message: Option, error: Option, } #[cfg(feature = "mail")] async fn test_smtp_connection( State(_state): State>, Json(config): Json, ) -> Json { use lettre::SmtpTransport; use lettre::transport::smtp::authentication::Credentials; log::info!("Testing SMTP connection to {}:{}", config.host, config.port); let mailer_result = if let (Some(user), Some(pass)) = (config.username, config.password) { let creds = Credentials::new(user, pass); SmtpTransport::relay(&config.host) .map(|b| b.port(config.port as u16).credentials(creds).build()) } else { Ok(SmtpTransport::builder_dangerous(&config.host) .port(config.port as u16) .build()) }; match mailer_result { Ok(mailer) => { match mailer.test_connection() { Ok(true) => Json(SmtpTestResponse { success: true, message: Some("SMTP connection successful".to_string()), error: None, }), Ok(false) => Json(SmtpTestResponse { success: false, message: None, error: Some("SMTP connection test failed".to_string()), }), Err(e) => Json(SmtpTestResponse { success: false, message: None, error: Some(format!("SMTP error: {}", e)), }), } } Err(e) => Json(SmtpTestResponse { success: false, message: None, error: Some(format!("Failed to create SMTP transport: {}", e)), }), } } #[cfg(not(feature = "mail"))] async fn test_smtp_connection( State(_state): State>, Json(_config): Json, ) -> Json { Json(SmtpTestResponse { success: false, message: None, error: Some("SMTP email feature is not enabled in this build".to_string()), }) } async fn get_2fa_status(State(_state): State>) -> Html { Html( r##"
Two-factor authentication is not enabled
"## .to_string(), ) } async fn enable_2fa(State(_state): State>) -> Html { Html( r##"
Two-factor authentication enabled
"## .to_string(), ) } async fn disable_2fa(State(_state): State>) -> Html { Html( r##"
Two-factor authentication disabled
"## .to_string(), ) } async fn get_active_sessions(State(_state): State>) -> Html { Html( r##"
💻 Current Session This device
Current browser session Active now

No other active sessions

"## .to_string(), ) } async fn revoke_all_sessions(State(_state): State>) -> Html { Html( r##"
All other sessions have been revoked
"## .to_string(), ) } async fn get_trusted_devices(State(_state): State>) -> Html { Html( r##"
💻
Current Device Last active: Just now
Trusted

No other trusted devices

"## .to_string(), ) }