use crate::types::error::{ErrorCode, HstpError};
use jsonwebtoken::{decode_header, jwk::AlgorithmParameters, DecodingKey, Validation};
use serde::{Deserialize, Serialize};
use super::jwks::JWKS_KEY_CONTENTS;
#[derive(Debug, Serialize, Deserialize)]
pub struct Claims {
pub sub: String, pub exp: u32, pub iat: u32, }
pub(crate) async fn decode_jwt(token: &str) -> Result<Claims, HstpError> {
let header = decode_header(token).map_err(HstpError::from_error)?;
let key_id = header.kid.ok_or_else(|| {
HstpError::new(
ErrorCode::None,
"Failed to decode JWT, key id not found".to_string(),
"".into(),
)
})?;
let jwks = JWKS_KEY_CONTENTS
.lock()
.expect("Unable to get JWKS_KEY_CONTENTS lock")
.clone();
let jwks = match jwks {
Some(jwks) => jwks,
None => {
return Err(HstpError::new(
ErrorCode::None,
"Failed to decode JWT, JWKS not set".to_string(),
"".into(),
))
}
};
let key = jwks.find(&key_id).ok_or_else(|| {
HstpError::new(
ErrorCode::None,
"Failed to decode JWT, key not found".to_string(),
"".into(),
)
})?;
let rsa = match &key.algorithm {
AlgorithmParameters::RSA(rsa) => rsa,
_ => {
return Err(HstpError::new(
ErrorCode::None,
"Failed to decode JWT, algorithm not supported".to_string(),
"".into(),
))
}
};
let decoding_key = DecodingKey::from_rsa_components(&rsa.n, &rsa.e).map_err(|e| {
HstpError::new(
ErrorCode::None,
format!("Failed to decode JWT from_rsa_components, {}", e),
"".into(),
)
})?;
let validation = &mut Validation::new(header.alg);
validation.validate_exp = false;
validation.validate_aud = false;
let decoded_token =
jsonwebtoken::decode::<Claims>(token, &decoding_key, validation).map_err(|e| {
HstpError::new(
ErrorCode::None,
format!("Failed to decode JWT (jsonwebtoken::decode): {}", e),
"".into(),
)
})?;
Ok(decoded_token.claims)
}