Rate limiting (closes the last security gap #3):
- New RateLimiter: in-memory fixed-window IP-based limiter (std::sync::Mutex
HashMap, no new deps). Configurable via RATE_LIMIT_MAX (default 100) +
RATE_LIMIT_WINDOW_SECS (default 60) env vars.
- general_rate_limit_middleware now reads ClientIp from request extensions and
rejects with 429 + Retry-After header when over the limit. Wired via
from_fn_with_state in app.rs. Lived on AppState as Arc<RateLimiter>.
- Deleted the dead auth_rate_limit_middleware (never wired).
- 3 unit tests (allows up to N, independent IPs, window reset).
E2E crypto lifecycle test:
- Full zero-knowledge round-trip against jsdom's real Web Crypto: setup →
encrypt → verify ciphertext → unlock with password → decrypt → recover via
phrase → rewrap under new password → decrypt. Plus wrong-password/wrong-phrase
failures and cross-user key isolation.
- Fixed wrapDek/unwrapDek: base64-encode raw DEK bytes (was using TextDecoder
which produced non-base64), and make unwrapped DEK extractable (needed for
rewrapDek to export).
Verified: backend 24 tests 0 warnings; frontend 24 tests, build clean.
Refresh-token rotation bug (found via Solaria smoke test):
* RefreshClaims now carries a unique random jti (UUID v4). Without it, two
refresh tokens issued in the same second (e.g. on rotation) were byte-identical
— breaking rotation, colliding on the tokenHash unique index, and making a
stolen old token indistinguishable from the new one. Every refresh token is
now unique regardless of issue time. Added a unit test asserting consecutive
tokens differ.
Code cleanup (review items):
* #15: removed unused deps tower_governor, slog, thiserror (zero refs in src/).
* #30: deleted leftover src/main.rs.restore (a stale git-error-message backup).
* #28: removed the 9 single-line-comment stub files under src/db/ (appointment,
family, health_data, lab_result, medication, profile, permission, share, user)
and their mod declarations; nothing referenced them, real logic lives in
mongodb_impl.rs/init.rs.
* #29: stripped 61 broad module-level #![allow(...)] suppressions across src/.
Fixed the surfaced warnings instead: 4 unused 'claims' extractor bindings ->
_claims; removed dead OpenFDAService.client/base_url fields + the never-called
query_drug_events method + unused HashMap/reqwest imports; applied clippy's
mechanical fixes (Ok(?) -> ?, Copy ObjectId clone, redundant closures,
useless conversions); rewrote 'if let Ok(_) = x' -> 'if x.is_ok()'. Result:
cargo build + clippy --all-targets are warning-free with no blanket allows.
Verified: fmt clean, build clean, clippy 0 warnings, 19 unit tests pass
(was 18; +1 jti-uniqueness test).
- Apply rustfmt to all Rust source files in backend/
- Fix trailing whitespace inconsistencies
- Standardize formatting across handlers, models, and services
- Improve code readability with consistent formatting
These changes are purely stylistic and do not affect functionality.
All CI checks now pass with proper formatting.