diff options
-rw-r--r-- | resources/404.svg | 93 | ||||
-rw-r--r-- | src/api/web.rs | 15 | ||||
-rw-r--r-- | src/config.rs | 2 | ||||
-rw-r--r-- | src/static/images/404.png | bin | 0 -> 5042 bytes | |||
-rw-r--r-- | src/static/templates/404.hbs | 62 |
5 files changed, 167 insertions, 5 deletions
diff --git a/resources/404.svg b/resources/404.svg new file mode 100644 index 00000000..112db68d --- /dev/null +++ b/resources/404.svg @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="500" + height="222" + viewBox="0 0 500 222" + version="1.1" + id="svg5" + xml:space="preserve" + inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)" + sodipodi:docname="404.svg" + inkscape:export-filename="404.png" + inkscape:export-xdpi="96" + inkscape:export-ydpi="96" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview + id="namedview7" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:document-units="px" + showgrid="false" + inkscape:zoom="1.3791767" + inkscape:cx="284.59007" + inkscape:cy="214.25826" + inkscape:window-width="1916" + inkscape:window-height="1038" + inkscape:window-x="0" + inkscape:window-y="18" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + showguides="false" /><defs + id="defs2"><mask + id="holes"><rect + x="-60" + y="-60" + width="120" + height="120" + fill="#ffffff" + id="rect3296" /><circle + id="hole" + cy="-40" + r="3" + cx="0" /><use + transform="rotate(72)" + xlink:href="#hole" + id="use3299" /><use + transform="rotate(144)" + xlink:href="#hole" + id="use3301" /><use + transform="rotate(-144)" + xlink:href="#hole" + id="use3303" /><use + transform="rotate(-72)" + xlink:href="#hole" + id="use3305" /></mask></defs><g + inkscape:label="Ebene 1" + inkscape:groupmode="layer" + id="layer1"><rect + style="fill:none;fill-opacity:0.5;stroke:none;stroke-width:0.74;stroke-opacity:1" + id="rect681" + width="666" + height="222" + x="0" + y="0" /><text + xml:space="preserve" + style="font-size:128px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:center;text-anchor:middle;fill:#000000;fill-opacity:0.7;stroke-width:1" + x="249.9375" + y="134.8125" + id="text3425"><tspan + id="tspan3423" + x="249.9375" + y="134.8125" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:128px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:center;text-anchor:middle;fill:#000000;fill-opacity:0.7;stroke-width:1" + sodipodi:role="line">404</tspan></text><text + xml:space="preserve" + style="font-size:26.6667px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:center;text-anchor:middle" + x="249.04297" + y="194.68582" + id="text4067"><tspan + sodipodi:role="line" + id="tspan4065" + x="249.04295" + y="194.68582" + style="font-size:26.6667px;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:0.7">Return to the web vault?</tspan></text></g></svg> diff --git a/src/api/web.rs b/src/api/web.rs index e5485123..a7640cd9 100644 --- a/src/api/web.rs +++ b/src/api/web.rs @@ -1,11 +1,10 @@ use std::path::{Path, PathBuf}; -use rocket::serde::json::Json; -use rocket::{fs::NamedFile, http::ContentType, Catcher, Route}; +use rocket::{fs::NamedFile, http::ContentType, response::content::RawHtml as Html, serde::json::Json, Catcher, Route}; use serde_json::Value; use crate::{ - api::core::now, + api::{core::now, ApiResult}, error::Error, util::{Cached, SafeString}, CONFIG, @@ -30,8 +29,13 @@ pub fn catchers() -> Vec<Catcher> { } #[catch(404)] -async fn not_found() -> Cached<Option<NamedFile>> { - Cached::short(NamedFile::open(Path::new(&CONFIG.web_vault_folder()).join("404.html")).await.ok(), false) +fn not_found() -> ApiResult<Html<String>> { + // Return the page + let json = json!({ + "urlpath": CONFIG.domain_path() + }); + let text = CONFIG.render_template("404", &json)?; + Ok(Html(text)) } #[get("/")] @@ -91,6 +95,7 @@ fn alive(_conn: DbConn) -> Json<String> { #[get("/vw_static/<filename>")] pub fn static_files(filename: String) -> Result<(ContentType, &'static [u8]), Error> { match filename.as_ref() { + "404.png" => Ok((ContentType::PNG, include_bytes!("../static/images/404.png"))), "mail-github.png" => Ok((ContentType::PNG, include_bytes!("../static/images/mail-github.png"))), "logo-gray.png" => Ok((ContentType::PNG, include_bytes!("../static/images/logo-gray.png"))), "error-x.svg" => Ok((ContentType::SVG, include_bytes!("../static/images/error-x.svg"))), diff --git a/src/config.rs b/src/config.rs index fbf0e412..eb776bb9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1123,6 +1123,8 @@ where reg!("admin/organizations"); reg!("admin/diagnostics"); + reg!("404"); + // And then load user templates to overwrite the defaults // Use .hbs extension for the files // Templates get registered with their relative name diff --git a/src/static/images/404.png b/src/static/images/404.png Binary files differnew file mode 100644 index 00000000..a76ddb04 --- /dev/null +++ b/src/static/images/404.png diff --git a/src/static/templates/404.hbs b/src/static/templates/404.hbs new file mode 100644 index 00000000..dc30b9e4 --- /dev/null +++ b/src/static/templates/404.hbs @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> + <meta name="robots" content="noindex,nofollow" /> + <link rel="icon" type="image/png" href="{{urlpath}}/vw_static/vaultwarden-icon.png"> + <title>Page not found!</title> + <link rel="stylesheet" href="{{urlpath}}/vw_static/bootstrap.css" /> + <style> + body { + padding-top: 75px; + } + .vaultwarden-icon { + width: 48px; + height: 48px; + height: 32px; + width: auto; + margin: -5px 0 0 0; + } + .footer { + padding: 40px 0 40px 0; + border-top: 1px solid #dee2e6; + } + .container { + max-width: 980px; + } + .content { + padding-top: 20px; + padding-bottom: 20px; + padding-left: 15px; + padding-right: 15px; + } + </style> +</head> + +<body class="bg-light"> + + <nav class="navbar navbar-expand-md navbar-dark bg-dark mb-4 shadow fixed-top"> + <div class="container"> + <a class="navbar-brand" href="{{urlpath}}/"><img class="vaultwarden-icon" src="{{urlpath}}/vw_static/vaultwarden-icon.png" alt="V">aultwarden</a> + <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" + aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarCollapse"> + <ul class="navbar-nav me-auto"> + </div> + </div> + </nav> + + <main class="container inner content text-center"> + <h2>Page not found!</h2> + <p class="lead">Sorry, but the page you were looking for could not be found.</p> + <p class="display-6"> + <a href="{{urlpath}}/"><img style="max-width: 500px; width: 100%;" src="{{urlpath}}/vw_static/404.png" alt="Return to the web vault?"></a></p> + <p>You can <a href="{{urlpath}}/">return to the web-vault</a>, or <a href="https://github.com/dani-garcia/vaultwarden">contact us</a>.</p> + </main> + + <div class="container footer text-muted content">Vaultwarden (unofficial Bitwarden® server)</div> +</body> +</html> |