refactor: streamline environment variable loading and improve logging
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
use crate::{Env, load_env, surrealdb_init_mem, surrealdb_init_ws};
|
||||
use crate::{surrealdb_init_mem, surrealdb_init_ws};
|
||||
use axum::{Router, serve};
|
||||
use imphnen_entities::{SurrealMemClient, SurrealWsClient};
|
||||
use std::{future::Future, net::SocketAddr};
|
||||
use tokio::net::TcpListener;
|
||||
use crate::enviroment::ENV;
|
||||
|
||||
pub async fn axum_init<F, Fut>(router_fn: F)
|
||||
where
|
||||
F: FnOnce(SurrealWsClient, SurrealMemClient) -> Fut,
|
||||
Fut: Future<Output = Router>,
|
||||
{
|
||||
load_env();
|
||||
let env = Env::new();
|
||||
let env = &ENV;
|
||||
|
||||
let surrealdb_ws = surrealdb_init_ws().await.expect("Failed surrealdb ws");
|
||||
|
||||
|
||||
@@ -1,100 +1,204 @@
|
||||
//! Environment configuration module using once_cell::sync::Lazy for one-time loading.
|
||||
|
||||
use std::env;
|
||||
use once_cell::sync::Lazy;
|
||||
// Logging for warnings if .env is missing
|
||||
use log::warn;
|
||||
|
||||
pub fn load_env() {
|
||||
if dotenvy::dotenv().is_ok() {}
|
||||
}
|
||||
|
||||
/// Struct holding all environment configuration.
|
||||
pub struct Env {
|
||||
pub port: u16,
|
||||
pub access_token_secret: String,
|
||||
pub refresh_token_secret: String,
|
||||
pub surrealdb_url: String,
|
||||
pub surrealdb_username: String,
|
||||
pub surrealdb_password: String,
|
||||
pub surrealdb_namespace: String,
|
||||
pub surrealdb_dbname: String,
|
||||
pub surrealdb_url_ws: String,
|
||||
pub smtp_email: String,
|
||||
pub smtp_password: String,
|
||||
pub smtp_name: String,
|
||||
pub smtp_host: String,
|
||||
pub redisdb_url: String,
|
||||
pub fe_url: String,
|
||||
pub rust_env: String,
|
||||
pub minio_endpoint: String,
|
||||
pub minio_bucket_name: String,
|
||||
pub minio_access_key: String,
|
||||
pub minio_secret_key: String,
|
||||
pub port: u16,
|
||||
pub access_token_secret: String,
|
||||
pub refresh_token_secret: String,
|
||||
pub surrealdb_url: String,
|
||||
pub surrealdb_username: String,
|
||||
pub surrealdb_password: String,
|
||||
pub surrealdb_namespace: String,
|
||||
pub surrealdb_dbname: String,
|
||||
pub surrealdb_url_ws: String,
|
||||
pub smtp_email: String,
|
||||
pub smtp_password: String,
|
||||
pub smtp_name: String,
|
||||
pub smtp_host: String,
|
||||
pub redisdb_url: String,
|
||||
pub fe_url: String,
|
||||
pub rust_env: String,
|
||||
pub minio_endpoint: String,
|
||||
pub minio_bucket_name: String,
|
||||
pub minio_access_key: String,
|
||||
pub minio_secret_key: String,
|
||||
}
|
||||
|
||||
impl Env {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
port: env::var("PORT")
|
||||
.unwrap_or_else(|_| "3000".to_string())
|
||||
.parse()
|
||||
.unwrap_or(3000),
|
||||
/// Loads environment variables from .env and system, only once.
|
||||
pub static ENV: Lazy<Env> = Lazy::new(|| {
|
||||
// Try to load .env file, log a warning if not found, proceed regardless.
|
||||
match dotenvy::dotenv() {
|
||||
Ok(_) => {}
|
||||
Err(dotenvy::Error::Io(ref e)) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||
warn!(".env file not found, falling back to system environment variables");
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
|
||||
rust_env: env::var("RUST_ENV").unwrap_or_else(|_| "development".to_string()),
|
||||
Env {
|
||||
port: match env::var("PORT") {
|
||||
Ok(val) => val.parse().unwrap_or(3000),
|
||||
Err(_) => {
|
||||
warn!("Environment variable PORT not set, using default 3000.");
|
||||
3000
|
||||
}
|
||||
},
|
||||
|
||||
access_token_secret: env::var("ACCESS_TOKEN_SECRET")
|
||||
.unwrap_or_else(|_| "default_access_secret".to_string()),
|
||||
rust_env: match env::var("RUST_ENV") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable RUST_ENV not set, using default 'development'.");
|
||||
"development".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
refresh_token_secret: env::var("REFRESH_TOKEN_SECRET")
|
||||
.unwrap_or_else(|_| "default_refresh_secret".to_string()),
|
||||
access_token_secret: match env::var("ACCESS_TOKEN_SECRET") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable ACCESS_TOKEN_SECRET not set, using default.");
|
||||
"default_access_secret".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
surrealdb_url: env::var("SURREALDB_URL")
|
||||
.unwrap_or_else(|_| "http://localhost:8000".to_string()),
|
||||
refresh_token_secret: match env::var("REFRESH_TOKEN_SECRET") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable REFRESH_TOKEN_SECRET not set, using default.");
|
||||
"default_refresh_secret".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
surrealdb_username: env::var("SURREALDB_USERNAME")
|
||||
.unwrap_or_else(|_| "root".to_string()),
|
||||
surrealdb_url: match env::var("SURREALDB_URL") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SURREALDB_URL not set, using default 'http://localhost:8000'.");
|
||||
"http://localhost:8000".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
surrealdb_password: env::var("SURREALDB_PASSWORD")
|
||||
.unwrap_or_else(|_| "password".to_string()),
|
||||
surrealdb_username: match env::var("SURREALDB_USERNAME") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SURREALDB_USERNAME not set, using default 'root'.");
|
||||
"root".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
surrealdb_namespace: env::var("SURREALDB_NAMESPACE")
|
||||
.unwrap_or_else(|_| "namespace".to_string()),
|
||||
surrealdb_password: match env::var("SURREALDB_PASSWORD") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SURREALDB_PASSWORD not set, using default 'password'.");
|
||||
"password".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
surrealdb_dbname: env::var("SURREALDB_DBNAME")
|
||||
.unwrap_or_else(|_| "database".to_string()),
|
||||
surrealdb_namespace: match env::var("SURREALDB_NAMESPACE") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SURREALDB_NAMESPACE not set, using default 'namespace'.");
|
||||
"namespace".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
surrealdb_url_ws: env::var("SURREALDB_URL_WS")
|
||||
.unwrap_or_else(|_| "ws://localhost:8000/rpc".to_string()),
|
||||
surrealdb_dbname: match env::var("SURREALDB_DBNAME") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SURREALDB_DBNAME not set, using default 'database'.");
|
||||
"database".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
smtp_email: env::var("SMTP_EMAIL")
|
||||
.unwrap_or_else(|_| "no-reply@example.com".to_string()),
|
||||
surrealdb_url_ws: match env::var("SURREALDB_URL_WS") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SURREALDB_URL_WS not set, using default 'ws://localhost:8000/rpc'.");
|
||||
"ws://localhost:8000/rpc".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
smtp_password: env::var("SMTP_PASSWORD")
|
||||
.unwrap_or_else(|_| "default_smtp_password".to_string()),
|
||||
smtp_email: match env::var("SMTP_EMAIL") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SMTP_EMAIL not set, using default 'no-reply@example.com'.");
|
||||
"no-reply@example.com".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
smtp_name: env::var("SMTP_NAME").unwrap_or_else(|_| "MyApp SMTP".to_string()),
|
||||
smtp_password: match env::var("SMTP_PASSWORD") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SMTP_PASSWORD not set, using default.");
|
||||
"default_smtp_password".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
smtp_host: env::var("SMTP_HOST")
|
||||
.unwrap_or_else(|_| "smtp.gmail.com".to_string()),
|
||||
smtp_name: match env::var("SMTP_NAME") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SMTP_NAME not set, using default 'MyApp SMTP'.");
|
||||
"MyApp SMTP".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
redisdb_url: env::var("REDISDB_URL")
|
||||
.unwrap_or_else(|_| "localhost".to_string()),
|
||||
smtp_host: match env::var("SMTP_HOST") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable SMTP_HOST not set, using default 'smtp.gmail.com'.");
|
||||
"smtp.gmail.com".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
fe_url: env::var("FE_URL").unwrap_or_else(|_| "http://localhost".to_string()),
|
||||
redisdb_url: match env::var("REDISDB_URL") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable REDISDB_URL not set, using default 'localhost'.");
|
||||
"localhost".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
minio_endpoint: env::var("MINIO_ENDPOINT")
|
||||
.unwrap_or_else(|_| "http://localhost:9000".to_string()),
|
||||
fe_url: match env::var("FE_URL") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable FE_URL not set, using default 'http://localhost'.");
|
||||
"http://localhost".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
minio_bucket_name: env::var("MINIO_BUCKET_NAME")
|
||||
.unwrap_or_else(|_| "default_bucket".to_string()),
|
||||
minio_endpoint: match env::var("MINIO_ENDPOINT") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable MINIO_ENDPOINT not set, using default 'http://localhost:9000'.");
|
||||
"http://localhost:9000".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
minio_access_key: env::var("MINIO_ACCESS_KEY")
|
||||
.unwrap_or_else(|_| "minio_access".to_string()),
|
||||
minio_bucket_name: match env::var("MINIO_BUCKET_NAME") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable MINIO_BUCKET_NAME not set, using default 'default_bucket'.");
|
||||
"default_bucket".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
minio_secret_key: env::var("MINIO_SECRET_KEY")
|
||||
.unwrap_or_else(|_| "minio_secret".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
minio_access_key: match env::var("MINIO_ACCESS_KEY") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable MINIO_ACCESS_KEY not set, using default 'minio_access'.");
|
||||
"minio_access".to_string()
|
||||
}
|
||||
},
|
||||
|
||||
impl Default for Env {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
minio_secret_key: match env::var("MINIO_SECRET_KEY") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
warn!("Environment variable MINIO_SECRET_KEY not set, using default 'minio_secret'.");
|
||||
"minio_secret".to_string()
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::Env;
|
||||
use crate::enviroment::ENV;
|
||||
use axum::http::StatusCode;
|
||||
use chrono::{Duration, TimeDelta, Utc};
|
||||
use jsonwebtoken::{
|
||||
@@ -14,8 +14,8 @@ pub struct Claims {
|
||||
}
|
||||
|
||||
pub fn encode_access_token(sub: String) -> Result<String, StatusCode> {
|
||||
let env = Env::new();
|
||||
let secret: String = env.access_token_secret;
|
||||
let env = &ENV;
|
||||
let secret: String = env.access_token_secret.clone();
|
||||
let now = Utc::now();
|
||||
let expire: TimeDelta = Duration::minutes(15);
|
||||
let exp: usize = (now + expire).timestamp() as usize;
|
||||
@@ -30,8 +30,8 @@ pub fn encode_access_token(sub: String) -> Result<String, StatusCode> {
|
||||
}
|
||||
|
||||
pub fn encode_reset_password_token(sub: String) -> Result<String, StatusCode> {
|
||||
let env = Env::new();
|
||||
let secret: String = env.access_token_secret;
|
||||
let env = &ENV;
|
||||
let secret: String = env.access_token_secret.clone();
|
||||
let now = Utc::now();
|
||||
let expire: TimeDelta = Duration::minutes(5);
|
||||
let exp: usize = (now + expire).timestamp() as usize;
|
||||
@@ -48,8 +48,8 @@ pub fn encode_reset_password_token(sub: String) -> Result<String, StatusCode> {
|
||||
pub fn decode_access_token(
|
||||
jwt_token: &str,
|
||||
) -> Result<TokenData<Claims>, StatusCode> {
|
||||
let env = Env::new();
|
||||
let secret: String = env.access_token_secret;
|
||||
let env = &ENV;
|
||||
let secret: String = env.access_token_secret.clone();
|
||||
let result: Result<TokenData<Claims>, StatusCode> = decode(
|
||||
jwt_token,
|
||||
&DecodingKey::from_secret(secret.as_ref()),
|
||||
@@ -60,8 +60,8 @@ pub fn decode_access_token(
|
||||
}
|
||||
|
||||
pub fn encode_refresh_token(sub: String) -> Result<String, StatusCode> {
|
||||
let env = Env::new();
|
||||
let secret: String = env.refresh_token_secret;
|
||||
let env = &ENV;
|
||||
let secret: String = env.refresh_token_secret.clone();
|
||||
let now = Utc::now();
|
||||
let expire: TimeDelta = Duration::days(1);
|
||||
let exp: usize = (now + expire).timestamp() as usize;
|
||||
@@ -78,8 +78,8 @@ pub fn encode_refresh_token(sub: String) -> Result<String, StatusCode> {
|
||||
pub fn decode_refresh_token(
|
||||
jwt_token: &str,
|
||||
) -> Result<TokenData<Claims>, StatusCode> {
|
||||
let env = Env::new();
|
||||
let secret: String = env.refresh_token_secret;
|
||||
let env = &ENV;
|
||||
let secret: String = env.refresh_token_secret.clone();
|
||||
let result: Result<TokenData<Claims>, StatusCode> = decode(
|
||||
jwt_token,
|
||||
&DecodingKey::from_secret(secret.as_ref()),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::Env;
|
||||
use crate::enviroment::ENV;
|
||||
use lettre::message::Mailbox;
|
||||
use lettre::transport::smtp::authentication::Credentials;
|
||||
use lettre::{Message, SmtpTransport, Transport};
|
||||
@@ -9,11 +9,11 @@ pub fn send_email(
|
||||
subject: &str,
|
||||
body: &str,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let env = Env::new();
|
||||
let host = env.smtp_host;
|
||||
let sender_email = env.smtp_email;
|
||||
let sender_name = env.smtp_name;
|
||||
let sender_password = env.smtp_password;
|
||||
let env = &ENV;
|
||||
let host = env.smtp_host.clone();
|
||||
let sender_email = env.smtp_email.clone();
|
||||
let sender_name = env.smtp_name.clone();
|
||||
let sender_password = env.smtp_password.clone();
|
||||
let recipient_email = to;
|
||||
let email = Message::builder()
|
||||
.from(Mailbox::new(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::Env;
|
||||
use crate::enviroment::ENV;
|
||||
use crate::SurrealMemClient;
|
||||
use crate::enviroment::load_env;
|
||||
use surrealdb::engine::any;
|
||||
use surrealdb::engine::local::Mem;
|
||||
use surrealdb::opt::auth::Root;
|
||||
@@ -10,8 +9,7 @@ pub mod resource;
|
||||
pub use resource::*;
|
||||
|
||||
pub async fn surrealdb_init_ws() -> Result<Surreal<any::Any>> {
|
||||
load_env();
|
||||
let env = Env::new();
|
||||
let env = &ENV;
|
||||
let db = any::connect(&env.surrealdb_url).await?;
|
||||
|
||||
db.signin(Root {
|
||||
@@ -26,7 +24,7 @@ pub async fn surrealdb_init_ws() -> Result<Surreal<any::Any>> {
|
||||
}
|
||||
|
||||
pub async fn surrealdb_init_mem() -> Result<SurrealMemClient> {
|
||||
let env = Env::new();
|
||||
let env = &ENV;
|
||||
let db = Surreal::new::<Mem>(()).await?;
|
||||
db.use_ns(&env.surrealdb_namespace)
|
||||
.use_db(&env.surrealdb_dbname)
|
||||
|
||||
Reference in New Issue
Block a user