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>(
32 &'_ self,
33 ) -> Result<DecodedJwt<'_, C>, DecodeError>;
34
35 fn to_decoded_jwt(&'_ self) -> Result<DecodedJwt<'_>, DecodeError> {
37 self.to_decoded_custom_jwt::<AnyClaims>()
38 }
39
40 #[allow(async_fn_in_trait)]
44 async fn verify_jwt<V>(&self, verifier: &V) -> Result<Verification, ProofValidationError>
45 where
46 V: ResolverProvider + DateTimeProvider,
47 V::Resolver: JWKResolver,
48 {
49 self.to_decoded_jwt()?.verify(verifier).await
50 }
51}
52
53pub trait IntoDecodedJwt: Sized {
55 fn into_decoded_custom_jwt<C: DeserializeOwned>(
57 self,
58 ) -> Result<DecodedJwt<'static, C>, DecodeError>;
59
60 fn into_decoded_jwt(self) -> Result<DecodedJwt<'static>, DecodeError> {
61 self.into_decoded_custom_jwt::<AnyClaims>()
62 }
63}
64
65impl ToDecodedJwt for JwsSlice {
66 fn to_decoded_custom_jwt<C: DeserializeOwned>(
67 &'_ self,
68 ) -> Result<DecodedJwt<'_, C>, DecodeError> {
69 self.decode()?
70 .try_map(|bytes| serde_json::from_slice(&bytes).map_err(Into::into))
71 }
72}
73
74impl ToDecodedJwt for JwsStr {
75 fn to_decoded_custom_jwt<C: DeserializeOwned>(
76 &'_ self,
77 ) -> Result<DecodedJwt<'_, C>, DecodeError> {
78 JwsSlice::to_decoded_custom_jwt(self)
79 }
80}
81
82impl ToDecodedJwt for JwsVec {
83 fn to_decoded_custom_jwt<C: DeserializeOwned>(
84 &'_ self,
85 ) -> Result<DecodedJwt<'_, C>, DecodeError> {
86 JwsSlice::to_decoded_custom_jwt(self)
87 }
88}
89
90impl IntoDecodedJwt for JwsVec {
91 fn into_decoded_custom_jwt<C: DeserializeOwned>(
92 self,
93 ) -> Result<DecodedJwt<'static, C>, DecodeError> {
94 self.into_decoded()?
95 .try_map(|bytes| serde_json::from_slice(&bytes).map_err(Into::into))
96 }
97}
98
99impl ToDecodedJwt for JwsString {
100 fn to_decoded_custom_jwt<C: DeserializeOwned>(
101 &'_ self,
102 ) -> Result<DecodedJwt<'_, C>, DecodeError> {
103 JwsSlice::to_decoded_custom_jwt(self)
104 }
105}
106
107impl IntoDecodedJwt for JwsString {
108 fn into_decoded_custom_jwt<C: DeserializeOwned>(
109 self,
110 ) -> Result<DecodedJwt<'static, C>, DecodeError> {
111 self.into_decoded()?
112 .try_map(|bytes| serde_json::from_slice(&bytes).map_err(Into::into))
113 }
114}