115 lines
3.6 KiB
Rust
115 lines
3.6 KiB
Rust
use actix_files as fs;
|
|
use actix_web::{App, HttpServer, web};
|
|
use actix_web::middleware::Logger;
|
|
use tera::Tera;
|
|
use std::io;
|
|
use std::env;
|
|
use lazy_static::lazy_static;
|
|
|
|
mod config;
|
|
mod controllers;
|
|
mod middleware;
|
|
mod models;
|
|
mod routes;
|
|
mod utils;
|
|
|
|
// Import middleware components
|
|
use middleware::{RequestTimer, SecurityHeaders, JwtAuth};
|
|
use utils::redis_service;
|
|
use models::initialize_mock_data;
|
|
|
|
// Initialize lazy_static for in-memory storage
|
|
extern crate lazy_static;
|
|
|
|
// Create a consistent session key
|
|
lazy_static! {
|
|
pub static ref SESSION_KEY: actix_web::cookie::Key = {
|
|
// In production, this should be a proper secret key from environment variables
|
|
let secret = std::env::var("SESSION_SECRET").unwrap_or_else(|_| {
|
|
// Create a key that's at least 64 bytes long
|
|
"my_secret_session_key_that_is_at_least_64_bytes_long_for_security_reasons_1234567890abcdef".to_string()
|
|
});
|
|
|
|
// Ensure the key is at least 64 bytes
|
|
let mut key_bytes = secret.as_bytes().to_vec();
|
|
while key_bytes.len() < 64 {
|
|
key_bytes.extend_from_slice(b"0123456789abcdef");
|
|
}
|
|
|
|
actix_web::cookie::Key::from(&key_bytes[0..64])
|
|
};
|
|
}
|
|
|
|
#[actix_web::main]
|
|
async fn main() -> io::Result<()> {
|
|
// Initialize environment
|
|
dotenv::dotenv().ok();
|
|
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
|
|
|
|
// Load configuration
|
|
let config = config::get_config();
|
|
|
|
// Check for port override from command line arguments
|
|
let args: Vec<String> = env::args().collect();
|
|
let mut port = config.server.port;
|
|
|
|
for i in 1..args.len() {
|
|
if args[i] == "--port" && i + 1 < args.len() {
|
|
if let Ok(p) = args[i + 1].parse::<u16>() {
|
|
port = p;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
let bind_address = format!("{}:{}", config.server.host, port);
|
|
|
|
// Initialize Redis client
|
|
let redis_url = std::env::var("REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
|
|
if let Err(e) = redis_service::init_redis_client(&redis_url) {
|
|
log::error!("Failed to initialize Redis client: {}", e);
|
|
log::warn!("Calendar functionality will not work properly without Redis");
|
|
} else {
|
|
log::info!("Redis client initialized successfully");
|
|
}
|
|
|
|
// Initialize mock data for DeFi operations
|
|
initialize_mock_data();
|
|
log::info!("DeFi mock data initialized successfully");
|
|
|
|
log::info!("Starting server at http://{}", bind_address);
|
|
|
|
// Create and configure the HTTP server
|
|
HttpServer::new(move || {
|
|
// Initialize Tera templates
|
|
let mut tera = match Tera::new(&format!("{}/**/*.html", config.templates.dir)) {
|
|
Ok(t) => t,
|
|
Err(e) => {
|
|
log::error!("Parsing error(s): {}", e);
|
|
::std::process::exit(1);
|
|
}
|
|
};
|
|
|
|
// Register custom Tera functions
|
|
utils::register_tera_functions(&mut tera);
|
|
|
|
App::new()
|
|
// Enable logger middleware
|
|
.wrap(Logger::default())
|
|
// Add custom middleware
|
|
.wrap(RequestTimer)
|
|
.wrap(SecurityHeaders)
|
|
.wrap(JwtAuth)
|
|
// Configure static files
|
|
.service(fs::Files::new("/static", "./src/static"))
|
|
// Add Tera template engine
|
|
.app_data(web::Data::new(tera))
|
|
// Configure routes
|
|
.configure(routes::configure_routes)
|
|
})
|
|
.bind(bind_address)?
|
|
.workers(num_cpus::get())
|
|
.run()
|
|
.await
|
|
}
|