Conversation
Phase 2 ReviewGood, solid work — rate limiting, audit logging, branding, session management, and RFC 7009 revocation are all implemented cleanly. The 53-test suite is a major improvement over Phase 1. A few things worth looking at: Security
{% when Some with (css) %}
<style>{{ css }}</style>Askama escapes
validation.validate_aud = false;This was added without a comment. For a JWT library that validates claims, silently disabling audience validation is a non-obvious security trade-off. Even if it's intentional (public clients, no fixed audience), a comment explaining the reasoning would help the next reader avoid re-adding it by mistake. Rate limiter map grows unbounded (
entry.retain(|t| *t > cutoff);
if entry.is_empty() {
attempts.remove(&ip);
}
RFC 7009 §2.1 says requests SHOULD include client credentials. The current implementation accepts revocations from anyone with knowledge of a valid refresh token. For public-client-only deployments this is acceptable, but it should be called out as a documented gap (it isn't listed in ROADMAP.md's Known Gaps). Code Quality
<button type="submit">{{ branding_title }}</button>Before this change the button said "Sign In". Now if
pub fn hex_encode(bytes: &[u8]) -> String {
bytes.iter().map(|b| format!("{b:02x}")).collect()
}
use std::fmt::Write;
pub fn hex_encode(bytes: &[u8]) -> String {
let mut s = String::with_capacity(bytes.len() * 2);
for b in bytes { let _ = write!(s, "{b:02x}"); }
s
}Duplicate realm+user lookup in The Test CoverageThese new modules have no tests:
The existing test for Minor Notes
Overall this is well-structured code with good separation of concerns, idiomatic Rust error handling, and solid coverage of the core cryptographic and DB paths. The issues above are mostly minor polish items — the main ones worth acting on are the |
No description provided.