2c6062a53e
The /web/ prefix predated the /api/ split; today it just clutters every URL
without disambiguating anything. All 16 browser routes move to the apex
(/cases, /login, /magic, /events, /audio/...). The 6 /api/* routes are
unchanged. A new /->>/cases redirect closes the apex 404.
The open-redirect guard in magic.rs and case_actions.rs flips from a
positive whitelist (starts_with("/web/")) to a deny-list: same-origin path,
not protocol-relative, not under /api/, no \. The /api/ exclusion is now
load-bearing and covered by tests.
Pre-production: no transition redirects.
76 lines
2.3 KiB
Rust
76 lines
2.3 KiB
Rust
mod bulk;
|
|
pub(crate) mod case_actions;
|
|
mod debug;
|
|
mod events;
|
|
mod health;
|
|
mod login;
|
|
mod magic;
|
|
mod oneliner_override;
|
|
mod oneliners;
|
|
mod upload;
|
|
pub(crate) mod user_web;
|
|
pub(crate) mod web;
|
|
|
|
use axum::Router;
|
|
use axum::response::Redirect;
|
|
use axum::routing::{get, post, put};
|
|
|
|
use crate::AppState;
|
|
|
|
pub fn api_router() -> Router<AppState> {
|
|
Router::new()
|
|
.route("/", get(|| async { Redirect::permanent("/cases") }))
|
|
.route("/api/health", get(health::handle_health))
|
|
.route("/api/debug/whoami", get(debug::handle_whoami))
|
|
.route("/api/upload", post(upload::handle_upload))
|
|
.route("/api/oneliners", get(oneliners::handle_oneliners))
|
|
.route(
|
|
"/api/cases/{case_id}/oneliner",
|
|
put(oneliner_override::handle_put_oneliner),
|
|
)
|
|
.route("/api/auth/magic-link", post(magic::handle_create))
|
|
.route("/magic", get(magic::handle_consume))
|
|
.route(
|
|
"/login",
|
|
get(login::handle_login_page).post(login::handle_login_submit),
|
|
)
|
|
.route("/logout", post(login::handle_logout))
|
|
.route("/cases", get(user_web::handle_my_cases))
|
|
.route("/cases/{case_id}", get(user_web::handle_case_page))
|
|
.route(
|
|
"/cases/{case_id}/recordings",
|
|
get(user_web::handle_case_recordings),
|
|
)
|
|
.route(
|
|
"/cases/{case_id}/recordings/delete",
|
|
post(case_actions::handle_delete_recording),
|
|
)
|
|
.route(
|
|
"/cases/{case_id}/analyze",
|
|
post(case_actions::handle_analyze_case),
|
|
)
|
|
.route(
|
|
"/cases/{case_id}/close",
|
|
post(case_actions::handle_close_case),
|
|
)
|
|
.route(
|
|
"/cases/{case_id}/reopen",
|
|
post(case_actions::handle_reopen_case),
|
|
)
|
|
.route(
|
|
"/cases/{case_id}/reset",
|
|
post(case_actions::handle_reset_case),
|
|
)
|
|
.route(
|
|
"/cases/{case_id}/oneliner",
|
|
post(oneliner_override::handle_web_put_oneliner),
|
|
)
|
|
.route(
|
|
"/cases/purge-closed",
|
|
post(case_actions::handle_purge_closed),
|
|
)
|
|
.route("/cases/bulk", post(bulk::handle_bulk_action))
|
|
.route("/audio/{user}/{case_id}/{filename}", get(web::handle_audio))
|
|
.route("/events", get(events::handle_events))
|
|
}
|