use thiserror::Error;
#[derive(Debug, Error)]
pub enum JWTError {
#[error("error-atproto-oauth-jwt-1 Invalid JWT format: expected 3 parts separated by dots")]
InvalidFormat,
#[error("error-atproto-oauth-jwt-2 Invalid JWT header: failed to decode or parse")]
InvalidHeader,
#[error(
"error-atproto-oauth-jwt-3 Unsupported JWT algorithm: algorithm {algorithm} incompatible with key type {key_type}"
)]
UnsupportedAlgorithm {
algorithm: String,
key_type: String,
},
#[error("error-atproto-oauth-jwt-4 Invalid JWT claims: failed to decode or parse")]
InvalidClaims,
#[error("error-atproto-oauth-jwt-5 Invalid JWT signature: failed to decode signature")]
InvalidSignature,
#[error("error-atproto-oauth-jwt-6 System time error: unable to get current timestamp")]
SystemTimeError,
#[error("error-atproto-oauth-jwt-7 JWT expired: token is past expiration time")]
TokenExpired,
#[error("error-atproto-oauth-jwt-8 JWT not valid yet: token is before not-before time")]
TokenNotValidYet,
#[error("error-atproto-oauth-jwt-9 Signature verification failed: invalid signature")]
SignatureVerificationFailed,
#[error("error-atproto-oauth-jwt-10 Invalid JWT payload: failed to decode payload")]
InvalidPayload,
#[error("error-atproto-oauth-jwt-11 Invalid JWT payload JSON: failed to parse payload as JSON")]
InvalidPayloadJson,
#[error("error-atproto-oauth-jwt-12 Missing required claim: {claim}")]
MissingClaim {
claim: String,
},
#[error("error-atproto-oauth-jwt-13 Invalid token type: expected '{expected}', got '{actual}'")]
InvalidTokenType {
expected: String,
actual: String,
},
#[error(
"error-atproto-oauth-jwt-14 HTTP method mismatch: expected '{expected}', got '{actual}'"
)]
HttpMethodMismatch {
expected: String,
actual: String,
},
#[error("error-atproto-oauth-jwt-15 HTTP URI mismatch: expected '{expected}', got '{actual}'")]
HttpUriMismatch {
expected: String,
actual: String,
},
#[error("error-atproto-oauth-jwt-16 Access token hash mismatch: invalid 'ath' claim")]
AccessTokenHashMismatch,
#[error("error-atproto-oauth-jwt-17 Invalid nonce: value '{nonce}' not in expected values")]
InvalidNonce {
nonce: String,
},
#[error("error-atproto-oauth-jwt-18 Invalid timestamp: {reason}")]
InvalidTimestamp {
reason: String,
},
}
#[derive(Debug, Error)]
pub enum JWKError {
#[error("error-atproto-oauth-jwk-1 P-256 JWK conversion failed: unable to convert to KeyData")]
P256ConversionFailed,
#[error("error-atproto-oauth-jwk-2 P-384 JWK conversion failed: unable to convert to KeyData")]
P384ConversionFailed,
#[error("error-atproto-oauth-jwk-3 K-256 JWK conversion failed: unable to convert to KeyData")]
K256ConversionFailed,
#[error("error-atproto-oauth-jwk-4 Unsupported curve: {curve}")]
UnsupportedCurve {
curve: String,
},
#[error("error-atproto-oauth-jwk-5 Unsupported key type: {kty}")]
UnsupportedKeyType {
kty: String,
},
#[error("error-atproto-oauth-jwk-6 Missing required field: {field}")]
MissingField {
field: String,
},
#[error("error-atproto-oauth-jwk-7 JWK serialization failed: {message}")]
SerializationError {
message: String,
},
}
#[derive(Debug, Error)]
pub enum OAuthClientError {
#[error("error-atproto-oauth-client-1 Authorization Server Request Failed: {0:?}")]
AuthorizationServerRequestFailed(reqwest::Error),
#[error("error-atproto-oauth-client-2 Malformed Authorization Server Response: {0:?}")]
MalformedAuthorizationServerResponse(reqwest::Error),
#[error("error-atproto-oauth-client-3 Invalid Authorization Server Response: {0:?}")]
InvalidAuthorizationServerResponse(anyhow::Error),
#[error("error-atproto-oauth-client-4 Invalid OAuth Protected Resource")]
InvalidOAuthProtectedResource,
#[error("error-atproto-oauth-client-5 OAuth Protected Resource Request Failed: {0:?}")]
OAuthProtectedResourceRequestFailed(reqwest::Error),
#[error("error-atproto-oauth-client-6 Malformed OAuth Protected Resource Response: {0:?}")]
MalformedOAuthProtectedResourceResponse(reqwest::Error),
#[error("error-atproto-oauth-client-7 Invalid OAuth Protected Resource Response: {0:?}")]
InvalidOAuthProtectedResourceResponse(anyhow::Error),
#[error("error-atproto-oauth-client-8 Token minting failed: {0:?}")]
MintTokenFailed(anyhow::Error),
#[error("error-atproto-oauth-client-9 JWT header creation from key failed: {0:?}")]
JWTHeaderCreationFailed(anyhow::Error),
#[error("error-atproto-oauth-client-10 DPoP token creation failed: {0:?}")]
DpopTokenCreationFailed(anyhow::Error),
#[error("error-atproto-oauth-client-11 PAR HTTP request failed: {0:?}")]
PARHttpRequestFailed(reqwest_middleware::Error),
#[error("error-atproto-oauth-client-12 PAR response JSON parsing failed: {0:?}")]
PARResponseJsonParsingFailed(reqwest::Error),
#[error("error-atproto-oauth-client-13 Token endpoint HTTP request failed: {0:?}")]
TokenHttpRequestFailed(reqwest_middleware::Error),
#[error("error-atproto-oauth-client-14 Token response JSON parsing failed: {0:?}")]
TokenResponseJsonParsingFailed(reqwest::Error),
}
#[derive(Debug, Error)]
pub enum ResourceValidationError {
#[error("error-atproto-oauth-resource-1 Resource must match PDS")]
ResourceMustMatchPds,
#[error("error-atproto-oauth-resource-2 Authorization servers must contain exactly one server")]
AuthorizationServersMustContainExactlyOne,
}
#[derive(Debug, Error)]
pub enum AuthServerValidationError {
#[error("error-atproto-oauth-auth-server-1 Issuer must match PDS")]
IssuerMustMatchPds,
#[error("error-atproto-oauth-auth-server-2 Response types supported must include 'code'")]
ResponseTypesSupportMustIncludeCode,
#[error(
"error-atproto-oauth-auth-server-3 Grant types supported must include 'authorization_code'"
)]
GrantTypesSupportMustIncludeAuthorizationCode,
#[error("error-atproto-oauth-auth-server-4 Grant types supported must include 'refresh_token'")]
GrantTypesSupportMustIncludeRefreshToken,
#[error(
"error-atproto-oauth-auth-server-5 Code challenge methods supported must include 'S256'"
)]
CodeChallengeMethodsSupportedMustIncludeS256,
#[error(
"error-atproto-oauth-auth-server-6 Token endpoint auth methods supported must include 'none'"
)]
TokenEndpointAuthMethodsSupportedMustIncludeNone,
#[error(
"error-atproto-oauth-auth-server-7 Token endpoint auth methods supported must include 'private_key_jwt'"
)]
TokenEndpointAuthMethodsSupportedMustIncludePrivateKeyJwt,
#[error(
"error-atproto-oauth-auth-server-8 Token endpoint auth signing algorithm values must include 'ES256'"
)]
TokenEndpointAuthSigningAlgValuesMustIncludeES256,
#[error("error-atproto-oauth-auth-server-9 Scopes supported must include 'atproto'")]
ScopesSupportedMustIncludeAtProto,
#[error(
"error-atproto-oauth-auth-server-10 Scopes supported must include 'transition:generic'"
)]
ScopesSupportedMustIncludeTransitionGeneric,
#[error(
"error-atproto-oauth-auth-server-11 DPoP signing algorithm values supported must include 'ES256'"
)]
DpopSigningAlgValuesSupportedMustIncludeES256,
#[error(
"error-atproto-oauth-auth-server-12 Authorization response parameters, pushed requests, client ID metadata must be supported"
)]
RequiredServerFeaturesMustBeSupported,
}
#[derive(Debug, Error)]
pub enum DpopError {
#[error("error-atproto-oauth-dpop-1 Unexpected OAuth error: {error}")]
UnexpectedOAuthError {
error: String,
},
#[error("error-atproto-oauth-dpop-2 Missing DPoP-Nonce response header")]
MissingDpopNonceHeader,
#[error("error-atproto-oauth-dpop-3 DPoP token minting failed: {0:?}")]
TokenMintingFailed(anyhow::Error),
#[error("error-atproto-oauth-dpop-4 HTTP header creation failed: {0:?}")]
HeaderCreationFailed(reqwest::header::InvalidHeaderValue),
#[error("error-atproto-oauth-dpop-5 Response body JSON parsing failed: {0:?}")]
ResponseBodyParsingFailed(reqwest::Error),
#[error("error-atproto-oauth-dpop-6 Response body is not a valid JSON object")]
ResponseBodyObjectParsingFailed,
}
#[derive(Debug, Error)]
pub enum OAuthStorageError {
#[error(
"error-atproto-oauth-storage-1 Cache lock acquisition failed for get operation: {details}"
)]
CacheLockFailedGet {
details: String,
},
#[error(
"error-atproto-oauth-storage-2 Cache lock acquisition failed for insert operation: {details}"
)]
CacheLockFailedInsert {
details: String,
},
#[error(
"error-atproto-oauth-storage-3 Cache lock acquisition failed for delete operation: {details}"
)]
CacheLockFailedDelete {
details: String,
},
#[error(
"error-atproto-oauth-storage-4 Cache lock acquisition failed for cleanup operation: {details}"
)]
CacheLockFailedCleanup {
details: String,
},
}