mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-04 00:47:01 +01:00
Single-user diary served as one Rust binary with the Svelte frontend embedded. - axum 0.8 + SQLite (sqlx), migrations run at startup - stateless HMAC session cookie; credentials from .env, compared in constant time - FTS5 full-text search, user input rewritten into quoted prefix terms - media uploads linked to entries by scanning bodies for /api/media/<id>, which scopes share-token media access and entry deletion - unguessable share links (192-bit token) serving a public read-only page - vim keybindings via CodeMirror plus a modal browse layer and : command line; disabled on touch devices
46 lines
1.4 KiB
Rust
46 lines
1.4 KiB
Rust
use axum::{
|
|
http::{header, StatusCode, Uri},
|
|
response::{IntoResponse, Response},
|
|
};
|
|
use rust_embed::Embed;
|
|
|
|
/// The built Svelte app. In debug builds rust-embed reads from disk, so a
|
|
/// `vite build --watch` next to `cargo run` is enough for iteration.
|
|
#[derive(Embed)]
|
|
#[folder = "$CARGO_MANIFEST_DIR/web/dist"]
|
|
struct Assets;
|
|
|
|
pub async fn handler(uri: Uri) -> Response {
|
|
let path = uri.path().trim_start_matches('/');
|
|
match Assets::get(path) {
|
|
Some(file) => serve(path, file),
|
|
// Unknown paths are client-side routes; hand them the shell.
|
|
None => match Assets::get("index.html") {
|
|
Some(index) => serve("index.html", index),
|
|
None => (
|
|
StatusCode::NOT_FOUND,
|
|
"frontend not built - run `bun run build` in web/",
|
|
)
|
|
.into_response(),
|
|
},
|
|
}
|
|
}
|
|
|
|
fn serve(path: &str, file: rust_embed::EmbeddedFile) -> Response {
|
|
let mime = mime_guess::from_path(path).first_or_octet_stream();
|
|
// Vite fingerprints everything under /assets/, so it is safe to cache hard.
|
|
let cache = if path.starts_with("assets/") {
|
|
"public, max-age=31536000, immutable"
|
|
} else {
|
|
"no-cache"
|
|
};
|
|
(
|
|
[
|
|
(header::CONTENT_TYPE, mime.as_ref()),
|
|
(header::CACHE_CONTROL, cache),
|
|
],
|
|
file.data,
|
|
)
|
|
.into_response()
|
|
}
|