Phase 1 server: TLS + token auth, session registry, EchoDriver, SSE with cursors
The whole pipe behind one Driver trait and a common event model: spawn/list/delete sessions, message + question answering, append-only JSONL transcripts whose sequence numbers are the phone's resume cursor (surviving backend restarts), bearer-token middleware wrapping every route including the fallback, wg0-only binding that fails closed, and first-run token enrollment via a terminal QR. Verified: cargo test (10), clippy clean, and curl end-to-end over pinned TLS -- auth rejection, spawn, streamed SSE replay/resume, /question round trip, restart continuing seq numbers, delete removing everything. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xn8nHw1tw1R6PtiY1eEtw
This commit is contained in:
1 parent
a6ece28344
commit
967fc814ab
13 files changed
+3349
No files matched your search
@@ -0,0 +1,37 @@
|
||||
[package]
|
||||
name = "ai-server"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "ai-server"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
axum = { version = "0.8", features = ["json"] }
|
||||
axum-server = { version = "0.8", features = ["tls-rustls"] }
|
||||
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "sync", "time"] }
|
||||
tokio-stream = "0.1"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
anyhow = "1"
|
||||
thiserror = "2"
|
||||
# Token auth: hash for storage, constant-time compare for verification,
|
||||
# CSPRNG-backed generation, base64url for the enrollment string.
|
||||
sha2 = "0.11"
|
||||
subtle = "2"
|
||||
rand = "0.10"
|
||||
base64 = "0.23"
|
||||
# Renders the enrollment QR straight to the terminal; no image output needed.
|
||||
qrcode = { version = "0.14", default-features = false }
|
||||
# The wg0-bound listener needs the interface's address; the stdlib has no
|
||||
# getifaddrs. This is the smallest crate that wraps just that.
|
||||
if-addrs = "0.15"
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
# ServiceExt::oneshot, to drive the auth middleware without a socket.
|
||||
tower = { version = "0.5", features = ["util"] }
|
||||
Reference in new issue
Block a user