test(auth): read the clock once in NIP-FI until test (#8457)

🤖 The exact NIP-FI assertion-lifetime boundary test could fail when its
JWT helper read the clock, then ES256 signing crossed a whole-second
boundary. The token's `until` claim could land one second beyond the
verifier's `now + skew + maximum_age` ceiling even though both were
intended to use the same test instant.

This changes the test helper to accept a captured instant and uses that
instant for both the JWT time claims and `verify_at`. The boundary
remains strict: `now + 3630s` is accepted and `now + 3631s` is rejected.
No production code changes.

Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Alia <d32955ad69077062930cc46cfe2df30ca9aaf6f8e76422681265e9e9af704d78@buzz.block.builderlab.xyz>
Co-authored-by: Alia <d32955ad69077062930cc46cfe2df30ca9aaf6f8e76422681265e9e9af704d78@buzz.block.builderlab.xyz>
This commit is contained in:
Will Pfleger
2026-10-19 13:37:12 -04:00
committed by GitHub
parent dc4cdc4990
commit af7979e1ca

View File

@@ -948,7 +948,17 @@ mod tests {
until_offset_secs: i64, until_offset_secs: i64,
overrides: serde_json::Value, overrides: serde_json::Value,
) -> String { ) -> String {
let now = now_ts(); mint_cmd_jwt_at(target, Utc::now(), until_offset_secs, overrides)
}
/// Mint a command JWT using the supplied instant for all time claims.
fn mint_cmd_jwt_at(
target: &nostr::PublicKey,
now: DateTime<Utc>,
until_offset_secs: i64,
overrides: serde_json::Value,
) -> String {
let now = now.timestamp();
let mut claims = serde_json::json!({ let mut claims = serde_json::json!({
"iss": ISS, "iss": ISS,
"aud": AUD, "aud": AUD,
@@ -1225,14 +1235,14 @@ mod tests {
let target = target_key(); let target = target_key();
let now = Utc::now(); let now = Utc::now();
for until_offset in [3600, 30 + 3600, 1] { for until_offset in [3600, 30 + 3600, 1] {
let token = mint_cmd_jwt(&target, until_offset, serde_json::json!({})); let token = mint_cmd_jwt_at(&target, now, until_offset, serde_json::json!({}));
assert_eq!( assert_eq!(
cv.verify_at(&token, METHOD, PATH, &target, now).map(|_| ()), cv.verify_at(&token, METHOD, PATH, &target, now).map(|_| ()),
Ok(()), Ok(()),
"until = now + {until_offset}s must fit the ceiling" "until = now + {until_offset}s must fit the ceiling"
); );
} }
let token = mint_cmd_jwt(&target, 30 + 3600 + 1, serde_json::json!({})); let token = mint_cmd_jwt_at(&target, now, 30 + 3600 + 1, serde_json::json!({}));
assert_eq!( assert_eq!(
cv.verify_at(&token, METHOD, PATH, &target, now).map(|_| ()), cv.verify_at(&token, METHOD, PATH, &target, now).map(|_| ()),
Err(CommandError::UntilExceedsCeiling), Err(CommandError::UntilExceedsCeiling),