1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
use super::{Jwk, KeyPair};
use serde::Serialize;
/// Represents a JSON Web Key Set (JWKS).
///
/// JWKS is a set of keys containing the cryptographic information
/// required to verify tokens or signatures. This struct is typically
/// used to convey public keys in a JWKS endpoint.
#[derive(Serialize)]
pub struct Jwks {
    /// A collection of `Jwk` objects, each representing a public key.
    pub keys: Vec<Jwk>,
}
impl Jwks {
    /// Filters and returns a `Jwks` instance containing only the non-expired keys
    /// from the given `key_pairs`.
    ///
    /// This method is used to prepare a JWKS response with valid keys, omitting
    /// any that have expired.
    ///
    /// # Arguments
    ///
    /// * `key_pairs` - A vector of `KeyPair` instances.
    ///
    /// # Returns
    ///
    /// Returns a `Jwks` instance containing only valid, non-expired `Jwk` keys.
    pub fn from_valid_pairs(key_pairs: Vec<KeyPair>) -> Self {
        Self {
            keys: key_pairs
                .into_iter()
                .filter_map(|jwt_key| {
                    if !jwt_key.is_expired() {
                        Some(Jwk::new(&jwt_key.kid, &jwt_key.public_key))
                    } else {
                        None
                    }
                })
                .collect(),
        }
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    fn mock_key_pair(kid: &str, is_expired: bool) -> KeyPair {
        let expiration = if is_expired { -72_000 } else { 72_000 };
        KeyPair::new(&kid.to_string(), expiration).unwrap()
    }
    #[test]
    fn test_from_valid_pairs() {
        let key_pairs = vec![
            mock_key_pair("valid1", false),
            mock_key_pair("expired1", true),
            mock_key_pair("valid2", false),
            mock_key_pair("expired2", true),
            mock_key_pair("valid3", false),
            mock_key_pair("valid4", false),
            mock_key_pair("expired3", true),
            mock_key_pair("valid5", false),
        ];
        let jwks = Jwks::from_valid_pairs(key_pairs);
        assert_eq!(
            jwks.keys.len(),
            5,
            "Jwks should only include non-expired keys."
        );
    }
}