use axum::{ Router, middleware, response::Redirect, routing::{delete, get, post}, }; use crate::{ app::App, boot, conversation, event, expire, invite, login, message, push, setup, ui, vapid, }; 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::handlers::asset)) .route("/.swatch/{*path}", get(ui::handlers::swatch)) .route("/setup", get(ui::handlers::setup)); // UI routes that require the administrator to complete setup first. let ui_setup_required = Router::new() .route("/", get(ui::handlers::index)) .route("/c/{conversation}", get(ui::handlers::conversation)) .route("/invite/{invite}", get(ui::handlers::invite)) .route("/login", get(ui::handlers::login)) .route("/me", get(ui::handlers::me)) .route_layer(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::handlers::setup)); // API routes that require the administrator to complete setup first. let api_setup_required = Router::new() .route("/api/auth/login", post(login::handlers::login)) .route("/api/auth/logout", post(login::handlers::logout)) .route("/api/boot", get(boot::handlers::boot)) .route("/api/conversations", post(conversation::handlers::create)) .route( "/api/conversations/{conversation}", post(conversation::handlers::send), ) .route( "/api/conversations/{conversation}", delete(conversation::handlers::delete), ) .route("/api/events", get(event::handlers::stream)) .route("/api/invite", post(invite::handlers::issue)) .route("/api/invite/{invite}", get(invite::handlers::get)) .route("/api/invite/{invite}", post(invite::handlers::accept)) .route("/api/messages/{message}", delete(message::handlers::delete)) .route("/api/push/subscribe", post(push::handlers::subscribe)) .route("/api/password", post(login::handlers::change_password)) // 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(middleware::from_fn_with_state( app.clone(), vapid::middleware, )) .route_layer(setup::Required(app.clone())); [ ui_bootstrap, ui_setup_required, api_bootstrap, api_setup_required, ] .into_iter() .fold(Router::default(), Router::merge) }