1use serde::{Deserialize, Serialize};
2
3use crate::SubscriptionStatus;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct DomainEndUserClaims {
11 pub sub: String,
13
14 pub domain_id: String,
16
17 pub domain: String,
19
20 pub active_org_id: String,
22
23 pub org_role: String,
25
26 pub roles: Vec<String>,
28
29 pub subscription: SubscriptionClaims,
31
32 pub exp: i64,
34
35 pub iat: i64,
37}
38
39#[derive(Debug, Clone, Default, Serialize, Deserialize)]
43pub struct SubscriptionClaims {
44 pub status: SubscriptionStatus,
47
48 pub plan_code: Option<String>,
50
51 pub plan_name: Option<String>,
53
54 pub current_period_end: Option<i64>,
56
57 pub cancel_at_period_end: Option<bool>,
59
60 pub trial_ends_at: Option<i64>,
62
63 pub subscription_id: Option<String>,
65}
66
67impl SubscriptionClaims {
68 pub fn none() -> Self {
70 Self {
71 status: SubscriptionStatus::None,
72 ..Default::default()
73 }
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_subscription_claims_none() {
83 let sub = SubscriptionClaims::none();
84 assert_eq!(sub.status, SubscriptionStatus::None);
85 assert!(sub.plan_code.is_none());
86 assert!(sub.plan_name.is_none());
87 }
88
89 #[test]
90 fn test_subscription_claims_status_helpers() {
91 let active_sub = SubscriptionClaims {
92 status: SubscriptionStatus::Active,
93 ..Default::default()
94 };
95 assert!(active_sub.status.is_active());
96 assert!(active_sub.status.has_access());
97
98 let trialing_sub = SubscriptionClaims {
99 status: SubscriptionStatus::Trialing,
100 ..Default::default()
101 };
102 assert!(trialing_sub.status.is_active());
103 assert!(trialing_sub.status.has_access());
104
105 let canceled_sub = SubscriptionClaims {
106 status: SubscriptionStatus::Canceled,
107 ..Default::default()
108 };
109 assert!(!canceled_sub.status.is_active());
110 assert!(!canceled_sub.status.has_access());
111 }
112
113 #[test]
114 fn test_domain_end_user_claims_serde() {
115 let claims = DomainEndUserClaims {
116 sub: "user123".to_string(),
117 domain_id: "00000000-0000-0000-0000-000000000001".to_string(),
118 domain: "example.com".to_string(),
119 active_org_id: "00000000-0000-0000-0000-000000000002".to_string(),
120 org_role: "owner".to_string(),
121 roles: vec!["user".to_string()],
122 subscription: SubscriptionClaims {
123 status: SubscriptionStatus::Active,
124 plan_code: Some("pro".to_string()),
125 plan_name: Some("Pro Plan".to_string()),
126 current_period_end: Some(1735689600),
127 cancel_at_period_end: Some(false),
128 trial_ends_at: None,
129 subscription_id: Some("sub_123".to_string()),
130 },
131 exp: 1735689600,
132 iat: 1735603200,
133 };
134
135 let json = serde_json::to_string(&claims).unwrap();
136 let parsed: DomainEndUserClaims = serde_json::from_str(&json).unwrap();
137
138 assert_eq!(parsed.sub, "user123");
139 assert_eq!(parsed.domain, "example.com");
140 assert_eq!(parsed.active_org_id, "00000000-0000-0000-0000-000000000002");
141 assert_eq!(parsed.org_role, "owner");
142 assert_eq!(parsed.subscription.status, SubscriptionStatus::Active);
143 assert!(parsed.subscription.status.is_active());
144 }
145}