Skip to main content

better_auth_core/
entity.rs

1//! Entity traits for the Better Auth framework.
2//!
3//! These traits define the interface that entity types must implement.
4//! The framework accesses entity fields through these trait methods,
5//! allowing users to define their own entity structs with custom field names
6//! and extra fields.
7//!
8//! Use `#[derive(AuthUser)]` etc. from `better-auth-derive` to auto-implement
9//! these traits, or implement them manually.
10
11use chrono::{DateTime, Utc};
12use serde::Serialize;
13
14use crate::types::InvitationStatus;
15
16/// Trait representing a user entity.
17///
18/// The framework reads user fields through these getters. Custom types
19/// must provide all framework fields and may have additional fields.
20pub trait AuthUser: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
21    fn id(&self) -> &str;
22    fn email(&self) -> Option<&str>;
23    fn name(&self) -> Option<&str>;
24    fn email_verified(&self) -> bool;
25    fn image(&self) -> Option<&str>;
26    fn created_at(&self) -> DateTime<Utc>;
27    fn updated_at(&self) -> DateTime<Utc>;
28    fn username(&self) -> Option<&str>;
29    fn display_username(&self) -> Option<&str>;
30    fn two_factor_enabled(&self) -> bool;
31    fn role(&self) -> Option<&str>;
32    fn banned(&self) -> bool;
33    fn ban_reason(&self) -> Option<&str>;
34    fn ban_expires(&self) -> Option<DateTime<Utc>>;
35    fn metadata(&self) -> &serde_json::Value;
36}
37
38/// Trait representing a session entity.
39pub trait AuthSession: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
40    fn id(&self) -> &str;
41    fn expires_at(&self) -> DateTime<Utc>;
42    fn token(&self) -> &str;
43    fn created_at(&self) -> DateTime<Utc>;
44    fn updated_at(&self) -> DateTime<Utc>;
45    fn ip_address(&self) -> Option<&str>;
46    fn user_agent(&self) -> Option<&str>;
47    fn user_id(&self) -> &str;
48    fn impersonated_by(&self) -> Option<&str>;
49    fn active_organization_id(&self) -> Option<&str>;
50    fn active(&self) -> bool;
51}
52
53/// Trait representing an account entity (OAuth provider linking).
54pub trait AuthAccount: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
55    fn id(&self) -> &str;
56    fn account_id(&self) -> &str;
57    fn provider_id(&self) -> &str;
58    fn user_id(&self) -> &str;
59    fn access_token(&self) -> Option<&str>;
60    fn refresh_token(&self) -> Option<&str>;
61    fn id_token(&self) -> Option<&str>;
62    fn access_token_expires_at(&self) -> Option<DateTime<Utc>>;
63    fn refresh_token_expires_at(&self) -> Option<DateTime<Utc>>;
64    fn scope(&self) -> Option<&str>;
65    fn password(&self) -> Option<&str>;
66    fn created_at(&self) -> DateTime<Utc>;
67    fn updated_at(&self) -> DateTime<Utc>;
68}
69
70/// Trait representing an organization entity.
71pub trait AuthOrganization: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
72    fn id(&self) -> &str;
73    fn name(&self) -> &str;
74    fn slug(&self) -> &str;
75    fn logo(&self) -> Option<&str>;
76    fn metadata(&self) -> Option<&serde_json::Value>;
77    fn created_at(&self) -> DateTime<Utc>;
78    fn updated_at(&self) -> DateTime<Utc>;
79}
80
81/// Trait representing an organization member entity.
82pub trait AuthMember: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
83    fn id(&self) -> &str;
84    fn organization_id(&self) -> &str;
85    fn user_id(&self) -> &str;
86    fn role(&self) -> &str;
87    fn created_at(&self) -> DateTime<Utc>;
88}
89
90/// Trait representing an invitation entity.
91pub trait AuthInvitation: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
92    fn id(&self) -> &str;
93    fn organization_id(&self) -> &str;
94    fn email(&self) -> &str;
95    fn role(&self) -> &str;
96    fn status(&self) -> &InvitationStatus;
97    fn inviter_id(&self) -> &str;
98    fn expires_at(&self) -> DateTime<Utc>;
99    fn created_at(&self) -> DateTime<Utc>;
100
101    /// Check if the invitation is still pending.
102    fn is_pending(&self) -> bool {
103        *self.status() == InvitationStatus::Pending
104    }
105
106    /// Check if the invitation has expired.
107    fn is_expired(&self) -> bool {
108        self.expires_at() < Utc::now()
109    }
110}
111
112/// Trait representing a verification token entity.
113pub trait AuthVerification: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
114    fn id(&self) -> &str;
115    fn identifier(&self) -> &str;
116    fn value(&self) -> &str;
117    fn expires_at(&self) -> DateTime<Utc>;
118    fn created_at(&self) -> DateTime<Utc>;
119    fn updated_at(&self) -> DateTime<Utc>;
120}
121
122/// Trait representing a two-factor authentication entity.
123pub trait AuthTwoFactor: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
124    fn id(&self) -> &str;
125    fn secret(&self) -> &str;
126    fn backup_codes(&self) -> Option<&str>;
127    fn user_id(&self) -> &str;
128}
129
130/// Trait representing an API key entity.
131pub trait AuthApiKey: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
132    fn id(&self) -> &str;
133    fn name(&self) -> Option<&str>;
134    fn start(&self) -> Option<&str>;
135    fn prefix(&self) -> Option<&str>;
136    fn key_hash(&self) -> &str;
137    fn user_id(&self) -> &str;
138    fn refill_interval(&self) -> Option<i64>;
139    fn refill_amount(&self) -> Option<i64>;
140    fn last_refill_at(&self) -> Option<&str>;
141    fn enabled(&self) -> bool;
142    fn rate_limit_enabled(&self) -> bool;
143    fn rate_limit_time_window(&self) -> Option<i64>;
144    fn rate_limit_max(&self) -> Option<i64>;
145    fn request_count(&self) -> Option<i64>;
146    fn remaining(&self) -> Option<i64>;
147    fn last_request(&self) -> Option<&str>;
148    fn expires_at(&self) -> Option<&str>;
149    fn created_at(&self) -> &str;
150    fn updated_at(&self) -> &str;
151    fn permissions(&self) -> Option<&str>;
152    fn metadata(&self) -> Option<&str>;
153}
154
155/// Trait representing a passkey entity.
156pub trait AuthPasskey: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
157    fn id(&self) -> &str;
158    fn name(&self) -> &str;
159    fn public_key(&self) -> &str;
160    fn user_id(&self) -> &str;
161    fn credential_id(&self) -> &str;
162    fn counter(&self) -> u64;
163    fn device_type(&self) -> &str;
164    fn backed_up(&self) -> bool;
165    fn transports(&self) -> Option<&str>;
166    fn created_at(&self) -> DateTime<Utc>;
167}
168
169/// Minimal user info for member-related API responses.
170///
171/// This is a concrete framework type (not generic) used to project
172/// user fields into member responses.
173#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct MemberUserView {
175    pub id: String,
176    pub email: Option<String>,
177    pub name: Option<String>,
178    pub image: Option<String>,
179}
180
181impl MemberUserView {
182    /// Construct from any type implementing [`AuthUser`].
183    pub fn from_user(user: &impl AuthUser) -> Self {
184        Self {
185            id: user.id().to_string(),
186            email: user.email().map(|s| s.to_string()),
187            name: user.name().map(|s| s.to_string()),
188            image: user.image().map(|s| s.to_string()),
189        }
190    }
191}
192
193use serde::Deserialize;