use axum::{ Router, middleware, response::Redirect, routing::{delete, get, post}, }; use crate::{app::App, boot, channel, event, expire, invite, message, setup, ui, user}; pub fn routes(app: &App) -> Router { // UI routes that can be accessed before the administrator completes setup. let ui_bootstrap = Router::new() .route("/{*path}", get(ui::routes::path::get::handler)) .route("/setup", get(ui::routes::setup::get::handler)); // UI routes that require the administrator to complete setup first. let ui_setup_required = Router::new() .route("/", get(ui::routes::get::handler)) .route("/ch/{channel}", get(ui::routes::ch::channel::get::handler)) .route( "/invite/{invite}", get(ui::routes::invite::invite::get::handler), ) .route("/login", get(ui::routes::login::get::handler)) .route("/me", get(ui::routes::me::get::handler)) .route_layer(crate::setup::Required(app.clone()).with_fallback(Redirect::to("/setup"))); // API routes that can run before the administrator completes setup. let api_bootstrap = Router::new().route("/api/setup", post(setup::routes::post::handler)); // API routes that require the administrator to complete setup first. let api_setup_required = Router::new() .route("/api/auth/login", post(user::routes::login::post::handler)) .route( "/api/auth/logout", post(user::routes::logout::post::handler), ) .route("/api/boot", get(boot::routes::get::handler)) .route("/api/channels", post(channel::routes::post::handler)) .route( "/api/channels/{channel}", post(channel::routes::channel::post::handler), ) .route( "/api/channels/{channel}", delete(channel::routes::channel::delete::handler), ) .route("/api/events", get(event::routes::get::handler)) .route("/api/invite", post(invite::routes::post::handler)) .route( "/api/invite/{invite}", get(invite::routes::invite::get::handler), ) .route( "/api/invite/{invite}", post(invite::routes::invite::post::handler), ) .route( "/api/messages/{message}", delete(message::routes::message::delete::handler), ) .route("/api/password", post(user::routes::password::post::handler)) // Run expiry whenever someone accesses the API. This was previously a blanket middleware // affecting the whole service, but loading the client makes a several requests before the // client can completely load, each of which was triggering expiry. There is absolutely no // upside to re-checking expiry tens of times back-to-back like that; the API is accessed // more regularly and with less of a traffic rush. // // This should, probably, be moved to a background job at some point. .route_layer(middleware::from_fn_with_state( app.clone(), expire::middleware, )) .route_layer(setup::Required(app.clone())); [ ui_bootstrap, ui_setup_required, api_bootstrap, api_setup_required, ] .into_iter() .fold(Router::default(), Router::merge) }