use std::error::Error; use std::time::Duration; use actix_request_identifier::RequestIdentifier; use actix_web::{App, HttpResponse, HttpServer, post, web::{Data, Json, JsonConfig}}; use log::{error, info, Level}; use sea_orm::{ConnectOptions, Database, DatabaseConnection}; use serde::{Serialize, Deserialize}; use trifid_api_migration::{Migrator, MigratorTrait}; use crate::config::CONFIG; use crate::error::{APIError, APIErrorsResponse}; use crate::tokens::random_id_no_id; pub mod config; pub mod routes; pub mod error; pub mod tokens; pub mod timers; pub mod magic_link; pub mod auth_tokens; pub struct AppState { pub conn: DatabaseConnection } #[actix_web::main] async fn main() -> Result<(), Box> { simple_logger::init_with_level(Level::Debug).unwrap(); info!("Connecting to database at {}...", CONFIG.database.url); let mut opt = ConnectOptions::new(CONFIG.database.url.clone()); opt.max_connections(CONFIG.database.max_connections) .min_connections(CONFIG.database.min_connections) .connect_timeout(Duration::from_secs(CONFIG.database.connect_timeout)) .acquire_timeout(Duration::from_secs(CONFIG.database.acquire_timeout)) .idle_timeout(Duration::from_secs(CONFIG.database.idle_timeout)) .max_lifetime(Duration::from_secs(CONFIG.database.max_lifetime)) .sqlx_logging(CONFIG.database.sqlx_logging) .sqlx_logging_level(log::LevelFilter::Info); let db = Database::connect(opt).await?; info!("Performing database migration..."); Migrator::up(&db, None).await?; let data = Data::new(AppState { conn: db }); HttpServer::new(move || { App::new() .app_data(data.clone()) .app_data(JsonConfig::default().error_handler(|err, _req| { let api_error: APIError = (&err).into(); actix_web::error::InternalError::from_response( err, HttpResponse::BadRequest().json(APIErrorsResponse { errors: vec![ api_error ], }) ).into() })) .wrap(RequestIdentifier::with_generator(random_id_no_id)) .service(routes::v1::auth::magic_link::magic_link_request) .service(routes::v1::signup::signup_request) .service(routes::v1::auth::verify_magic_link::verify_magic_link_request) .service(routes::v1::totp_authenticators::totp_authenticators_request) .service(routes::v1::verify_totp_authenticators::verify_totp_authenticators_request) .service(routes::v1::auth::totp::totp_request) }).bind(CONFIG.server.bind)?.run().await?; Ok(()) }