1use serde::de::DeserializeOwned;
2use ssi_claims_core::{DateTimeProvider, ProofValidationError, ResolverProvider, Verification};
3use ssi_jwk::JWKResolver;
4use ssi_jws::{DecodeError as JWSDecodeError, DecodedJws, JwsSlice, JwsStr, JwsString, JwsVec};
5
6use crate::{AnyClaims, JWTClaims};
7
8#[derive(Debug, thiserror::Error)]
9pub enum DecodeError {
10 #[error("invalid JWS: {0}")]
11 JWS(#[from] JWSDecodeError),
12
13 #[error("invalid JWT claims: {0}")]
14 Claims(#[from] serde_json::Error),
15}
16
17impl From<DecodeError> for ProofValidationError {
18 fn from(value: DecodeError) -> Self {
19 Self::InvalidInputData(value.to_string())
20 }
21}
22
23pub type DecodedJwt<'a, T = AnyClaims> = DecodedJws<'a, JWTClaims<T>>;
27
28pub trait ToDecodedJwt {
30 fn to_decoded_custom_jwt<C: DeserializeOwned>(&self) -> Result<DecodedJwt<C>, DecodeError>;
32
33 fn to_decoded_jwt(&self) -> Result<DecodedJwt, DecodeError> {
35 self.to_decoded_custom_jwt::<AnyClaims>()
36 }
37
38 #[allow(async_fn_in_trait)]
42 async fn verify_jwt<V>(&self, verifier: &V) -> Result<Verification, ProofValidationError>
43 where
44 V: ResolverProvider + DateTimeProvider,
45 V::Resolver: JWKResolver,
46 {
47 self.to_decoded_jwt()?.verify(verifier).await
48 }
49}
50
51pub trait IntoDecodedJwt: Sized {
53 fn into_decoded_custom_jwt<C: DeserializeOwned>(
55 self,
56 ) -> Result<DecodedJwt<'static, C>, DecodeError>;
57
58 fn into_decoded_jwt(self) -> Result<DecodedJwt<'static>, DecodeError> {
59 self.into_decoded_custom_jwt::<AnyClaims>()
60 }
61}
62
63impl ToDecodedJwt for JwsSlice {
64 fn to_decoded_custom_jwt<C: DeserializeOwned>(&self) -> Result<DecodedJwt<C>, DecodeError> {
65 self.decode()?
66 .try_map(|bytes| serde_json::from_slice(&bytes).map_err(Into::into))
67 }
68}
69
70impl ToDecodedJwt for JwsStr {
71 fn to_decoded_custom_jwt<C: DeserializeOwned>(&self) -> Result<DecodedJwt<C>, DecodeError> {
72 JwsSlice::to_decoded_custom_jwt(self)
73 }
74}
75
76impl ToDecodedJwt for JwsVec {
77 fn to_decoded_custom_jwt<C: DeserializeOwned>(&self) -> Result<DecodedJwt<C>, DecodeError> {
78 JwsSlice::to_decoded_custom_jwt(self)
79 }
80}
81
82impl IntoDecodedJwt for JwsVec {
83 fn into_decoded_custom_jwt<C: DeserializeOwned>(
84 self,
85 ) -> Result<DecodedJwt<'static, C>, DecodeError> {
86 self.into_decoded()?
87 .try_map(|bytes| serde_json::from_slice(&bytes).map_err(Into::into))
88 }
89}
90
91impl ToDecodedJwt for JwsString {
92 fn to_decoded_custom_jwt<C: DeserializeOwned>(&self) -> Result<DecodedJwt<C>, DecodeError> {
93 JwsSlice::to_decoded_custom_jwt(self)
94 }
95}
96
97impl IntoDecodedJwt for JwsString {
98 fn into_decoded_custom_jwt<C: DeserializeOwned>(
99 self,
100 ) -> Result<DecodedJwt<'static, C>, DecodeError> {
101 self.into_decoded()?
102 .try_map(|bytes| serde_json::from_slice(&bytes).map_err(Into::into))
103 }
104}