| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- use actix_web::{HttpServer, web, App, middleware};
- use actix_cors::Cors;
- use http_error::HttpError;
- use sqlx::PgPool;
- use std::{env, sync::OnceLock};
- mod http_error;
- mod routes;
- mod controllers;
- mod models;
- mod logic;
- mod auth;
- static JWT_SECRET: OnceLock<String> = OnceLock::new();
- static STRIPE_KEY: OnceLock<String> = OnceLock::new();
- static TOKEN_PACK_PRICE: OnceLock<i32> = OnceLock::new();
- static TOKENS_PER_PACK: OnceLock<i32> = OnceLock::new();
- static STRIPE_WEBHOOK_SECRET: OnceLock<String> = OnceLock::new();
- static DEEPINFRA_TOKEN: OnceLock<String> = OnceLock::new();
- #[actix_web::main]
- async fn main() -> std::io::Result<()> {
- //Environment variables
- dotenvy::from_filename(".env").expect("Failed to load .env file");
- let port: u16 = env_var("PORT");
- let app_env: String = env_var("APP_ENV");
- let database_url: String = env_var("DATABASE_URL");
- JWT_SECRET.set(env_var("JWT_SECRET")).expect("Failed to set JWT");
- STRIPE_KEY.set(env_var("STRIPE_KEY")).expect("Failed to set Stripe key");
- TOKEN_PACK_PRICE.set(env_var("TOKEN_PACK_PRICE")).expect("Failed to set token pack price");
- TOKENS_PER_PACK.set(env_var("TOKENS_PER_PACK")).expect("Failed to set tokens per pack");
- STRIPE_WEBHOOK_SECRET.set(env_var("STRIPE_WEBHOOK_SECRET")).expect("Failed to set stripe webhook secret");
- DEEPINFRA_TOKEN.set(env_var("DEEPINFRA_TOKEN")).expect("Failed to set DeepInfra token");
- //Database
- let pool = PgPool::connect(&database_url)
- .await
- .expect("Failed to start Postgres");
- //Server
- HttpServer::new(move || {
- let cors = if app_env == "development" {
- Cors::default()
- .allowed_origin("http://localhost:5173")
- .allowed_methods(vec!["GET", "POST", "PUT", "PATCH", "DELETE"])
- .allow_any_header()
- .supports_credentials()
- } else {
- Cors::default()
- .allowed_origin_fn(|origin, _req| {
- let bytes = origin.as_bytes();
- bytes == b"http://localhost:5173" || bytes == b"https://chatrpg.leemorgan.dev"
- })
- .allowed_methods(vec!["GET", "POST", "PUT", "PATCH", "DELETE"])
- .allow_any_header()
- .supports_credentials()
- };
- App::new()
- .wrap(middleware::Compress::default())
- .wrap(cors)
- .app_data(
- web::JsonConfig::default().error_handler(|err, _req| {
- HttpError::JsonDeserializationError(err.to_string()).into()
- })
- )
- .app_data(web::Data::new(pool.clone()))
- .configure(routes::other::config)
- .configure(routes::user::config)
- .configure(routes::webhook::config)
- .configure(routes::game::game::config)
- .configure(routes::game::character::config)
- .configure(routes::game::session::config)
- .configure(routes::game::turn::config)
- })
- .bind(("0.0.0.0", port))
- .expect("Failed to bind to port")
- .run()
- .await
- .expect("Failed to start server");
- Ok(())
- }
- fn env_var<T: std::str::FromStr>(key: &str) -> T
- where
- T::Err: std::fmt::Debug,
- {
- env::var(key)
- .unwrap_or_else(|_| panic!("Environment variable {} not set", key))
- .parse()
- .unwrap_or_else(|_| panic!("{} could not be parsed", key))
- }
|