summaryrefslogtreecommitdiff
path: root/src/routes.rs
blob: 5bb5f9158b4b4f3787ecce07b221eb310f4c3c11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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<App> {
    // 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)
}