omega/src/main.rs
2026-08-20 17:05:37 +02:00

117 lines
3.4 KiB
Rust

mod api;
mod config;
mod db;
pub mod error;
mod identity;
mod models;
mod server;
mod sql;
mod state;
mod transport;
mod util;
pub use error::{OmegaError, Result};
use crate::db::initialize;
use crate::state::OmegaState;
use crate::transport::omikron_connection;
use crate::util::file_util::get_directory;
use crate::util::logger::PrintType;
use crate::util::logger::startup;
use crate::{config::OmegaConfig, server::middleware};
use dotenv::from_path;
use rustls::crypto::aws_lc_rs::default_provider;
use std::env;
use std::path::Path;
use std::time::Duration;
use tokio::time::interval;
use zeroize::Zeroizing;
#[tokio::main]
async fn main() {
if default_provider().install_default().is_err() {
println!("Error loading Provider");
return;
}
let _ = from_path(Path::new(&get_directory()).join(".env"));
startup();
log_in!("Incoming messages");
log_out!("Outgoing messages");
let identity_secret = match env::var("OMEGA_IDENTITY_SECRET") {
Ok(secret) if !secret.is_empty() => secret,
Ok(_) => {
log!("[FATAL] OMEGA_IDENTITY_SECRET must not be empty");
return;
}
Err(error) => {
log!("[FATAL] Unable to load OMEGA_IDENTITY_SECRET: {}", error);
return;
}
};
let identity_secret = Zeroizing::new(identity_secret);
let config = match OmegaConfig::from_env() {
Ok(config) => config,
Err(error) => {
log!("[FATAL] Omega configuration is invalid: {}", error);
return;
}
};
if middleware::initialize_config(config.rate_limits.clone()).is_err() {
log!("[FATAL] Omega rate-limit configuration was initialized more than once");
return;
}
let identity = match identity::OmegaIdentity::load_or_create(identity_secret.as_bytes()) {
Ok(identity) => identity,
Err(error) => {
log!("[FATAL] Omega identity initialization failed: {}", error);
return;
}
};
drop(identity_secret);
let state = OmegaState::new(identity, config);
log!("Started");
log!(" .env");
if let Err(e) = initialize().await {
log!("[FATAL] Database initialization failed: {}", e);
log!(
"[FATAL] Please ensure the database is running and the .env file is configured correctly."
);
return;
} else {
log!(" DB");
}
let rate_limit_cleanup = crate::server::middleware::spawn_cleanup_task();
let short_link_cleanup = tokio::spawn(async {
let mut ticker = interval(Duration::from_secs(24 * 60 * 60));
loop {
ticker.tick().await;
if let Err(error) = crate::db::short_link_repo::delete_expired().await {
log_err!(
0,
PrintType::General,
"Short-link cleanup failed: {}",
error
);
}
}
});
let port: u16 = env::var("PORT")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(443);
tokio::select! {
result = omikron_connection::start(port, state) => {
if let Err(e) = result {
log_err!(0, PrintType::General, "Server error: {:?}", e);
}
}
_ = tokio::signal::ctrl_c() => {
log!("Shutting down on signal...");
}
}
rate_limit_cleanup.abort();
short_link_cleanup.abort();
}