this repo has no description
1use super::{Claims, Header}; 2use anyhow::Result; 3use base64::Engine as _; 4use base64::engine::general_purpose::URL_SAFE_NO_PAD; 5use chrono::{Duration, Utc}; 6use k256::ecdsa::{Signature, SigningKey, signature::Signer}; 7use uuid; 8 9pub fn create_access_token(did: &str, key_bytes: &[u8]) -> Result<String> { 10 create_signed_token(did, "access", key_bytes, Duration::minutes(15)) 11} 12 13pub fn create_refresh_token(did: &str, key_bytes: &[u8]) -> Result<String> { 14 create_signed_token(did, "refresh", key_bytes, Duration::days(7)) 15} 16 17pub fn create_service_token(did: &str, aud: &str, lxm: &str, key_bytes: &[u8]) -> Result<String> { 18 let signing_key = SigningKey::from_slice(key_bytes)?; 19 20 let expiration = Utc::now() 21 .checked_add_signed(Duration::seconds(60)) 22 .expect("valid timestamp") 23 .timestamp(); 24 25 let claims = Claims { 26 iss: did.to_owned(), 27 sub: did.to_owned(), 28 aud: aud.to_owned(), 29 exp: expiration as usize, 30 iat: Utc::now().timestamp() as usize, 31 scope: None, 32 lxm: Some(lxm.to_string()), 33 jti: uuid::Uuid::new_v4().to_string(), 34 }; 35 36 sign_claims(claims, &signing_key) 37} 38 39fn create_signed_token( 40 did: &str, 41 scope: &str, 42 key_bytes: &[u8], 43 duration: Duration, 44) -> Result<String> { 45 let signing_key = SigningKey::from_slice(key_bytes)?; 46 47 let expiration = Utc::now() 48 .checked_add_signed(duration) 49 .expect("valid timestamp") 50 .timestamp(); 51 52 let claims = Claims { 53 iss: did.to_owned(), 54 sub: did.to_owned(), 55 aud: format!( 56 "did:web:{}", 57 std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string()) 58 ), 59 exp: expiration as usize, 60 iat: Utc::now().timestamp() as usize, 61 scope: Some(scope.to_string()), 62 lxm: None, 63 jti: uuid::Uuid::new_v4().to_string(), 64 }; 65 66 sign_claims(claims, &signing_key) 67} 68 69fn sign_claims(claims: Claims, key: &SigningKey) -> Result<String> { 70 let header = Header { 71 alg: "ES256K".to_string(), 72 typ: "JWT".to_string(), 73 }; 74 75 let header_json = serde_json::to_string(&header)?; 76 let claims_json = serde_json::to_string(&claims)?; 77 78 let header_b64 = URL_SAFE_NO_PAD.encode(header_json); 79 let claims_b64 = URL_SAFE_NO_PAD.encode(claims_json); 80 81 let message = format!("{}.{}", header_b64, claims_b64); 82 let signature: Signature = key.sign(message.as_bytes()); 83 let signature_b64 = URL_SAFE_NO_PAD.encode(signature.to_bytes()); 84 85 Ok(format!("{}.{}", message, signature_b64)) 86}