axum_gate/codecs/
mod.rs

1//! JWT and token encoding/decoding infrastructure.
2//!
3//! This module provides the [`Codec`] trait for pluggable token encoding/decoding and
4//! a complete JWT implementation via the [`jwt`] submodule. The codec system allows
5//! axum-gate to work with different token formats while maintaining type safety.
6//!
7//! # JWT Implementation
8//!
9//! The primary implementation is [`jwt::JsonWebToken`], which provides secure JWT
10//! encoding/decoding with customizable keys and validation:
11//!
12//! ```rust
13//! use axum_gate::codecs::jwt::{JsonWebToken, JwtClaims, JsonWebTokenOptions};
14//! use axum_gate::accounts::Account;
15//! use axum_gate::prelude::{Role, Group};
16//! use std::sync::Arc;
17//!
18//! // Use default (random key - development only)
19//! let jwt_codec = Arc::new(JsonWebToken::<JwtClaims<Account<Role, Group>>>::default());
20//!
21//! // Production: use persistent key
22//! let options = JsonWebTokenOptions {
23//!     enc_key: jsonwebtoken::EncodingKey::from_secret(b"your-secret-key"),
24//!     dec_key: jsonwebtoken::DecodingKey::from_secret(b"your-secret-key"),
25//!     header: None,
26//!     validation: None,
27//! };
28//! let jwt_codec = Arc::new(JsonWebToken::<JwtClaims<Account<Role, Group>>>::new_with_options(options));
29//! ```
30//!
31//! # Custom Codec Implementation
32//!
33//! Implement the [`Codec`] trait for custom token formats:
34//!
35//! ```rust
36//! use axum_gate::codecs::Codec;
37//! use axum_gate::errors::Result;
38//! use serde::{Serialize, Deserialize};
39//!
40//! #[derive(Clone)]
41//! struct CustomCodec {
42//!     secret: String,
43//! }
44//!
45//! #[derive(Serialize, Deserialize)]
46//! struct CustomPayload {
47//!     data: String,
48//! }
49//!
50//! impl Codec for CustomCodec {
51//!     type Payload = CustomPayload;
52//!
53//!     fn encode(&self, payload: &Self::Payload) -> Result<Vec<u8>> {
54//!         // Your encoding implementation
55//!         # Ok(vec![])
56//!     }
57//!
58//!     fn decode(&self, encoded: &[u8]) -> Result<Self::Payload> {
59//!         // Your decoding implementation
60//!         # Ok(CustomPayload { data: "".to_string() })
61//!     }
62//! }
63//! ```
64//!
65//! # Security Requirements
66//!
67//! Codec implementations must:
68//! - Validate integrity/authenticity in `decode` (verify signatures/MACs)
69//! - Use secure key management practices
70//! - Avoid leaking sensitive validation details in error messages
71//! - Handle token expiration and validation consistently
72use crate::errors::Result;
73use serde::{Serialize, de::DeserializeOwned};
74
75pub mod errors;
76pub mod jwt;
77pub use errors::{CodecOperation, CodecsError, JwtError, JwtOperation};
78
79/// A pluggable payload encoder/decoder.
80///
81/// See the module-level documentation for detailed guidance and examples.
82pub trait Codec
83where
84    Self: Clone,
85    Self::Payload: Serialize + DeserializeOwned,
86{
87    /// Type of the payload being encoded/decoded.
88    type Payload;
89
90    /// Encode a payload into an opaque, implementation-defined byte vector.
91    ///
92    /// Implementations MUST:
93    /// - Serialize + sign / encrypt (where applicable)
94    /// - Return an error if encoding or cryptographic operations fail
95    fn encode(&self, payload: &Self::Payload) -> Result<Vec<u8>>;
96
97    /// Decode a previously encoded payload.
98    ///
99    /// Implementations MUST:
100    /// - Fully validate integrity/authenticity (e.g. signature/MAC) before returning
101    /// - Reject malformed or tampered data with an appropriate error
102    fn decode(&self, encoded_value: &[u8]) -> Result<Self::Payload>;
103}