adminx/configs/
initializer.rs1use log::{info, debug, warn};
3use mongodb::Database;
4use anyhow::{Error as AnyhowError};
5use actix_web::{web};
6use actix_session::{SessionMiddleware, storage::CookieSessionStore, config::PersistentSession};
7use actix_web::cookie::{Key, SameSite};
8use env_logger::Env;
9use std::{env, time::Duration};
10use crate::router::register_all_admix_routes;
11use crate::utils::{
12 database::{
13 initiate_database
14 },
15};
16
17#[derive(Debug, Clone)]
18pub struct AdminxConfig {
19 pub jwt_secret: String,
20 pub session_secret: String,
21 pub environment: String,
22 pub log_level: String,
23 pub session_timeout: Duration,
24}
25
26impl AdminxConfig {
27 pub fn from_env() -> Result<Self, Box<dyn std::error::Error>> {
28 Ok(Self {
29 jwt_secret: env::var("JWT_SECRET")
30 .map_err(|_| "JWT_SECRET is required")?,
31 session_secret: env::var("SESSION_SECRET")
32 .unwrap_or_else(|_| {
33 if cfg!(debug_assertions) {
34 warn!("⚠️ SESSION_SECRET not set, using generated key - NOT suitable for production!");
35 String::new() } else {
37 panic!("SESSION_SECRET is required in production");
38 }
39 }),
40 environment: env::var("ENVIRONMENT")
41 .unwrap_or_else(|_| "development".to_string()),
42 log_level: env::var("RUST_LOG")
43 .unwrap_or_else(|_| "debug".to_string()),
44 session_timeout: Duration::from_secs(
45 env::var("SESSION_TIMEOUT")
46 .unwrap_or_else(|_| "86400".to_string())
47 .parse()
48 .unwrap_or(86400)
49 ),
50 })
51 }
52
53 pub fn is_production(&self) -> bool {
54 self.environment == "production"
55 }
56}
57
58fn load_session_key(config: &AdminxConfig) -> Key {
59 if config.session_secret.is_empty() {
60 if cfg!(debug_assertions) {
61 warn!("⚠️ Using generated session key - NOT suitable for production!");
62 Key::generate()
63 } else {
64 panic!("SESSION_SECRET environment variable is required in production");
65 }
66 } else {
67 if config.session_secret.len() < 64 {
68 panic!("SESSION_SECRET must be at least 64 characters long");
69 }
70 Key::from(config.session_secret.as_bytes())
71 }
72}
73
74fn create_session_middleware(config: &AdminxConfig) -> SessionMiddleware<CookieSessionStore> {
75 let secret_key = load_session_key(config);
76
77 let session_ttl = actix_web::cookie::time::Duration::seconds(config.session_timeout.as_secs() as i64);
79
80 SessionMiddleware::builder(
81 CookieSessionStore::default(),
82 secret_key
83 )
84 .cookie_name("adminx_session".to_string())
85 .cookie_secure(config.is_production())
86 .cookie_http_only(true)
87 .cookie_same_site(if config.is_production() {
88 SameSite::Strict
89 } else {
90 SameSite::Lax
91 })
92 .session_lifecycle(
93 PersistentSession::default()
94 .session_ttl(session_ttl)
95 )
96 .build()
97}
98
99pub fn get_adminx_config() -> AdminxConfig {
101 AdminxConfig::from_env().unwrap_or_else(|e| {
102 eprintln!("❌ AdminX configuration error: {}", e);
103 std::process::exit(1);
104 })
105}
106
107pub fn setup_adminx_logging(config: &AdminxConfig) {
108 if env::var("ADMINX_LOGGING_INITIALIZED").is_err() {
109 let _ = env_logger::Builder::from_env(Env::default().default_filter_or(&config.log_level))
110 .format_timestamp_millis()
111 .try_init();
112
113 env::set_var("ADMINX_LOGGING_INITIALIZED", "true");
114 info!("✅ AdminX logging initialized");
115 info!("🔧 AdminX environment: {}", config.environment);
116 debug!("🔍 AdminX debug logging active");
117 }
118}
119
120pub fn get_adminx_session_middleware(config: &AdminxConfig) -> SessionMiddleware<CookieSessionStore> {
121 create_session_middleware(config)
122}
123
124pub fn configure_adminx_services(cfg: &mut web::ServiceConfig) {
126 let config = get_adminx_config();
127 cfg.app_data(web::Data::new(config));
128 cfg.service(register_all_admix_routes());
129
130}
131
132pub async fn adminx_initialize(db: Database) -> Result<(), AnyhowError> {
133 let _ = initiate_database(db);
134 info!("AdminX initialized successfully");
136 Ok(())
137}