brewlog/Cargo.toml
Jon Seager 03e03d87d9
feat(auth): replace password auth with WebAuthn passkeys
Replace username/password authentication with FIDO2/WebAuthn passkey-based
auth using webauthn-rs. Sessions and bearer tokens are unchanged — only the
way they are created changes.

- Add webauthn-rs, uuid, open, url deps; remove argon2, rpassword
- Add passkey_credentials and registration_tokens tables (migrations 17-18)
- Add domain entities, typed IDs, and repository traits for passkeys/tokens
- Add SQL repository implementations for passkeys and registration tokens
- Add ChallengeStore for in-memory WebAuthn ceremony state
- Add WebAuthn route handlers (register/auth start+finish ceremonies)
- Add CLI browser handoff for token creation (opens browser, local callback)
- Replace login form with "Sign in with Passkey" button
- Add registration page for first-user bootstrap via one-time token
- Replace BREWLOG_ADMIN_USERNAME/PASSWORD with BREWLOG_RP_ID/RP_ORIGIN
- Change default BREWLOG_URL from 127.0.0.1 to localhost (WebAuthn requires it)
2026-02-05 11:00:07 +00:00

89 lines
2.9 KiB
TOML

[package]
name = "brewlog"
version = "0.1.0"
edition = "2024"
[features]
default = ["sqlite"]
sqlite = ["sqlx/sqlite"]
postgres = ["sqlx/postgres"]
[dependencies]
anyhow = "1.0"
async-trait = "0.1"
axum = { version = "0.7", features = ["macros"] }
askama = "0.12"
base64 = "0.22"
chrono = { version = "0.4", features = ["serde", "clock"] }
clap = { version = "4.5", features = ["derive", "env"] }
dotenvy = "0.15"
isocountry = "0.3"
open = "5"
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls", "gzip"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rand = "0.8"
sha2 = "0.10"
sqlx = { version = "0.7", default-features = false, features = [
"runtime-tokio",
"tls-rustls",
"macros",
"chrono",
"any",
"migrate",
] }
thiserror = "1.0"
tokio = { version = "1.38", features = ["rt-multi-thread", "macros", "signal"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tower = "0.4"
tower-cookies = "0.10"
slug = "0.1.6"
tracing-bunyan-formatter = "0.3.10"
tracing-log = "0.2.0"
url = "2"
uuid = { version = "1", features = ["v4"] }
webauthn-rs = { version = "0.5", features = ["danger-allow-state-serialisation"] }
webauthn-rs-proto = "0.5"
[dev-dependencies]
portpicker = "0.1"
reqwest = { version = "0.12", default-features = false, features = ["blocking", "cookies", "rustls-tls"] }
tempfile = "3.8"
once_cell = "1.19"
webauthn-authenticator-rs = { version = "0.5", features = ["softpasskey"] }
wiremock = "0.6"
[[test]]
name = "cli"
path = "tests/cli/main.rs"
harness = true
[profile.test]
# Run CLI tests serially to share single server instance
opt-level = 0
[[test]]
name = "server"
path = "tests/server/main.rs"
harness = true
[lints.clippy]
# Enable pedantic lints with lower priority so individual allows take precedence
pedantic = { level = "warn", priority = -1 }
# Pedantic lints to disable (too noisy or not applicable)
missing_errors_doc = "allow" # Would require extensive doc changes
missing_panics_doc = "allow" # Would require extensive doc changes
module_name_repetitions = "allow" # Common pattern in domain types (e.g., RoasterId in roasters)
must_use_candidate = "allow" # Too aggressive for this codebase
return_self_not_must_use = "allow" # Builder methods returning Self are common
needless_pass_by_value = "allow" # Generic T: ToString pattern and consumed value types
cast_possible_truncation = "allow" # Pagination values won't exceed u32 in practice
cast_sign_loss = "allow" # Database counts are non-negative
# Cherry-picked restriction lints (production safety)
dbg_macro = "deny" # Prevent debug macros in production
todo = "warn" # Flag TODOs for attention
unwrap_used = "warn" # Flag unwrap() for review; allow where justified
expect_used = "warn" # Flag expect() for review; allow where justified