summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/boot/mod.rs10
-rw-r--r--src/boot/routes/mod.rs10
-rw-r--r--src/channel/mod.rs4
-rw-r--r--src/channel/routes/mod.rs18
-rw-r--r--src/cli.rs39
-rw-r--r--src/event/mod.rs10
-rw-r--r--src/event/routes/mod.rs10
-rw-r--r--src/invite/mod.rs8
-rw-r--r--src/invite/routes/mod.rs18
-rw-r--r--src/lib.rs1
-rw-r--r--src/message/mod.rs6
-rw-r--r--src/message/routes/mod.rs10
-rw-r--r--src/routes.rs83
-rw-r--r--src/setup/mod.rs4
-rw-r--r--src/setup/routes/mod.rs10
-rw-r--r--src/ui/mod.rs4
-rw-r--r--src/ui/routes/mod.rs35
-rw-r--r--src/user/mod.rs6
-rw-r--r--src/user/routes/mod.rs17
19 files changed, 127 insertions, 176 deletions
diff --git a/src/boot/mod.rs b/src/boot/mod.rs
index 122bd53..2b74de1 100644
--- a/src/boot/mod.rs
+++ b/src/boot/mod.rs
@@ -1,11 +1,11 @@
-use crate::{channel::Channel, event::Sequence, message::Message, user::User};
-use serde::Serialize;
use std::time::Duration;
-pub mod app;
-mod routes;
+use serde::Serialize;
-pub use self::routes::router;
+use crate::{channel::Channel, event::Sequence, message::Message, user::User};
+
+pub mod app;
+pub mod routes;
#[derive(serde::Serialize)]
pub struct Snapshot {
diff --git a/src/boot/routes/mod.rs b/src/boot/routes/mod.rs
index 8fd99d3..60ad5d8 100644
--- a/src/boot/routes/mod.rs
+++ b/src/boot/routes/mod.rs
@@ -1,11 +1,3 @@
-use axum::{Router, routing::get};
-
-use crate::app::App;
-
-mod get;
+pub mod get;
#[cfg(test)]
mod test;
-
-pub fn router() -> Router<App> {
- Router::new().route("/api/boot", get(get::handler))
-}
diff --git a/src/channel/mod.rs b/src/channel/mod.rs
index d5ba828..feb00a9 100644
--- a/src/channel/mod.rs
+++ b/src/channel/mod.rs
@@ -3,8 +3,8 @@ pub mod event;
mod history;
mod id;
pub mod repo;
-mod routes;
+pub mod routes;
mod snapshot;
mod validate;
-pub use self::{event::Event, history::History, id::Id, routes::router, snapshot::Channel};
+pub use self::{event::Event, history::History, id::Id, snapshot::Channel};
diff --git a/src/channel/routes/mod.rs b/src/channel/routes/mod.rs
index c917348..bd90721 100644
--- a/src/channel/routes/mod.rs
+++ b/src/channel/routes/mod.rs
@@ -1,19 +1,5 @@
-use axum::{
- Router,
- routing::{delete, post},
-};
-
-use crate::app::App;
-
-mod channel;
-mod post;
+pub mod channel;
+pub mod post;
#[cfg(test)]
mod test;
-
-pub fn router() -> Router<App> {
- Router::new()
- .route("/api/channels", post(post::handler))
- .route("/api/channels/{channel}", post(channel::post::handler))
- .route("/api/channels/{channel}", delete(channel::delete::handler))
-}
diff --git a/src/cli.rs b/src/cli.rs
index 7bfdbc0..28c2ec8 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -6,7 +6,6 @@
use std::{future, io};
use axum::{
- Router,
http::header,
middleware,
response::{IntoResponse, Response},
@@ -15,7 +14,7 @@ use clap::{CommandFactory, Parser};
use sqlx::sqlite::SqlitePool;
use tokio::net;
-use crate::{app::App, boot, channel, clock, db, event, expire, invite, message, setup, ui, user};
+use crate::{app::App, clock, db, routes};
/// Command-line entry point for running the `pilcrow` server.
///
@@ -82,7 +81,7 @@ impl Args {
let pool = self.pool().await?;
let app = App::from(pool);
- let app = routers(&app)
+ let app = routes::routes(&app)
.route_layer(middleware::from_fn(clock::middleware))
.route_layer(middleware::map_response(Self::server_info()))
.with_state(app);
@@ -123,40 +122,6 @@ impl Args {
}
}
-fn routers(app: &App) -> Router<App> {
- [
- [
- // API endpoints that require setup to function
- boot::router(),
- channel::router(),
- event::router(),
- invite::router(),
- user::router(),
- message::router(),
- ]
- .into_iter()
- .fold(Router::default(), Router::merge)
- // 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())),
- // API endpoints that handle setup
- setup::router(),
- // The UI (handles setup state itself)
- ui::router(app),
- ]
- .into_iter()
- .fold(Router::default(), Router::merge)
-}
-
fn started_msg(listener: &net::TcpListener) -> io::Result<String> {
let local_addr = listener.local_addr()?;
Ok(format!("listening on http://{local_addr}/"))
diff --git a/src/event/mod.rs b/src/event/mod.rs
index 1f2ec42..ff30dc7 100644
--- a/src/event/mod.rs
+++ b/src/event/mod.rs
@@ -1,18 +1,18 @@
-use crate::{channel, message, user};
-use axum::response::sse;
-use axum::response::sse::KeepAlive;
use std::time::Duration;
+use axum::response::sse::{self, KeepAlive};
+
+use crate::{channel, message, user};
+
pub mod app;
mod broadcaster;
mod extract;
pub mod repo;
-mod routes;
+pub mod routes;
mod sequence;
pub use self::{
broadcaster::Broadcaster,
- routes::router,
sequence::{Instant, Sequence, Sequenced},
};
diff --git a/src/event/routes/mod.rs b/src/event/routes/mod.rs
index 742d397..60ad5d8 100644
--- a/src/event/routes/mod.rs
+++ b/src/event/routes/mod.rs
@@ -1,11 +1,3 @@
-use axum::{Router, routing::get};
-
-use crate::app::App;
-
-mod get;
+pub mod get;
#[cfg(test)]
mod test;
-
-pub fn router() -> Router<App> {
- Router::new().route("/api/events", get(get::handler))
-}
diff --git a/src/invite/mod.rs b/src/invite/mod.rs
index 2d32fda..3932eea 100644
--- a/src/invite/mod.rs
+++ b/src/invite/mod.rs
@@ -1,11 +1,11 @@
+use crate::{clock::DateTime, normalize::nfc, user};
+
pub mod app;
mod id;
mod repo;
-mod routes;
-
-use crate::{clock::DateTime, normalize::nfc, user};
+pub mod routes;
-pub use self::{id::Id, routes::router};
+pub use self::id::Id;
#[derive(Debug, serde::Serialize)]
pub struct Invite {
diff --git a/src/invite/routes/mod.rs b/src/invite/routes/mod.rs
index d83efc6..8747a4e 100644
--- a/src/invite/routes/mod.rs
+++ b/src/invite/routes/mod.rs
@@ -1,18 +1,4 @@
-use axum::{
- Router,
- routing::{get, post},
-};
-
-use crate::app::App;
-
-mod invite;
-mod post;
+pub mod invite;
+pub mod post;
#[cfg(test)]
mod test;
-
-pub fn router() -> Router<App> {
- Router::new()
- .route("/api/invite", post(post::handler))
- .route("/api/invite/{invite}", get(invite::get::handler))
- .route("/api/invite/{invite}", post(invite::post::handler))
-}
diff --git a/src/lib.rs b/src/lib.rs
index 4cce63b..d2fa390 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -17,6 +17,7 @@ mod invite;
mod message;
mod name;
mod normalize;
+mod routes;
mod setup;
#[cfg(test)]
mod test;
diff --git a/src/message/mod.rs b/src/message/mod.rs
index c2687bc..fbaa4a3 100644
--- a/src/message/mod.rs
+++ b/src/message/mod.rs
@@ -4,9 +4,7 @@ pub mod event;
mod history;
mod id;
pub mod repo;
-mod routes;
+pub mod routes;
mod snapshot;
-pub use self::{
- body::Body, event::Event, history::History, id::Id, routes::router, snapshot::Message,
-};
+pub use self::{body::Body, event::Event, history::History, id::Id, snapshot::Message};
diff --git a/src/message/routes/mod.rs b/src/message/routes/mod.rs
index 00b2b1a..e216a50 100644
--- a/src/message/routes/mod.rs
+++ b/src/message/routes/mod.rs
@@ -1,9 +1 @@
-use axum::{Router, routing::delete};
-
-use crate::app::App;
-
-mod message;
-
-pub fn router() -> Router<App> {
- Router::new().route("/api/messages/{message}", delete(message::delete::handler))
-}
+pub mod message;
diff --git a/src/routes.rs b/src/routes.rs
new file mode 100644
index 0000000..5bb5f91
--- /dev/null
+++ b/src/routes.rs
@@ -0,0 +1,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)
+}
diff --git a/src/setup/mod.rs b/src/setup/mod.rs
index a4b821c..e741a60 100644
--- a/src/setup/mod.rs
+++ b/src/setup/mod.rs
@@ -1,6 +1,6 @@
pub mod app;
pub mod repo;
mod required;
-mod routes;
+pub mod routes;
-pub use self::{required::Required, routes::router};
+pub use self::required::Required;
diff --git a/src/setup/routes/mod.rs b/src/setup/routes/mod.rs
index 977a790..e94a249 100644
--- a/src/setup/routes/mod.rs
+++ b/src/setup/routes/mod.rs
@@ -1,11 +1,3 @@
-use axum::{Router, routing::post};
-
-use crate::app::App;
-
-mod post;
+pub mod post;
#[cfg(test)]
mod test;
-
-pub fn router() -> Router<App> {
- Router::new().route("/api/setup", post(post::handler))
-}
diff --git a/src/ui/mod.rs b/src/ui/mod.rs
index e834bba..eeaf27a 100644
--- a/src/ui/mod.rs
+++ b/src/ui/mod.rs
@@ -1,6 +1,4 @@
mod assets;
mod error;
mod mime;
-mod routes;
-
-pub use self::routes::router;
+pub mod routes;
diff --git a/src/ui/routes/mod.rs b/src/ui/routes/mod.rs
index dc94773..2390802 100644
--- a/src/ui/routes/mod.rs
+++ b/src/ui/routes/mod.rs
@@ -1,28 +1,7 @@
-use axum::{Router, response::Redirect, routing::get};
-
-use crate::app::App;
-
-mod ch;
-mod get;
-mod invite;
-mod login;
-mod me;
-mod path;
-mod setup;
-
-pub fn router(app: &App) -> Router<App> {
- [
- Router::new()
- .route("/{*path}", get(path::get::handler))
- .route("/setup", get(setup::get::handler)),
- Router::new()
- .route("/", get(get::handler))
- .route("/me", get(me::get::handler))
- .route("/login", get(login::get::handler))
- .route("/ch/{channel}", get(ch::channel::get::handler))
- .route("/invite/{invite}", get(invite::invite::get::handler))
- .route_layer(crate::setup::Required(app.clone()).with_fallback(Redirect::to("/setup"))),
- ]
- .into_iter()
- .fold(Router::default(), Router::merge)
-}
+pub mod ch;
+pub mod get;
+pub mod invite;
+pub mod login;
+pub mod me;
+pub mod path;
+pub mod setup;
diff --git a/src/user/mod.rs b/src/user/mod.rs
index f4c66ab..7ea3d26 100644
--- a/src/user/mod.rs
+++ b/src/user/mod.rs
@@ -6,10 +6,8 @@ mod history;
mod id;
pub mod password;
pub mod repo;
-mod routes;
+pub mod routes;
mod snapshot;
mod validate;
-pub use self::{
- event::Event, history::History, id::Id, password::Password, routes::router, snapshot::User,
-};
+pub use self::{event::Event, history::History, id::Id, password::Password, snapshot::User};
diff --git a/src/user/routes/mod.rs b/src/user/routes/mod.rs
index ade96cb..f9bbed7 100644
--- a/src/user/routes/mod.rs
+++ b/src/user/routes/mod.rs
@@ -1,14 +1,3 @@
-use axum::{Router, routing::post};
-
-use crate::app::App;
-
-mod login;
-mod logout;
-mod password;
-
-pub fn router() -> Router<App> {
- Router::new()
- .route("/api/password", post(password::post::handler))
- .route("/api/auth/login", post(login::post::handler))
- .route("/api/auth/logout", post(logout::post::handler))
-}
+pub mod login;
+pub mod logout;
+pub mod password;