fts_server/utils/
jwt.rs

1use crate::AppState;
2use axum::extract::FromRef;
3use fts_core::ports::MarketRepository;
4use jwt_simple::{
5    algorithms::{HS256Key, MACLike},
6    claims::JWTClaims,
7};
8use serde::{Deserialize, Serialize};
9
10/// JWT verification service.
11///
12/// Handles verification of JWT tokens and extraction of claims.
13/// Uses HS256 for signature verification.
14#[derive(Clone)]
15pub struct JWTVerifier(HS256Key);
16
17impl JWTVerifier {
18    /// Creates a new JWTVerifier from a secret string.
19    pub fn from(secret: &str) -> Self {
20        Self(HS256Key::from_bytes(secret.as_bytes()))
21    }
22
23    /// Verifies a token and extracts its claims if valid.
24    pub fn claims(&self, token: &str) -> Option<JWTClaims<CustomJWTClaims>> {
25        // Process the claims. According to simple-jwt docs, this will automatically
26        // check and verify all the things a responsible implementation should.
27        self.0.verify_token::<CustomJWTClaims>(token, None).ok()
28    }
29}
30
31impl<T: MarketRepository> FromRef<AppState<T>> for JWTVerifier {
32    fn from_ref(input: &AppState<T>) -> Self {
33        input.jwt.clone()
34    }
35}
36
37/// Custom claims structure for JWT tokens.
38///
39/// Contains application-specific claims beyond standard JWT claims.
40#[derive(Serialize, Deserialize)]
41pub struct CustomJWTClaims {
42    /// Indicates whether the token holder has admin privileges.
43    #[serde(default)]
44    pub admin: bool,
45}