mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-04 00:47:01 +01:00
The file pane decided what to show by MIME type, and uploads keep a
type only when it cannot execute, so a .md, a .json or a .pem arrived
as application/octet-stream and got "no preview". It now goes by name
first (preview.ts), and a file with a name it does not know has its
first 8 KiB looked at: no NUL bytes and valid UTF-8 means text.
- text and code: the first 256 KiB with line numbers, as before
- markdown: rendered through the same sanitiser as documents, with a
source toggle
- CSV/TSV: a table of the first 500 rows, quotes respected
- PDF: the browser's own viewer in a frame. Only a PDF is served
without the sandbox CSP (Chrome's viewer will not start under it),
with frame-ancestors 'self' and X-Frame-Options SAMEORIGIN; the app
CSP allows same-origin frames.
- certificates, keys, keystores: POST /api/nodes/{id}/inspect reads
PEM (chains, keys, requests, public keys), DER and PKCS#12 on the
server, in pure Rust, including the RC2/3DES keystores that
openssl -legacy and older keychains write. It answers with subject,
issuer, validity, key, names, usage and fingerprints, and pairs each
private key with its certificate by public key. A password is asked
for only when needed, used for that one answer and never stored;
no key material is ever sent back. Sealed files are read through the
vault, and only while it is open.
The tests read throwaway fixtures under src/routes/testdata, made with
the openssl commands listed beside them; .gitignore lets their .pem
files past a global *.pem rule.
91 lines
3.6 KiB
TOML
91 lines
3.6 KiB
TOML
[package]
|
|
name = "narl-workspace"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
# The Proton crates set the floor.
|
|
rust-version = "1.96"
|
|
description = "A terminal-themed personal diary for the browser"
|
|
|
|
[dependencies]
|
|
axum = { version = "0.8", features = ["multipart", "macros"] }
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal", "fs", "io-util"] }
|
|
tower = "0.5"
|
|
tokio-util = { version = "0.7", features = ["io"] }
|
|
tower-http = { version = "0.6", features = ["trace", "compression-gzip", "limit", "set-header"] }
|
|
sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio", "sqlite", "migrate", "macros"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
dotenvy = "0.15"
|
|
uuid = { version = "1", features = ["v4"] }
|
|
rand = "0.8"
|
|
hmac = "0.12"
|
|
sha2 = "0.10"
|
|
base64 = "0.22"
|
|
subtle = "2"
|
|
mime_guess = "2"
|
|
rust-embed = { version = "8", features = ["interpolate-folder-path"] }
|
|
regex = "1"
|
|
anyhow = "1"
|
|
zip = { version = "2", default-features = false, features = ["deflate"] }
|
|
tempfile = "3.27.0"
|
|
# Only for `--features keyring`, on a host that has a Secret Service; the
|
|
# container deployment has no session bus and falls back to the session file.
|
|
keyring = { version = "3", features = ["sync-secret-service", "crypto-rust"], optional = true }
|
|
|
|
# Mail. rustls rather than native-tls: the container has no OpenSSL, and the
|
|
# Proton client already pulls rustls in.
|
|
lettre = { version = "0.11", default-features = false, features = ["smtp-transport", "pool", "builder", "hostname", "tokio1-rustls-tls"] }
|
|
# "did I write today?" and "is this due today?" are local-day questions, and DST
|
|
# rules out doing them with a fixed offset.
|
|
chrono = { version = "0.4", default-features = false, features = ["clock", "std"] }
|
|
chrono-tz = "0.10"
|
|
|
|
# The vault: files encrypted at rest under a key only a password unlocks.
|
|
# AES-256-GCM in the STREAM construction, so a file of any size is sealed and
|
|
# opened a chunk at a time; Argon2id between the password and the key.
|
|
aes-gcm = { version = "0.10", features = ["stream"] }
|
|
argon2 = "0.5"
|
|
zeroize = { version = "1", features = ["serde"] }
|
|
futures-util = { version = "0.3", default-features = false, features = ["std"] }
|
|
|
|
proton-drive-rs = "0.9.2"
|
|
proton-sdk = "0.9.2"
|
|
rpassword = "7"
|
|
hex = "0.4"
|
|
|
|
# SFTP mount: spaces and folders as a filesystem, authenticated by pubkey
|
|
# instead of the cookie session. `ring` rather than the default `aws-lc-rs`
|
|
# backend, because rustls (via lettre) already pulls `ring` in.
|
|
russh = { version = "0.63", default-features = false, features = ["ring", "rsa"] }
|
|
russh-sftp = "3"
|
|
# Only for generating the host key at first boot — ssh-key needs an rng that
|
|
# speaks rand_core 0.10, one major version past the `rand` used everywhere else.
|
|
rand10 = { package = "rand", version = "0.10" }
|
|
|
|
# Reading certificates, keys and keystores for the file view, in pure Rust —
|
|
# there is no OpenSSL to lean on. p12-keystore brings RC2 and 3DES for the
|
|
# keystores older tools still export; pkcs8 opens encrypted PKCS#8 keys.
|
|
x509-parser = "0.18"
|
|
p12-keystore = "0.4"
|
|
pkcs8 = { version = "0.11", features = ["encryption", "3des", "std"] }
|
|
sec1 = { version = "0.8", features = ["der"] }
|
|
sha1 = "0.10"
|
|
|
|
[dev-dependencies]
|
|
# A paused clock, so tests of timed loops do not wait in real time.
|
|
tokio = { version = "1", features = ["test-util"] }
|
|
|
|
[features]
|
|
default = []
|
|
# Keep the Proton session in the OS keyring instead of a 0600 file. Needs a
|
|
# Secret Service on D-Bus, so it is off for the container deployment.
|
|
keyring = ["dep:keyring"]
|
|
|
|
[profile.release]
|
|
opt-level = 3
|
|
lto = true
|
|
codegen-units = 1
|
|
strip = true
|