chore(v1.1.9): F4 — dedup TIMING_FLAT_DUMMY_HASH
Replace the inline copy of the Argon2id PHC dummy hash in crates/manager-core/src/auth_api.rs::login with a reference to the shared TIMING_FLAT_DUMMY_HASH constant in crates/manager-core/src/auth.rs (added in v1.1.8 but not yet adopted by the login path). Verification: `grep -rn 'argon2id\$v=19\$m=19456,t=2,p=1\$dGltaW5n' crates/` returns exactly one hit — the const declaration in auth.rs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -73,10 +73,9 @@ pub struct AdminUserDto {
|
||||
|
||||
async fn login(State(state): State<AuthState>, Json(input): Json<LoginRequest>) -> Response {
|
||||
// Always perform a verify, even on missing/inactive users, to flatten
|
||||
// timing and prevent username enumeration. The dummy hash is a real
|
||||
// Argon2id PHC string for "x" — the verify will simply fail.
|
||||
const DUMMY_HASH: &str = "$argon2id$v=19$m=19456,t=2,p=1$dGltaW5nLWZsYXR0ZW4$Ux6dgPqgX1Mhg5fRgIeKZF3MWdYqJplKEz/cKLcSdks";
|
||||
|
||||
// timing and prevent username enumeration. The dummy hash is the
|
||||
// shared `TIMING_FLAT_DUMMY_HASH` constant from `auth.rs` so the
|
||||
// single PHC value lives in exactly one place (v1.1.9 F4 dedup).
|
||||
let creds = match state
|
||||
.users
|
||||
.get_credentials_by_username(&input.username)
|
||||
@@ -93,7 +92,11 @@ async fn login(State(state): State<AuthState>, Json(input): Json<LoginRequest>)
|
||||
// canonical row used in the response DTO.
|
||||
let (stored_hash, user_id, is_active) = match creds {
|
||||
Some(c) => (c.password_hash, Some(c.id), c.is_active),
|
||||
None => (DUMMY_HASH.to_string(), None, false),
|
||||
None => (
|
||||
crate::auth::TIMING_FLAT_DUMMY_HASH.to_string(),
|
||||
None,
|
||||
false,
|
||||
),
|
||||
};
|
||||
|
||||
let password_ok = verify_password(&stored_hash, &input.password);
|
||||
|
||||
Reference in New Issue
Block a user