use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::fmt::{Display, Formatter}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Identity { pub id: String, pub user_id: String, pub identity_data: Option, pub provider: String, pub last_sign_in_at: String, pub created_at: String, pub updated_at: String, } #[derive(Serialize, Deserialize, Debug)] pub struct AdminListUsersResponse { pub users: Vec, pub aud: String, } #[derive(Serialize, Deserialize, Debug)] pub struct User { pub id: String, pub aud: String, pub role: String, pub email: String, pub email_confirmed_at: Option, pub invited_at: Option, pub phone: String, pub phone_confirmed_at: Option, pub confirmation_sent_at: Option, // For backward compatibility only. Use EmailConfirmedAt or PhoneConfirmedAt instead. pub confirmed_at: Option, pub recovery_sent_at: Option, pub new_email: Option, pub email_change_sent_at: Option, pub new_phone: Option, pub phone_change_sent_at: Option, pub reauthentication_sent_at: Option, pub last_sign_in_at: Option, pub app_metadata: serde_json::Value, pub user_metadata: serde_json::Value, pub factors: Option>, pub identities: Option>, pub created_at: String, pub updated_at: String, pub banned_until: Option, pub deleted_at: Option, } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Factor { pub id: String, pub created_at: String, pub updated_at: String, pub status: String, pub friendly_name: Option, pub factor_type: String, } #[derive(Serialize, Deserialize, Debug)] pub struct GotrueTokenResponse { /// the token that clients use to make authenticated requests to the server or API. It is a bearer token that provides temporary, secure access to server resources. pub access_token: String, pub token_type: String, /// the access_token will remain valid before it expires and needs to be refreshed. pub expires_in: i64, /// a timestamp in seconds indicating the exact time at which the access_token will expire. pub expires_at: i64, /// The refresh token is used to obtain a new access_token once the current access_token expires. /// Refresh tokens are usually long-lived and are stored securely by the client. pub refresh_token: String, pub user: User, pub provider_access_token: Option, pub provider_refresh_token: Option, } impl Display for GotrueTokenResponse { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("GotrueTokenResponse") .field("expires_at", &self.expires_at) .field("token_type", &self.token_type) .finish() } } #[derive(Serialize, Deserialize, Debug)] pub struct GoTrueSettings { pub external: GoTrueOAuthProviderSettings, pub disable_signup: bool, pub mailer_autoconfirm: bool, pub phone_autoconfirm: bool, pub sms_provider: String, pub mfa_enabled: bool, pub saml_enabled: bool, } #[derive(Serialize, Deserialize, Debug)] pub struct GoTrueOAuthProviderSettings(BTreeMap); impl GoTrueOAuthProviderSettings { pub fn has_provider(&self, p: &AuthProvider) -> bool { let a = self.0.get(p.as_str()); match a { Some(v) => *v, None => false, } } pub fn oauth_providers(&self) -> Vec<&str> { self .0 .iter() .filter(|&(key, &value)| value && key != "email" && key != "phone") .map(|(key, _value)| key.as_str()) .collect() } } pub enum AuthProvider { // Non-OAuth providers Email, Phone, // OAuth providers Apple, Azure, Bitbucket, Discord, Facebook, Figma, Github, Gitlab, Google, Keycloak, Kakao, Linkedin, Notion, Spotify, Slack, Workos, Twitch, Twitter, Zoom, } impl AuthProvider { pub fn as_str(&self) -> &str { match self { AuthProvider::Apple => "apple", AuthProvider::Azure => "azure", AuthProvider::Bitbucket => "bitbucket", AuthProvider::Discord => "discord", AuthProvider::Facebook => "facebook", AuthProvider::Figma => "figma", AuthProvider::Github => "github", AuthProvider::Gitlab => "gitlab", AuthProvider::Google => "google", AuthProvider::Keycloak => "keycloak", AuthProvider::Kakao => "kakao", AuthProvider::Linkedin => "linkedin", AuthProvider::Notion => "notion", AuthProvider::Spotify => "spotify", AuthProvider::Slack => "slack", AuthProvider::Workos => "workos", AuthProvider::Twitch => "twitch", AuthProvider::Twitter => "twitter", AuthProvider::Email => "email", AuthProvider::Phone => "phone", AuthProvider::Zoom => "zoom", } } } impl AuthProvider { pub fn from>(value: A) -> Option { match value.as_ref() { "apple" => Some(AuthProvider::Apple), "azure" => Some(AuthProvider::Azure), "bitbucket" => Some(AuthProvider::Bitbucket), "discord" => Some(AuthProvider::Discord), "facebook" => Some(AuthProvider::Facebook), "figma" => Some(AuthProvider::Figma), "github" => Some(AuthProvider::Github), "gitlab" => Some(AuthProvider::Gitlab), "google" => Some(AuthProvider::Google), "keycloak" => Some(AuthProvider::Keycloak), "kakao" => Some(AuthProvider::Kakao), "linkedin" => Some(AuthProvider::Linkedin), "notion" => Some(AuthProvider::Notion), "spotify" => Some(AuthProvider::Spotify), "slack" => Some(AuthProvider::Slack), "workos" => Some(AuthProvider::Workos), "twitch" => Some(AuthProvider::Twitch), "twitter" => Some(AuthProvider::Twitter), "email" => Some(AuthProvider::Email), "phone" => Some(AuthProvider::Phone), "zoom" => Some(AuthProvider::Zoom), _ => None, } } } #[derive(Serialize, Deserialize)] pub struct OAuthURL { pub url: String, } #[derive(Serialize, Deserialize, Debug)] #[serde(untagged)] pub enum SignUpResponse { Authenticated(GotrueTokenResponse), NotAuthenticated(User), } #[derive(Default, Serialize, Deserialize)] pub struct UpdateGotrueUserParams { pub email: String, pub password: Option, pub nonce: String, pub data: BTreeMap, pub app_metadata: Option>, pub phone: String, pub channel: String, pub code_challenge: String, pub code_challenge_method: String, } impl UpdateGotrueUserParams { pub fn new() -> Self { Self::default() } pub fn with_opt_email(mut self, email: Option) -> Self { self.email = email.map(|v| v.to_string()).unwrap_or_default(); self } pub fn with_opt_password(mut self, password: Option) -> Self { self.password = password.map(|v| v.to_string()); self } }