diff --git a/relay_rpc/src/jwt.rs b/relay_rpc/src/jwt.rs index 7bbf3d2..406c467 100644 --- a/relay_rpc/src/jwt.rs +++ b/relay_rpc/src/jwt.rs @@ -22,11 +22,20 @@ pub enum JwtError { #[error("Invalid JWT signing algorithm")] Header, - #[error("JWT Token is expired")] - Expired, - - #[error("JWT Token is not yet valid")] - NotYetValid, + #[error("JWT Token is expired: {:?}", expiration)] + Expired { expiration: Option }, + + #[error( + "JWT Token is not yet valid: basic.iat: {}, now + time_leeway: {}, time_leeway: {}", + basic_iat, + now_time_leeway, + time_leeway + )] + NotYetValid { + basic_iat: i64, + now_time_leeway: i64, + time_leeway: i64, + }, #[error("Invalid audience")] InvalidAudience, @@ -202,11 +211,17 @@ pub trait VerifyableClaims: Serialize + DeserializeOwned { let now = Utc::now().timestamp(); if matches!(basic.exp, Some(exp) if now - time_leeway > exp) { - return Err(JwtError::Expired); + return Err(JwtError::Expired { + expiration: basic.exp, + }); } if now + time_leeway < basic.iat { - return Err(JwtError::NotYetValid); + return Err(JwtError::NotYetValid { + basic_iat: basic.iat, + now_time_leeway: now + time_leeway, + time_leeway, + }); } if !aud.contains(&basic.aud) { @@ -278,7 +293,7 @@ mod test { .unwrap(); assert!(matches!( Jwt(jwt.into()).decode(&aud), - Err(JwtError::NotYetValid) + Err(JwtError::NotYetValid { .. }) )); // IAT leeway, valid. @@ -297,7 +312,7 @@ mod test { .unwrap(); assert!(matches!( Jwt(jwt.into()).decode(&aud), - Err(JwtError::NotYetValid) + Err(JwtError::NotYetValid { .. }) )); // Past expiration. @@ -308,7 +323,7 @@ mod test { .unwrap(); assert!(matches!( Jwt(jwt.into()).decode(&aud), - Err(JwtError::Expired) + Err(JwtError::Expired { .. }) )); // Expiration leeway, valid. @@ -333,7 +348,7 @@ mod test { .unwrap(); assert!(matches!( Jwt(jwt.into()).decode(&aud), - Err(JwtError::Expired) + Err(JwtError::Expired { .. }) )); // Invalid aud.