1use crate::{claims::JwtClaims, jwks::JwksStore};
2use anyhow::{Result, anyhow};
3use jsonwebtoken::{Validation, decode, decode_header};
4
5pub async fn validate_token<T: JwtClaims>(
6 token: &str,
7 jwks: &JwksStore,
8 expected_issuer: &str,
9 expected_audience: Option<&str>,
10) -> Result<T> {
11 let header = decode_header(token)?;
12 let kid = header.kid.ok_or_else(|| anyhow!("Missing kid"))?;
13 let key = jwks
14 .get_key(&kid)
15 .await
16 .ok_or_else(|| anyhow!("Key not found"))?;
17
18 let mut validation = Validation::new(header.alg);
19 validation.set_issuer(&[expected_issuer]);
20 if let Some(aud) = expected_audience {
21 validation.set_audience(&[aud]);
22 }
23
24 let token_data = decode::<T>(token, &key, &validation)?;
25 Ok(token_data.claims)
26}