2024-08-06 11:08:15 -04:00
|
|
|
mod user;
|
|
|
|
|
2024-08-22 17:29:24 -04:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
2024-08-06 11:08:15 -04:00
|
|
|
use axum::Router;
|
|
|
|
use tokio::net::TcpListener;
|
2024-08-24 13:22:51 -04:00
|
|
|
use webauthn_rs::prelude::*;
|
2024-08-06 11:08:15 -04:00
|
|
|
|
2024-08-24 13:22:51 -04:00
|
|
|
use crate::{
|
|
|
|
db::DbPool,
|
|
|
|
models::{AppError, Environment},
|
|
|
|
};
|
2024-08-06 11:08:15 -04:00
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct AppState {
|
|
|
|
pool: DbPool,
|
|
|
|
env: Environment,
|
2024-08-22 17:29:24 -04:00
|
|
|
webauthn: Arc<Webauthn>,
|
2024-08-06 11:08:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AppState {
|
|
|
|
pub fn new(pool: DbPool, env: Environment) -> Self {
|
2024-08-24 13:22:51 -04:00
|
|
|
let rp_id = env.rp_id();
|
|
|
|
let rp_origin = env
|
|
|
|
.domain()
|
|
|
|
.parse::<Url>()
|
|
|
|
.expect("RP_ORIGIN must be in a valid domain name format");
|
2024-08-22 17:29:24 -04:00
|
|
|
|
2024-08-24 13:22:51 -04:00
|
|
|
let webauthn = Arc::new(
|
|
|
|
WebauthnBuilder::new(rp_id, &rp_origin)
|
|
|
|
.map(|builder| builder.allow_any_port(true))
|
|
|
|
.and_then(WebauthnBuilder::build)
|
|
|
|
.inspect_err(|err| eprintln!("{err}"))
|
|
|
|
.expect("Unable to build authenticator"),
|
|
|
|
);
|
|
|
|
|
|
|
|
Self {
|
|
|
|
pool,
|
|
|
|
env,
|
|
|
|
webauthn,
|
|
|
|
}
|
2024-08-06 11:08:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn pool(&self) -> &DbPool {
|
|
|
|
&self.pool
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn env(&self) -> &Environment {
|
|
|
|
&self.env
|
|
|
|
}
|
2024-08-24 13:22:51 -04:00
|
|
|
|
|
|
|
pub fn webauthn(&self) -> Arc<Webauthn> {
|
|
|
|
Arc::clone(&self.webauthn)
|
|
|
|
}
|
2024-08-06 11:08:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn start_app(pool: DbPool, env: Environment) -> Result<(), AppError> {
|
2024-08-22 17:29:24 -04:00
|
|
|
let address = env.hostname();
|
|
|
|
let port = env.port();
|
2024-08-06 11:08:15 -04:00
|
|
|
let listener = TcpListener::bind(format!("{address}:{port}"))
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let app_state = AppState::new(pool, env);
|
|
|
|
let app = Router::new().merge(user::requests(app_state.clone()));
|
|
|
|
|
|
|
|
axum::serve(listener, app)
|
|
|
|
.await
|
2024-08-25 13:06:29 -04:00
|
|
|
.inspect(|_| println!("Application started successfully."))
|
2024-08-06 11:08:15 -04:00
|
|
|
.map_err(AppError::app_startup)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|