tuwunel_service/oauth/server/
token.rs1use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD as b64};
2use jwt::{Algorithm, EncodingKey, Header};
3use serde::{Deserialize, Serialize};
4use tuwunel_core::{Result, err, implement, jwt, utils};
5use utils::hash::sha256;
6
7#[derive(Debug, Deserialize, Serialize)]
8pub struct IdTokenClaims {
9 pub iss: String,
10 pub sub: String,
11 pub aud: String,
12 pub exp: u64,
13 pub iat: u64,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub nonce: Option<String>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub at_hash: Option<String>,
18}
19
20#[implement(super::Server)]
21pub fn sign_id_token(&self, claims: &IdTokenClaims) -> Result<String> {
22 let mut header = Header::new(Algorithm::ES256);
23 header.kid = Some(self.key.key_id.clone());
24
25 let key = EncodingKey::from_ec_der(&self.key.key_der);
26 jwt::encode(&header, claims, &key).map_err(|e| err!(error!("Failed to sign ID token: {e}")))
27}
28
29#[implement(super::Server)]
30#[must_use]
31#[inline]
32pub fn at_hash(access_token: &str) -> String {
33 let hash = sha256::hash(access_token.as_bytes());
34
35 b64.encode(&hash[..16])
36}