Login now persists properly rather than through the JSON file the test
harness was using.
dr-plat SecretStore trait plus a Secret Service backend.
Verified against the live GNOME Keyring: store,
retrieve, delete, confirm-gone all round-trip.
Session/SessionStore splits credentials from settings — the app
password goes to the keyring (FR-NC-2), while
server, login, chosen root and format selection are
ordinary config. A test asserts the credential never
appears in the config file.
LaunchModel the launch-screen state machine, testable without a
display server: sign in, approve in browser, choose
folder, tick formats, sign out.
launch.slint the screen itself, in its own file.
Absence of a secrets daemon is an explicit degraded mode, not a silent
fallback to plaintext — the screen says sign-in will not persist rather
than letting the user find out next launch. Android's Keystore backend
fails loudly for the same reason: a no-op store would look like it
worked and then lose the credential.
Two bugs caught by tests rather than by running it:
- fail() after busy() signed the user out, because busy() had already
discarded the session. A failed *scan* would have logged you out.
Busy now carries the session.
- normalise_server upgrades http:// to https:// rather than accepting
it. NFR-SEC-3 requires TLS, and silently sending a credential in the
clear is not a decision to make on the user's behalf.
launch.slint is not yet wired into app.slint. Calling slint_build::compile
twice replaces the generated module rather than adding to it, which broke
the other in-flight work on dr-ui; I reverted that immediately. Wiring it
needs an import inside app.slint, which is that work's file to change.
419 tests passing across ten crates.
124 lines
4.5 KiB
TOML
124 lines
4.5 KiB
TOML
[workspace]
|
|
resolver = "2"
|
|
members = [
|
|
"core/dr-types",
|
|
"core/dr-catalog",
|
|
"core/dr-decode",
|
|
"core/dr-gpu",
|
|
"core/dr-lens",
|
|
"core/dr-pipeline",
|
|
"core/dr-sync",
|
|
"core/dr-sync-nextcloud",
|
|
"platform/dr-plat",
|
|
"ui/dr-ui",
|
|
"apps/darkroom-desktop",
|
|
"tools/traceability",
|
|
]
|
|
|
|
[workspace.package]
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
rust-version = "1.92"
|
|
license = "GPL-3.0-or-later"
|
|
repository = "https://github.com/dtourolle/DarkRoom"
|
|
|
|
[workspace.dependencies]
|
|
# Internal
|
|
dr-types = { path = "core/dr-types" }
|
|
dr-catalog = { path = "core/dr-catalog" }
|
|
dr-decode = { path = "core/dr-decode" }
|
|
dr-gpu = { path = "core/dr-gpu" }
|
|
dr-lens = { path = "core/dr-lens" }
|
|
dr-pipeline = { path = "core/dr-pipeline" }
|
|
dr-plat = { path = "platform/dr-plat" }
|
|
dr-sync = { path = "core/dr-sync" }
|
|
dr-sync-nextcloud = { path = "core/dr-sync-nextcloud" }
|
|
dr-ui = { path = "ui/dr-ui" }
|
|
|
|
# GPU + UI
|
|
wgpu = "23"
|
|
slint = { version = "1.9", default-features = false }
|
|
slint-build = "1.9"
|
|
|
|
# Foundations
|
|
anyhow = "1"
|
|
thiserror = "2"
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
pollster = "0.4"
|
|
|
|
# Networking — no mature Nextcloud crate exists; the connector is hand-rolled
|
|
# over reqwest (D7). reqwest_dav was evaluated and is too thin to build on.
|
|
# `rustls-no-provider` rather than `rustls`: the latter defaults to the
|
|
# aws-lc-rs crypto provider, whose aws-lc-sys crate is C and fails to
|
|
# cross-compile for Android — precisely the NDK pain D1 chose Rust to avoid.
|
|
# ring is pure Rust apart from a small asm core that does build under the NDK.
|
|
#
|
|
# Note this still pulls rustls-platform-verifier, which crashes on Android
|
|
# unless initialised from Kotlin (spike S3). D7 records `tls_certs_only` plus
|
|
# webpki-roots as the escape hatch.
|
|
reqwest = { version = "0.13", default-features = false, features = ["rustls-no-provider", "stream", "json"] }
|
|
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12"] }
|
|
quick-xml = "0.41"
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time"] }
|
|
url = "2.5"
|
|
async-trait = "0.1"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
base64 = "0.23"
|
|
|
|
# Platform secure storage: Secret Service on Linux, Keystore on Android
|
|
# (FR-NC-2). Credentials never touch the catalog or a plain file.
|
|
# keyring 4 restructured its features: `v1` is the default set and brings
|
|
# the zbus Secret Service backend, which is what GNOME Keyring and KWallet
|
|
# (via ksecretd) both speak.
|
|
keyring = { version = "4", features = ["v1"] }
|
|
|
|
# Decode. rawler is the pure-Rust decoder (D2); zune-jpeg decodes the
|
|
# embedded previews rawler extracts.
|
|
# Catalog. `bundled` compiles SQLite from source rather than linking the
|
|
# system library — the same cross-compilation reasoning as the TLS choice
|
|
# above: no system dependency to satisfy under the Android NDK.
|
|
#
|
|
# `backup` is not optional in practice: it is what takes a consistent snapshot
|
|
# of a live WAL database for upload. A filesystem copy of `catalog.sqlite`
|
|
# while a `-wal` exists beside it uploads a torn file.
|
|
rusqlite = { version = "0.40", features = ["bundled", "backup"] }
|
|
|
|
rawler = "0.7"
|
|
zune-jpeg = "0.4.21"
|
|
bytemuck = { version = "1", features = ["derive"] }
|
|
|
|
# Lens correction profiles. A pure-Rust port of Lensfun rather than a binding
|
|
# to the C library, for the same cross-compilation reason as the TLS and
|
|
# SQLite choices above: liblensfun would be a third C dependency to satisfy
|
|
# under the Android NDK.
|
|
#
|
|
# The database ships *inside* the crate — 56 XML files, gzipped at build time
|
|
# and decompressed on first lookup. That matters beyond convenience: Android
|
|
# gives us no filesystem path (ARCH §6.9), so a database loaded from a
|
|
# system directory would have nowhere to live there.
|
|
#
|
|
# Licence: LGPL-3.0-or-later, which upgrades cleanly into our GPLv3 (D8).
|
|
# The upstream Lensfun *database* is CC-BY-SA and is redistributed by the
|
|
# crate; attribution belongs in the about screen.
|
|
#
|
|
# Caveat worth remembering: this is a third-party port at 0.7.0, not upstream
|
|
# Lensfun. Verified working against the bundled database (interpolation
|
|
# between calibration points, and an unknown lens returning empty rather than
|
|
# panicking), but the pipeline talks to it through its own profile types so
|
|
# swapping it out is not a pipeline change.
|
|
lensfun = "0.7"
|
|
|
|
[profile.dev]
|
|
# Dependencies optimised even in dev builds — wgpu and image decoding are
|
|
# unusably slow otherwise, and they rarely need debugging.
|
|
opt-level = 0
|
|
|
|
[profile.dev.package."*"]
|
|
opt-level = 2
|
|
|
|
[profile.release]
|
|
lto = "thin"
|
|
codegen-units = 1
|