use chrono::{DateTime, Utc};
use serde::Serialize;
use crate::types::InvitationStatus;
pub const PASSWORD_HASH_KEY: &str = "password_hash";
pub trait AuthUser: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn email(&self) -> Option<&str>;
fn name(&self) -> Option<&str>;
fn email_verified(&self) -> bool;
fn image(&self) -> Option<&str>;
fn created_at(&self) -> DateTime<Utc>;
fn updated_at(&self) -> DateTime<Utc>;
fn username(&self) -> Option<&str>;
fn display_username(&self) -> Option<&str>;
fn two_factor_enabled(&self) -> bool;
fn role(&self) -> Option<&str>;
fn banned(&self) -> bool;
fn ban_reason(&self) -> Option<&str>;
fn ban_expires(&self) -> Option<DateTime<Utc>>;
fn metadata(&self) -> &serde_json::Value;
fn password_hash(&self) -> Option<&str> {
self.metadata()
.get(PASSWORD_HASH_KEY)
.and_then(|v| v.as_str())
}
}
pub trait AuthSession: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn expires_at(&self) -> DateTime<Utc>;
fn token(&self) -> &str;
fn created_at(&self) -> DateTime<Utc>;
fn updated_at(&self) -> DateTime<Utc>;
fn ip_address(&self) -> Option<&str>;
fn user_agent(&self) -> Option<&str>;
fn user_id(&self) -> &str;
fn impersonated_by(&self) -> Option<&str>;
fn active_organization_id(&self) -> Option<&str>;
fn active(&self) -> bool;
}
pub trait AuthAccount: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn account_id(&self) -> &str;
fn provider_id(&self) -> &str;
fn user_id(&self) -> &str;
fn access_token(&self) -> Option<&str>;
fn refresh_token(&self) -> Option<&str>;
fn id_token(&self) -> Option<&str>;
fn access_token_expires_at(&self) -> Option<DateTime<Utc>>;
fn refresh_token_expires_at(&self) -> Option<DateTime<Utc>>;
fn scope(&self) -> Option<&str>;
fn password(&self) -> Option<&str>;
fn created_at(&self) -> DateTime<Utc>;
fn updated_at(&self) -> DateTime<Utc>;
}
pub trait AuthOrganization: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn name(&self) -> &str;
fn slug(&self) -> &str;
fn logo(&self) -> Option<&str>;
fn metadata(&self) -> Option<&serde_json::Value>;
fn created_at(&self) -> DateTime<Utc>;
fn updated_at(&self) -> DateTime<Utc>;
}
pub trait AuthMember: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn organization_id(&self) -> &str;
fn user_id(&self) -> &str;
fn role(&self) -> &str;
fn created_at(&self) -> DateTime<Utc>;
}
pub trait AuthInvitation: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn organization_id(&self) -> &str;
fn email(&self) -> &str;
fn role(&self) -> &str;
fn status(&self) -> &InvitationStatus;
fn inviter_id(&self) -> &str;
fn expires_at(&self) -> DateTime<Utc>;
fn created_at(&self) -> DateTime<Utc>;
fn is_pending(&self) -> bool {
*self.status() == InvitationStatus::Pending
}
fn is_expired(&self) -> bool {
self.expires_at() < Utc::now()
}
}
pub trait AuthVerification: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn identifier(&self) -> &str;
fn value(&self) -> &str;
fn expires_at(&self) -> DateTime<Utc>;
fn created_at(&self) -> DateTime<Utc>;
fn updated_at(&self) -> DateTime<Utc>;
}
pub trait AuthTwoFactor: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn secret(&self) -> &str;
fn backup_codes(&self) -> Option<&str>;
fn user_id(&self) -> &str;
fn created_at(&self) -> DateTime<Utc>;
fn updated_at(&self) -> DateTime<Utc>;
}
pub trait AuthApiKey: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn name(&self) -> Option<&str>;
fn start(&self) -> Option<&str>;
fn prefix(&self) -> Option<&str>;
fn key_hash(&self) -> &str;
fn user_id(&self) -> &str;
fn refill_interval(&self) -> Option<i64>;
fn refill_amount(&self) -> Option<i64>;
fn last_refill_at(&self) -> Option<&str>;
fn enabled(&self) -> bool;
fn rate_limit_enabled(&self) -> bool;
fn rate_limit_time_window(&self) -> Option<i64>;
fn rate_limit_max(&self) -> Option<i64>;
fn request_count(&self) -> Option<i64>;
fn remaining(&self) -> Option<i64>;
fn last_request(&self) -> Option<&str>;
fn expires_at(&self) -> Option<&str>;
fn created_at(&self) -> &str;
fn updated_at(&self) -> &str;
fn permissions(&self) -> Option<&str>;
fn metadata(&self) -> Option<&str>;
}
pub trait AuthPasskey: Clone + Send + Sync + Serialize + std::fmt::Debug + 'static {
fn id(&self) -> &str;
fn name(&self) -> &str;
fn public_key(&self) -> &str;
fn user_id(&self) -> &str;
fn credential_id(&self) -> &str;
fn counter(&self) -> u64;
fn device_type(&self) -> &str;
fn backed_up(&self) -> bool;
fn transports(&self) -> Option<&str>;
fn created_at(&self) -> DateTime<Utc>;
}
pub trait AuthUserMeta {
fn table() -> &'static str {
"users"
}
fn col_id() -> &'static str {
"id"
}
fn col_email() -> &'static str {
"email"
}
fn col_name() -> &'static str {
"name"
}
fn col_image() -> &'static str {
"image"
}
fn col_email_verified() -> &'static str {
"email_verified"
}
fn col_created_at() -> &'static str {
"created_at"
}
fn col_updated_at() -> &'static str {
"updated_at"
}
fn col_metadata() -> &'static str {
"metadata"
}
fn col_username() -> &'static str {
"username"
}
fn col_display_username() -> &'static str {
"display_username"
}
fn col_two_factor_enabled() -> &'static str {
"two_factor_enabled"
}
fn col_role() -> &'static str {
"role"
}
fn col_banned() -> &'static str {
"banned"
}
fn col_ban_reason() -> &'static str {
"ban_reason"
}
fn col_ban_expires() -> &'static str {
"ban_expires"
}
}
pub trait AuthSessionMeta {
fn table() -> &'static str {
"sessions"
}
fn col_id() -> &'static str {
"id"
}
fn col_expires_at() -> &'static str {
"expires_at"
}
fn col_token() -> &'static str {
"token"
}
fn col_created_at() -> &'static str {
"created_at"
}
fn col_updated_at() -> &'static str {
"updated_at"
}
fn col_ip_address() -> &'static str {
"ip_address"
}
fn col_user_agent() -> &'static str {
"user_agent"
}
fn col_user_id() -> &'static str {
"user_id"
}
fn col_impersonated_by() -> &'static str {
"impersonated_by"
}
fn col_active_organization_id() -> &'static str {
"active_organization_id"
}
fn col_active() -> &'static str {
"active"
}
}
pub trait AuthAccountMeta {
fn table() -> &'static str {
"accounts"
}
fn col_id() -> &'static str {
"id"
}
fn col_account_id() -> &'static str {
"account_id"
}
fn col_provider_id() -> &'static str {
"provider_id"
}
fn col_user_id() -> &'static str {
"user_id"
}
fn col_access_token() -> &'static str {
"access_token"
}
fn col_refresh_token() -> &'static str {
"refresh_token"
}
fn col_id_token() -> &'static str {
"id_token"
}
fn col_access_token_expires_at() -> &'static str {
"access_token_expires_at"
}
fn col_refresh_token_expires_at() -> &'static str {
"refresh_token_expires_at"
}
fn col_scope() -> &'static str {
"scope"
}
fn col_password() -> &'static str {
"password"
}
fn col_created_at() -> &'static str {
"created_at"
}
fn col_updated_at() -> &'static str {
"updated_at"
}
}
pub trait AuthOrganizationMeta {
fn table() -> &'static str {
"organization"
}
fn col_id() -> &'static str {
"id"
}
fn col_name() -> &'static str {
"name"
}
fn col_slug() -> &'static str {
"slug"
}
fn col_logo() -> &'static str {
"logo"
}
fn col_metadata() -> &'static str {
"metadata"
}
fn col_created_at() -> &'static str {
"created_at"
}
fn col_updated_at() -> &'static str {
"updated_at"
}
}
pub trait AuthMemberMeta {
fn table() -> &'static str {
"member"
}
fn col_id() -> &'static str {
"id"
}
fn col_organization_id() -> &'static str {
"organization_id"
}
fn col_user_id() -> &'static str {
"user_id"
}
fn col_role() -> &'static str {
"role"
}
fn col_created_at() -> &'static str {
"created_at"
}
}
pub trait AuthInvitationMeta {
fn table() -> &'static str {
"invitation"
}
fn col_id() -> &'static str {
"id"
}
fn col_organization_id() -> &'static str {
"organization_id"
}
fn col_email() -> &'static str {
"email"
}
fn col_role() -> &'static str {
"role"
}
fn col_status() -> &'static str {
"status"
}
fn col_inviter_id() -> &'static str {
"inviter_id"
}
fn col_expires_at() -> &'static str {
"expires_at"
}
fn col_created_at() -> &'static str {
"created_at"
}
}
pub trait AuthVerificationMeta {
fn table() -> &'static str {
"verifications"
}
fn col_id() -> &'static str {
"id"
}
fn col_identifier() -> &'static str {
"identifier"
}
fn col_value() -> &'static str {
"value"
}
fn col_expires_at() -> &'static str {
"expires_at"
}
fn col_created_at() -> &'static str {
"created_at"
}
fn col_updated_at() -> &'static str {
"updated_at"
}
}
pub trait AuthTwoFactorMeta {
fn table() -> &'static str {
"two_factor"
}
fn col_id() -> &'static str {
"id"
}
fn col_secret() -> &'static str {
"secret"
}
fn col_backup_codes() -> &'static str {
"backup_codes"
}
fn col_user_id() -> &'static str {
"user_id"
}
fn col_created_at() -> &'static str {
"created_at"
}
fn col_updated_at() -> &'static str {
"updated_at"
}
}
pub trait AuthApiKeyMeta {
fn table() -> &'static str {
"api_keys"
}
fn col_id() -> &'static str {
"id"
}
fn col_name() -> &'static str {
"name"
}
fn col_start() -> &'static str {
"start"
}
fn col_prefix() -> &'static str {
"prefix"
}
fn col_key_hash() -> &'static str {
"key"
}
fn col_user_id() -> &'static str {
"user_id"
}
fn col_refill_interval() -> &'static str {
"refill_interval"
}
fn col_refill_amount() -> &'static str {
"refill_amount"
}
fn col_last_refill_at() -> &'static str {
"last_refill_at"
}
fn col_enabled() -> &'static str {
"enabled"
}
fn col_rate_limit_enabled() -> &'static str {
"rate_limit_enabled"
}
fn col_rate_limit_time_window() -> &'static str {
"rate_limit_time_window"
}
fn col_rate_limit_max() -> &'static str {
"rate_limit_max"
}
fn col_request_count() -> &'static str {
"request_count"
}
fn col_remaining() -> &'static str {
"remaining"
}
fn col_last_request() -> &'static str {
"last_request"
}
fn col_expires_at() -> &'static str {
"expires_at"
}
fn col_created_at() -> &'static str {
"created_at"
}
fn col_updated_at() -> &'static str {
"updated_at"
}
fn col_permissions() -> &'static str {
"permissions"
}
fn col_metadata() -> &'static str {
"metadata"
}
}
pub trait AuthPasskeyMeta {
fn table() -> &'static str {
"passkeys"
}
fn col_id() -> &'static str {
"id"
}
fn col_name() -> &'static str {
"name"
}
fn col_public_key() -> &'static str {
"public_key"
}
fn col_user_id() -> &'static str {
"user_id"
}
fn col_credential_id() -> &'static str {
"credential_id"
}
fn col_counter() -> &'static str {
"counter"
}
fn col_device_type() -> &'static str {
"device_type"
}
fn col_backed_up() -> &'static str {
"backed_up"
}
fn col_transports() -> &'static str {
"transports"
}
fn col_created_at() -> &'static str {
"created_at"
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemberUserView {
pub id: String,
pub email: Option<String>,
pub name: Option<String>,
pub image: Option<String>,
}
impl MemberUserView {
pub fn from_user(user: &impl AuthUser) -> Self {
Self {
id: user.id().to_string(),
email: user.email().map(|s| s.to_string()),
name: user.name().map(|s| s.to_string()),
image: user.image().map(|s| s.to_string()),
}
}
}
use serde::Deserialize;