use crate::service_account::ServiceAccount; use anyhow::Result; use jwt_simple::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct AddToWalletPayloadObject { id: String, #[serde(rename = "classId", skip_serializing_if = "Option::is_none")] class_id: Option, } #[derive(Serialize, Deserialize)] struct AddToWalletPayload { #[serde(skip_serializing_if = "Vec::is_empty", rename = "flightClasses")] flight_classes: Vec, #[serde(skip_serializing_if = "Vec::is_empty", rename = "flightObjects")] flight_objects: Vec, } #[derive(Serialize, Deserialize)] pub struct AddToWalletClaims { origins: Vec, #[serde(rename = "typ")] jwt_type: String, payload: AddToWalletPayload, } pub struct PassClassIdentifier { pub id: String, } pub struct PassIdentifier { pub id: String, pub class_id: String, } pub struct AddToWallet { pub service_account_email: String, pub flight_classes: Vec, pub flight_passes: Vec, } impl AddToWallet { pub fn to_claims(&self) -> JWTClaims { JWTClaims { issued_at: None, expires_at: None, invalid_before: None, audiences: Some(jwt_simple::claims::Audiences::AsString( "google".to_string(), )), issuer: Some(self.service_account_email.to_string()), jwt_id: None, subject: None, nonce: None, custom: AddToWalletClaims { jwt_type: "savetowallet".to_string(), origins: vec!["www.lukegb.com".to_string()], payload: AddToWalletPayload { flight_classes: self .flight_classes .iter() .map(|c| AddToWalletPayloadObject { id: c.id.to_string(), class_id: None, }) .collect(), flight_objects: self .flight_passes .iter() .map(|o| AddToWalletPayloadObject { id: o.id.to_string(), class_id: Some(o.class_id.to_string()), }) .collect(), }, }, } } pub fn to_url(&self, sa: &ServiceAccount) -> Result { let claims = self.to_claims(); let token = sa.key_pair.sign(claims)?; Ok(format!("https://pay.google.com/gp/v/save/{}", token)) } }