better_auth_api/plugins/jwt/
options.rs1use super::*;
2use std::{future::Future, pin::Pin, sync::Arc};
3
4#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
6#[serde(untagged)]
7pub enum JwtAudience {
8 Single(String),
10 Multiple(Vec<String>),
12}
13
14impl From<String> for JwtAudience {
15 fn from(value: String) -> Self {
16 Self::Single(value)
17 }
18}
19
20impl From<&str> for JwtAudience {
21 fn from(value: &str) -> Self {
22 Self::Single(value.into())
23 }
24}
25
26impl From<Vec<String>> for JwtAudience {
27 fn from(value: Vec<String>) -> Self {
28 Self::Multiple(value)
29 }
30}
31
32impl JwtAudience {
33 pub(super) fn recipients(&self) -> Vec<&str> {
34 match self {
35 Self::Single(value) => vec![value],
36 Self::Multiple(values) => values.iter().map(String::as_str).collect(),
37 }
38 }
39}
40
41#[derive(Clone, Debug)]
43pub enum JwtExpiration {
44 After(Duration),
46 At(serde_json::Number),
48}
49
50impl From<Duration> for JwtExpiration {
51 fn from(value: Duration) -> Self {
52 Self::After(value)
53 }
54}
55
56impl From<chrono::DateTime<Utc>> for JwtExpiration {
57 fn from(value: chrono::DateTime<Utc>) -> Self {
58 Self::At(value.timestamp().into())
59 }
60}
61
62impl From<i64> for JwtExpiration {
63 fn from(value: i64) -> Self {
64 Self::At(value.into())
65 }
66}
67
68impl JwtExpiration {
69 pub(super) fn claim(&self, issued: f64) -> Value {
70 match self {
71 Self::At(value) => Value::Number(value.clone()),
72 Self::After(duration) => {
73 let seconds =
74 duration.num_seconds() as f64 + f64::from(duration.subsec_nanos()) / 1e9;
75 let expires = issued + (seconds + 0.5).floor();
76 if expires.fract() == 0.0
78 && (i64::MIN as f64..-(i64::MIN as f64)).contains(&expires)
79 {
80 Value::from(expires as i64)
81 } else {
82 Value::from(expires)
83 }
84 }
85 }
86 }
87}
88
89pub type JwtCallbackFuture<T> = Pin<Box<dyn Future<Output = AuthResult<T>> + Send>>;
91pub type JwtDefinePayload =
93 Arc<dyn Fn(Value) -> JwtCallbackFuture<Map<String, Value>> + Send + Sync>;
94pub type JwtGetSubject = Arc<dyn Fn(Value) -> JwtCallbackFuture<String> + Send + Sync>;
96pub type JwtCustomSign =
98 Arc<dyn Fn(Map<String, Value>, JwtSigningOptions) -> JwtCallbackFuture<String> + Send + Sync>;
99
100#[derive(Clone, Debug, Default)]
102pub struct JwtSigningOptions {
103 pub key_id: Option<String>,
105 pub algorithm: Option<JwtAlgorithm>,
107 pub header: Map<String, Value>,
109}
110
111#[derive(Clone, Copy, Debug, serde::Deserialize)]
113#[serde(rename_all = "camelCase")]
114pub struct JwtKeyPairConfig {
115 #[serde(rename = "alg")]
117 pub algorithm: JwtAlgorithm,
118 #[serde(default = "default_modulus_length")]
120 pub modulus_length: u32,
121}
122
123impl JwtKeyPairConfig {
124 pub fn new(algorithm: JwtAlgorithm) -> Self {
126 Self {
127 algorithm,
128 modulus_length: 2048,
129 }
130 }
131}
132
133fn default_modulus_length() -> u32 {
134 2048
135}