better_auth_core/
entity.rs1use chrono::{DateTime, Utc};
27use serde::Serialize;
28
29use crate::types::InvitationStatus;
30
31pub const PASSWORD_HASH_KEY: &str = "password_hash";
33
34pub trait AuthUser: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
39 fn id(&self) -> &str;
40 fn email(&self) -> Option<&str>;
41 fn name(&self) -> Option<&str>;
42 fn email_verified(&self) -> bool;
43 fn image(&self) -> Option<&str>;
44 fn created_at(&self) -> DateTime<Utc>;
45 fn updated_at(&self) -> DateTime<Utc>;
46 fn username(&self) -> Option<&str>;
47 fn display_username(&self) -> Option<&str>;
48 fn two_factor_enabled(&self) -> bool;
49 fn role(&self) -> Option<&str>;
50 fn banned(&self) -> bool;
51 fn ban_reason(&self) -> Option<&str>;
52 fn ban_expires(&self) -> Option<DateTime<Utc>>;
53 fn metadata(&self) -> &serde_json::Value;
54
55 fn password_hash(&self) -> Option<&str> {
57 self.metadata()
58 .get(PASSWORD_HASH_KEY)
59 .and_then(|v| v.as_str())
60 }
61}
62
63pub trait AuthSession: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
65 fn id(&self) -> &str;
66 fn expires_at(&self) -> DateTime<Utc>;
67 fn token(&self) -> &str;
68 fn created_at(&self) -> DateTime<Utc>;
69 fn updated_at(&self) -> DateTime<Utc>;
70 fn ip_address(&self) -> Option<&str>;
71 fn user_agent(&self) -> Option<&str>;
72 fn user_id(&self) -> &str;
73 fn impersonated_by(&self) -> Option<&str>;
74 fn active_organization_id(&self) -> Option<&str>;
75 fn active(&self) -> bool;
76}
77
78pub trait AuthAccount: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
80 fn id(&self) -> &str;
81 fn account_id(&self) -> &str;
82 fn provider_id(&self) -> &str;
83 fn user_id(&self) -> &str;
84 fn access_token(&self) -> Option<&str>;
85 fn refresh_token(&self) -> Option<&str>;
86 fn id_token(&self) -> Option<&str>;
87 fn access_token_expires_at(&self) -> Option<DateTime<Utc>>;
88 fn refresh_token_expires_at(&self) -> Option<DateTime<Utc>>;
89 fn scope(&self) -> Option<&str>;
90 fn password(&self) -> Option<&str>;
91 fn created_at(&self) -> DateTime<Utc>;
92 fn updated_at(&self) -> DateTime<Utc>;
93}
94
95pub trait AuthOrganization: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
97 fn id(&self) -> &str;
98 fn name(&self) -> &str;
99 fn slug(&self) -> &str;
100 fn logo(&self) -> Option<&str>;
101 fn metadata(&self) -> Option<&serde_json::Value>;
102 fn created_at(&self) -> DateTime<Utc>;
103 fn updated_at(&self) -> DateTime<Utc>;
104}
105
106pub trait AuthMember: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
108 fn id(&self) -> &str;
109 fn organization_id(&self) -> &str;
110 fn user_id(&self) -> &str;
111 fn role(&self) -> &str;
112 fn created_at(&self) -> DateTime<Utc>;
113}
114
115pub trait AuthInvitation: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
117 fn id(&self) -> &str;
118 fn organization_id(&self) -> &str;
119 fn email(&self) -> &str;
120 fn role(&self) -> &str;
121 fn status(&self) -> &InvitationStatus;
122 fn inviter_id(&self) -> &str;
123 fn expires_at(&self) -> DateTime<Utc>;
124 fn created_at(&self) -> DateTime<Utc>;
125
126 fn is_pending(&self) -> bool {
128 *self.status() == InvitationStatus::Pending
129 }
130
131 fn is_expired(&self) -> bool {
133 self.expires_at() < Utc::now()
134 }
135}
136
137pub trait AuthVerification: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
139 fn id(&self) -> &str;
140 fn identifier(&self) -> &str;
141 fn value(&self) -> &str;
142 fn expires_at(&self) -> DateTime<Utc>;
143 fn created_at(&self) -> DateTime<Utc>;
144 fn updated_at(&self) -> DateTime<Utc>;
145}
146
147pub trait AuthTwoFactor: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
149 fn id(&self) -> &str;
150 fn secret(&self) -> &str;
151 fn backup_codes(&self) -> Option<&str>;
152 fn user_id(&self) -> &str;
153 fn created_at(&self) -> DateTime<Utc>;
154 fn updated_at(&self) -> DateTime<Utc>;
155}
156
157pub trait AuthApiKey: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
159 fn id(&self) -> &str;
160 fn name(&self) -> Option<&str>;
161 fn start(&self) -> Option<&str>;
162 fn prefix(&self) -> Option<&str>;
163 fn key_hash(&self) -> &str;
164 fn user_id(&self) -> &str;
165 fn refill_interval(&self) -> Option<i64>;
166 fn refill_amount(&self) -> Option<i64>;
167 fn last_refill_at(&self) -> Option<&str>;
168 fn enabled(&self) -> bool;
169 fn rate_limit_enabled(&self) -> bool;
170 fn rate_limit_time_window(&self) -> Option<i64>;
171 fn rate_limit_max(&self) -> Option<i64>;
172 fn request_count(&self) -> Option<i64>;
173 fn remaining(&self) -> Option<i64>;
174 fn last_request(&self) -> Option<&str>;
175 fn expires_at(&self) -> Option<&str>;
176 fn created_at(&self) -> &str;
177 fn updated_at(&self) -> &str;
178 fn permissions(&self) -> Option<&str>;
179 fn metadata(&self) -> Option<&str>;
180}
181
182pub trait AuthPasskey: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
184 fn id(&self) -> &str;
185 fn name(&self) -> &str;
186 fn public_key(&self) -> &str;
187 fn user_id(&self) -> &str;
188 fn credential_id(&self) -> &str;
189 fn counter(&self) -> u64;
190 fn device_type(&self) -> &str;
191 fn backed_up(&self) -> bool;
192 fn transports(&self) -> Option<&str>;
193 fn created_at(&self) -> DateTime<Utc>;
194}
195
196pub trait AuthUserMeta {
228 fn table() -> &'static str {
229 "users"
230 }
231 fn col_id() -> &'static str {
232 "id"
233 }
234 fn col_email() -> &'static str {
235 "email"
236 }
237 fn col_name() -> &'static str {
238 "name"
239 }
240 fn col_image() -> &'static str {
241 "image"
242 }
243 fn col_email_verified() -> &'static str {
244 "email_verified"
245 }
246 fn col_created_at() -> &'static str {
247 "created_at"
248 }
249 fn col_updated_at() -> &'static str {
250 "updated_at"
251 }
252 fn col_metadata() -> &'static str {
253 "metadata"
254 }
255 fn col_username() -> &'static str {
256 "username"
257 }
258 fn col_display_username() -> &'static str {
259 "display_username"
260 }
261 fn col_two_factor_enabled() -> &'static str {
262 "two_factor_enabled"
263 }
264 fn col_role() -> &'static str {
265 "role"
266 }
267 fn col_banned() -> &'static str {
268 "banned"
269 }
270 fn col_ban_reason() -> &'static str {
271 "ban_reason"
272 }
273 fn col_ban_expires() -> &'static str {
274 "ban_expires"
275 }
276}
277
278pub trait AuthSessionMeta {
280 fn table() -> &'static str {
281 "sessions"
282 }
283 fn col_id() -> &'static str {
284 "id"
285 }
286 fn col_expires_at() -> &'static str {
287 "expires_at"
288 }
289 fn col_token() -> &'static str {
290 "token"
291 }
292 fn col_created_at() -> &'static str {
293 "created_at"
294 }
295 fn col_updated_at() -> &'static str {
296 "updated_at"
297 }
298 fn col_ip_address() -> &'static str {
299 "ip_address"
300 }
301 fn col_user_agent() -> &'static str {
302 "user_agent"
303 }
304 fn col_user_id() -> &'static str {
305 "user_id"
306 }
307 fn col_impersonated_by() -> &'static str {
308 "impersonated_by"
309 }
310 fn col_active_organization_id() -> &'static str {
311 "active_organization_id"
312 }
313 fn col_active() -> &'static str {
314 "active"
315 }
316}
317
318pub trait AuthAccountMeta {
320 fn table() -> &'static str {
321 "accounts"
322 }
323 fn col_id() -> &'static str {
324 "id"
325 }
326 fn col_account_id() -> &'static str {
327 "account_id"
328 }
329 fn col_provider_id() -> &'static str {
330 "provider_id"
331 }
332 fn col_user_id() -> &'static str {
333 "user_id"
334 }
335 fn col_access_token() -> &'static str {
336 "access_token"
337 }
338 fn col_refresh_token() -> &'static str {
339 "refresh_token"
340 }
341 fn col_id_token() -> &'static str {
342 "id_token"
343 }
344 fn col_access_token_expires_at() -> &'static str {
345 "access_token_expires_at"
346 }
347 fn col_refresh_token_expires_at() -> &'static str {
348 "refresh_token_expires_at"
349 }
350 fn col_scope() -> &'static str {
351 "scope"
352 }
353 fn col_password() -> &'static str {
354 "password"
355 }
356 fn col_created_at() -> &'static str {
357 "created_at"
358 }
359 fn col_updated_at() -> &'static str {
360 "updated_at"
361 }
362}
363
364pub trait AuthOrganizationMeta {
366 fn table() -> &'static str {
367 "organization"
368 }
369 fn col_id() -> &'static str {
370 "id"
371 }
372 fn col_name() -> &'static str {
373 "name"
374 }
375 fn col_slug() -> &'static str {
376 "slug"
377 }
378 fn col_logo() -> &'static str {
379 "logo"
380 }
381 fn col_metadata() -> &'static str {
382 "metadata"
383 }
384 fn col_created_at() -> &'static str {
385 "created_at"
386 }
387 fn col_updated_at() -> &'static str {
388 "updated_at"
389 }
390}
391
392pub trait AuthMemberMeta {
394 fn table() -> &'static str {
395 "member"
396 }
397 fn col_id() -> &'static str {
398 "id"
399 }
400 fn col_organization_id() -> &'static str {
401 "organization_id"
402 }
403 fn col_user_id() -> &'static str {
404 "user_id"
405 }
406 fn col_role() -> &'static str {
407 "role"
408 }
409 fn col_created_at() -> &'static str {
410 "created_at"
411 }
412}
413
414pub trait AuthInvitationMeta {
416 fn table() -> &'static str {
417 "invitation"
418 }
419 fn col_id() -> &'static str {
420 "id"
421 }
422 fn col_organization_id() -> &'static str {
423 "organization_id"
424 }
425 fn col_email() -> &'static str {
426 "email"
427 }
428 fn col_role() -> &'static str {
429 "role"
430 }
431 fn col_status() -> &'static str {
432 "status"
433 }
434 fn col_inviter_id() -> &'static str {
435 "inviter_id"
436 }
437 fn col_expires_at() -> &'static str {
438 "expires_at"
439 }
440 fn col_created_at() -> &'static str {
441 "created_at"
442 }
443}
444
445pub trait AuthVerificationMeta {
447 fn table() -> &'static str {
448 "verifications"
449 }
450 fn col_id() -> &'static str {
451 "id"
452 }
453 fn col_identifier() -> &'static str {
454 "identifier"
455 }
456 fn col_value() -> &'static str {
457 "value"
458 }
459 fn col_expires_at() -> &'static str {
460 "expires_at"
461 }
462 fn col_created_at() -> &'static str {
463 "created_at"
464 }
465 fn col_updated_at() -> &'static str {
466 "updated_at"
467 }
468}
469
470pub trait AuthTwoFactorMeta {
472 fn table() -> &'static str {
473 "two_factor"
474 }
475 fn col_id() -> &'static str {
476 "id"
477 }
478 fn col_secret() -> &'static str {
479 "secret"
480 }
481 fn col_backup_codes() -> &'static str {
482 "backup_codes"
483 }
484 fn col_user_id() -> &'static str {
485 "user_id"
486 }
487 fn col_created_at() -> &'static str {
488 "created_at"
489 }
490 fn col_updated_at() -> &'static str {
491 "updated_at"
492 }
493}
494
495pub trait AuthApiKeyMeta {
497 fn table() -> &'static str {
498 "api_keys"
499 }
500 fn col_id() -> &'static str {
501 "id"
502 }
503 fn col_name() -> &'static str {
504 "name"
505 }
506 fn col_start() -> &'static str {
507 "start"
508 }
509 fn col_prefix() -> &'static str {
510 "prefix"
511 }
512 fn col_key_hash() -> &'static str {
518 "key"
519 }
520 fn col_user_id() -> &'static str {
521 "user_id"
522 }
523 fn col_refill_interval() -> &'static str {
524 "refill_interval"
525 }
526 fn col_refill_amount() -> &'static str {
527 "refill_amount"
528 }
529 fn col_last_refill_at() -> &'static str {
530 "last_refill_at"
531 }
532 fn col_enabled() -> &'static str {
533 "enabled"
534 }
535 fn col_rate_limit_enabled() -> &'static str {
536 "rate_limit_enabled"
537 }
538 fn col_rate_limit_time_window() -> &'static str {
539 "rate_limit_time_window"
540 }
541 fn col_rate_limit_max() -> &'static str {
542 "rate_limit_max"
543 }
544 fn col_request_count() -> &'static str {
545 "request_count"
546 }
547 fn col_remaining() -> &'static str {
548 "remaining"
549 }
550 fn col_last_request() -> &'static str {
551 "last_request"
552 }
553 fn col_expires_at() -> &'static str {
554 "expires_at"
555 }
556 fn col_created_at() -> &'static str {
557 "created_at"
558 }
559 fn col_updated_at() -> &'static str {
560 "updated_at"
561 }
562 fn col_permissions() -> &'static str {
563 "permissions"
564 }
565 fn col_metadata() -> &'static str {
566 "metadata"
567 }
568}
569
570pub trait AuthPasskeyMeta {
572 fn table() -> &'static str {
573 "passkeys"
574 }
575 fn col_id() -> &'static str {
576 "id"
577 }
578 fn col_name() -> &'static str {
579 "name"
580 }
581 fn col_public_key() -> &'static str {
582 "public_key"
583 }
584 fn col_user_id() -> &'static str {
585 "user_id"
586 }
587 fn col_credential_id() -> &'static str {
588 "credential_id"
589 }
590 fn col_counter() -> &'static str {
591 "counter"
592 }
593 fn col_device_type() -> &'static str {
594 "device_type"
595 }
596 fn col_backed_up() -> &'static str {
597 "backed_up"
598 }
599 fn col_transports() -> &'static str {
600 "transports"
601 }
602 fn col_created_at() -> &'static str {
603 "created_at"
604 }
605}
606
607#[derive(Debug, Clone, Serialize, Deserialize)]
612pub struct MemberUserView {
613 pub id: String,
614 pub email: Option<String>,
615 pub name: Option<String>,
616 pub image: Option<String>,
617}
618
619impl MemberUserView {
620 pub fn from_user(user: &impl AuthUser) -> Self {
622 Self {
623 id: user.id().to_string(),
624 email: user.email().map(|s| s.to_string()),
625 name: user.name().map(|s| s.to_string()),
626 image: user.image().map(|s| s.to_string()),
627 }
628 }
629}
630
631use serde::Deserialize;