main.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. use actix_web::{HttpServer, web, App, middleware};
  2. use actix_cors::Cors;
  3. use http_error::HttpError;
  4. use sqlx::PgPool;
  5. use std::{env, sync::OnceLock};
  6. mod http_error;
  7. mod routes;
  8. mod controllers;
  9. mod models;
  10. mod logic;
  11. mod auth;
  12. static JWT_SECRET: OnceLock<String> = OnceLock::new();
  13. static STRIPE_KEY: OnceLock<String> = OnceLock::new();
  14. static TOKEN_PACK_PRICE: OnceLock<i32> = OnceLock::new();
  15. static TOKENS_PER_PACK: OnceLock<i32> = OnceLock::new();
  16. #[actix_web::main]
  17. async fn main() -> std::io::Result<()> {
  18. //Environment variables
  19. dotenvy::from_filename(".env").expect("Failed to load .env file");
  20. let port: u16 = env_var("PORT");
  21. let app_env: String = env_var("APP_ENV");
  22. let database_url: String = env_var("DATABASE_URL");
  23. JWT_SECRET.set(env_var("JWT_SECRET")).expect("Failed to set JWT");
  24. STRIPE_KEY.set(env_var("STRIPE_KEY")).expect("Failed to set Stripe key");
  25. TOKEN_PACK_PRICE.set(env_var("TOKEN_PACK_PRICE")).expect("Failed to set token pack price");
  26. TOKENS_PER_PACK.set(env_var("TOKENS_PER_PACK")).expect("Failed to set tokens per pack");
  27. //Database
  28. let pool = PgPool::connect(&database_url)
  29. .await
  30. .expect("Failed to start Postgres");
  31. //Server
  32. HttpServer::new(move || {
  33. let cors = if app_env == "development" {
  34. Cors::default()
  35. .allowed_origin("http://localhost:5173")
  36. .allowed_methods(vec!["GET", "POST", "PUT", "PATCH", "DELETE"])
  37. .allow_any_header()
  38. .supports_credentials()
  39. } else {
  40. Cors::default()
  41. .allowed_origin_fn(|origin, _req| {
  42. origin.as_bytes().ends_with(b".chatrpg.com")
  43. })
  44. .allowed_methods(vec!["GET", "POST", "PUT", "PATCH", "DELETE"])
  45. .allow_any_header()
  46. .supports_credentials()
  47. };
  48. App::new()
  49. .wrap(middleware::Compress::default())
  50. .wrap(cors)
  51. .app_data(
  52. web::JsonConfig::default().error_handler(|err, _req| {
  53. HttpError::JsonDeserializationError(err.to_string()).into()
  54. })
  55. )
  56. .app_data(web::Data::new(pool.clone()))
  57. .configure(routes::user::config)
  58. })
  59. .bind(("0.0.0.0", port))
  60. .expect("Failed to bind to port")
  61. .run()
  62. .await
  63. .expect("Failed to start server");
  64. Ok(())
  65. }
  66. fn env_var<T: std::str::FromStr>(key: &str) -> T
  67. where
  68. T::Err: std::fmt::Debug,
  69. {
  70. env::var(key)
  71. .unwrap_or_else(|_| panic!("Environment variable {} not set", key))
  72. .parse()
  73. .unwrap_or_else(|_| panic!("{} could not be parsed", key))
  74. }