feat: Implement dedicated 404 page for routes under /_continuwuity/

This commit is contained in:
Ginger 2026-03-04 11:18:07 -05:00
parent 43aa172829
commit eec7103910
No known key found for this signature in database
6 changed files with 24 additions and 14 deletions

View file

@ -1,6 +1,10 @@
use std::sync::Arc;
use axum::{Router, response::IntoResponse};
use axum::{
Router,
response::{IntoResponse, Redirect},
routing::get,
};
use conduwuit::Error;
use conduwuit_service::{Services, state, state::Guard};
use http::{StatusCode, Uri};
@ -10,7 +14,8 @@ pub(crate) fn build(services: &Arc<Services>) -> (Router, Guard) {
let router = Router::<state::State>::new();
let (state, guard) = state::create(services.clone());
let router = conduwuit_api::router::build(router, &services.server)
.merge(conduwuit_web::build())
.nest("/_continuwuity/", conduwuit_web::build())
.route("/", get(async || Redirect::permanent("/_continuwuity/")))
.fallback(not_found)
.with_state(state);

View file

@ -20,6 +20,8 @@ enum WebError {
ValidationError(#[from] validator::ValidationErrors),
#[error("Bad request: {0}")]
BadRequest(String),
#[error("This page does not exist.")]
NotFound,
#[error("Internal server error: {0}")]
InternalError(#[from] conduwuit_core::Error),
}
@ -28,14 +30,13 @@ impl IntoResponse for WebError {
fn into_response(self) -> Response {
#[derive(Debug, Template)]
#[template(path = "error.html.j2")]
#[allow(unused)]
struct Error {
error: WebError,
status: StatusCode,
}
let status = match &self {
| Self::ValidationError(_) | Self::BadRequest(_) => StatusCode::BAD_REQUEST,
| Self::NotFound => StatusCode::NOT_FOUND,
| _ => StatusCode::INTERNAL_SERVER_ERROR,
};
@ -57,6 +58,7 @@ pub fn build() -> Router<state::State> {
.merge(index::build())
.merge(resources::build())
.merge(password_reset::build())
.fallback(async || WebError::NotFound)
.layer(SetResponseHeaderLayer::if_not_present(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("default-src 'self'; img-src 'self' data:;"),

View file

@ -2,17 +2,13 @@ use askama::Template;
use axum::{
Router,
extract::State,
response::{Html, IntoResponse, Redirect},
response::{Html, IntoResponse},
routing::get,
};
use crate::WebError;
pub(crate) fn build() -> Router<crate::State> {
Router::new()
.route("/", get(async || Redirect::permanent("/_continuwuity/")))
.route("/_continuwuity/", get(index_handler))
}
pub(crate) fn build() -> Router<crate::State> { Router::new().route("/", get(index_handler)) }
async fn index_handler(
State(services): State<crate::State>,

View file

@ -6,7 +6,6 @@ use axum::{
response::{Html, IntoResponse, Response},
routing::get,
};
use conduwuit_service::password_reset::PASSWORD_RESET_PATH;
use serde::Deserialize;
use validator::Validate;
@ -54,7 +53,8 @@ form! {
}
pub(crate) fn build() -> Router<crate::State> {
Router::new().route(PASSWORD_RESET_PATH, get(get_password_reset).post(post_password_reset))
Router::new()
.route("/account/reset_password", get(get_password_reset).post(post_password_reset))
}
async fn password_reset_form(

View file

@ -2,7 +2,7 @@ use axum::Router;
pub(crate) fn build() -> Router<crate::State> {
Router::new().nest(
"/_continuwuity/resources/",
"/resources/",
#[allow(unused_qualifications)]
memory_serve::load!().index_file(None).into_router(),
)

View file

@ -21,7 +21,14 @@
 \二つ
</pre>
<div class="panel">
<h1>Request error<small aria-hidden>(︶^︶)</small></h1>
<h1>
{% if status == StatusCode::NOT_FOUND %}
Not found
{% else %}
Request error
{% endif %}
<small aria-hidden>(︶^︶)</small>
</h1>
<pre><code>{{ error }}</code></pre>
</div>