rp_supabase_auth/
types.rs

1use std::collections::HashMap;
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use simd_json::OwnedValue;
6use typed_builder::TypedBuilder;
7
8pub type UserMetadata = OwnedValue;
9pub type AppMetadata = OwnedValue;
10
11/// Login credentials for authentication.
12#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
13pub struct LoginCredentials {
14    #[builder(setter(strip_option), default)]
15    pub email: Option<String>,
16    #[builder(setter(strip_option), default)]
17    pub password: Option<String>,
18    #[builder(setter(strip_option), default)]
19    pub phone: Option<String>,
20}
21
22/// Token request body for the `/token` endpoint.
23#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
24pub struct TokenRequestBody {
25    #[builder(default)]
26    pub email: Option<String>,
27    #[builder(default)]
28    pub phone: Option<String>,
29    #[builder(default)]
30    pub password: Option<String>,
31    #[builder(setter(strip_option), default)]
32    pub refresh_token: Option<String>,
33    #[builder(setter(strip_option), default)]
34    pub grant_type: Option<String>,
35    #[builder(setter(strip_option), default)]
36    pub gotrue_meta_security: Option<GoTrueMetaSecurity>,
37    #[builder(setter(strip_option), default)]
38    pub code: Option<String>,
39    #[builder(setter(strip_option), default)]
40    pub redirect_to: Option<String>,
41    #[builder(setter(strip_option), default)]
42    pub scope: Option<String>,
43    #[builder(setter(strip_option), default)]
44    pub client_id: Option<String>,
45    #[builder(setter(strip_option), default)]
46    pub client_secret: Option<String>,
47    #[builder(setter(strip_option), default)]
48    pub id_token: Option<String>,
49    #[builder(setter(strip_option), default)]
50    pub nonce: Option<String>,
51    #[builder(setter(strip_option), default)]
52    pub invite_token: Option<String>,
53    #[builder(setter(strip_option), default)]
54    pub provider_token: Option<String>,
55    #[builder(setter(strip_option), default)]
56    pub code_verifier: Option<String>,
57}
58
59/// Payload for the `/signup` endpoint.
60#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
61pub struct SignupPayload {
62    #[builder(setter(strip_option), default)]
63    pub email: Option<String>,
64    #[builder(setter(strip_option), default)]
65    pub password: Option<String>,
66    #[builder(setter(strip_option), default)]
67    pub phone: Option<String>,
68    #[builder(setter(strip_option), default)]
69    pub data: Option<UserMetadata>,
70    #[builder(setter(strip_option), default)]
71    pub gotrue_meta_security: Option<GoTrueMetaSecurity>,
72    #[builder(setter(strip_option), default)]
73    pub code_challenge: Option<String>,
74    #[builder(setter(strip_option), default)]
75    pub code_challenge_method: Option<String>,
76}
77
78/// Response from the `/signup` endpoint.
79pub type SignupResponse = AccessTokenResponseSchema;
80
81/// Response from the `/resend` endpoint.
82#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
83pub struct ResendResponse {
84    /// Unique ID of the message as reported by the SMS sending provider.
85    #[builder(setter(strip_option), default)]
86    pub message_id: Option<String>,
87}
88
89/// Response from the `/otp` endpoint.
90#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
91pub struct OtpResponse {
92    /// Unique ID of the message as reported by the SMS sending provider.
93    #[builder(setter(strip_option), default)]
94    pub message_id: Option<String>,
95}
96
97/// Response from the `/factors` endpoint.
98#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
99pub struct FactorsResponse {
100    pub id: String,
101    #[serde(rename = "type")]
102    pub factor_type: MFAFactorType,
103    #[builder(setter(strip_option), default)]
104    pub totp: Option<TotpDetails>,
105    #[builder(setter(strip_option), default)]
106    pub phone: Option<String>,
107}
108
109/// Details for TOTP factor.
110#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
111pub struct TotpDetails {
112    #[builder(setter(strip_option), default)]
113    pub qr_code: Option<String>,
114    #[builder(setter(strip_option), default)]
115    pub secret: Option<String>,
116    #[builder(setter(strip_option), default)]
117    pub uri: Option<String>,
118}
119
120/// Response from the `/factors/{factorId}/challenge` endpoint.
121#[derive(Debug, Serialize, Deserialize, Clone)]
122#[serde(untagged)]
123pub enum ChallengeResponse {
124    TOTPPhone(Box<TOTPPhoneChallengeResponse>),
125    WebAuthn(Box<WebAuthnChallengeResponse>),
126}
127
128/// Response from the `/factors/{factorId}` DELETE endpoint.
129#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
130pub struct FactorDeleteResponse {
131    pub id: String,
132}
133
134/// Response from the `/sso` endpoint.
135#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
136pub struct SsoResponse {
137    pub url: String,
138}
139
140/// Response from the `/admin/users` GET endpoint.
141#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
142pub struct AdminUsersResponse {
143    #[builder(setter(strip_option), default)]
144    pub aud: Option<String>, // Deprecated
145    pub users: Vec<UserSchema>,
146}
147
148/// Data for updating a user's MFA factor.
149#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
150pub struct MFAFactorUpdateData {
151    #[builder(setter(strip_option), default)]
152    pub friendly_name: Option<String>,
153    #[builder(setter(strip_option), default)]
154    pub status: Option<MFAFactorStatus>,
155    // Include additional fields as necessary.
156}
157
158/// Response from the `/admin/sso/providers` GET endpoint.
159#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
160pub struct SsoProvidersResponse {
161    pub items: Vec<SSOProviderSchema>,
162}
163
164/// Use this property to pass a CAPTCHA token only if you have enabled CAPTCHA protection.
165#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
166pub struct GoTrueMetaSecurity {
167    /// The CAPTCHA token.
168    #[serde(rename = "captcha_token")]
169    #[builder(setter(strip_option), default)]
170    pub captcha_token: Option<String>,
171}
172
173/// Error response schema.
174#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder, thiserror::Error)]
175pub struct ErrorSchema {
176    /// Certain responses will contain this property with the provided values.
177    ///
178    /// Usually one of these:
179    /// - `invalid_request`
180    /// - `unauthorized_client`
181    /// - `access_denied`
182    /// - `server_error`
183    /// - `temporarily_unavailable`
184    /// - `unsupported_otp_type`
185    #[serde(rename = "error")]
186    #[builder(setter(strip_option), default)]
187    pub error: Option<String>,
188
189    /// Certain responses that have an `error` property may have this property which describes the
190    /// error.
191    #[serde(rename = "error_description")]
192    #[builder(setter(strip_option), default)]
193    pub error_description: Option<String>,
194
195    /// The HTTP status code. Usually missing if `error` is present.
196    #[serde(rename = "code")]
197    #[builder(setter(strip_option), default)]
198    pub code: Option<i32>,
199
200    /// A basic message describing the problem with the request. Usually missing if `error` is
201    /// present.
202    #[serde(rename = "msg")]
203    #[builder(setter(strip_option), default)]
204    pub msg: Option<String>,
205
206    /// Only returned on the `/signup` endpoint if the password used is too weak. Inspect the
207    /// `reasons` and `msg` property to identify the causes.
208    #[serde(rename = "weak_password")]
209    #[builder(setter(strip_option), default)]
210    pub weak_password: Option<WeakPassword>,
211}
212
213impl core::fmt::Display for ErrorSchema {
214    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
215        // Start with the main error if available
216        if let Some(ref error) = self.error {
217            write!(fmt, "Error: {error}")?;
218        }
219
220        // Append the error description if available
221        if let Some(ref description) = self.error_description {
222            if self.error.is_some() {
223                write!(fmt, " - Description: {description}")?;
224            } else {
225                write!(fmt, "Description: {description}")?;
226            }
227        }
228
229        // Append the HTTP status code if available
230        if let Some(code) = self.code {
231            write!(fmt, " (HTTP Code: {code})")?;
232        }
233
234        // Append the basic message if available
235        if let Some(ref msg) = self.msg {
236            write!(fmt, ". Message: {msg}")?;
237        }
238
239        // Append weak password details if available
240        if let Some(ref weak_password) = self.weak_password {
241            write!(fmt, ". Weak Password: {weak_password}")?;
242        }
243
244        Ok(())
245    }
246}
247
248/// Details about why a password is considered weak.
249#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
250pub struct WeakPassword {
251    /// The reasons why the password is weak.
252    #[serde(rename = "reasons")]
253    pub reasons: Vec<WeakPasswordReason>,
254}
255
256/// Reasons why a password is considered weak.
257#[derive(Debug, Serialize, Deserialize, Clone)]
258#[serde(rename_all = "lowercase")]
259pub enum WeakPasswordReason {
260    Length,
261    Characters,
262    Pwned,
263}
264
265impl core::fmt::Display for WeakPassword {
266    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
267        let reasons = self
268            .reasons
269            .iter()
270            .map(|reason| format!("{reason:?}"))
271            .collect::<Vec<_>>()
272            .join(", ");
273        write!(fmt, "reasons: [{reasons}]")
274    }
275}
276
277/// Object describing the user related to the issued access and refresh tokens.
278#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
279pub struct UserSchema {
280    /// User ID.
281    #[serde(rename = "id")]
282    #[builder(setter(strip_option), default)]
283    pub id: Option<String>,
284
285    /// Deprecated.
286    #[serde(rename = "aud")]
287    #[builder(setter(strip_option), default)]
288    pub aud: Option<String>,
289
290    /// Role.
291    #[serde(rename = "role")]
292    #[builder(setter(strip_option), default)]
293    pub role: Option<String>,
294
295    /// User's primary contact email.
296    #[serde(rename = "email")]
297    #[builder(setter(strip_option), default)]
298    pub email: Option<String>,
299
300    /// Timestamp when the email was confirmed.
301    #[serde(rename = "email_confirmed_at")]
302    #[builder(setter(strip_option), default)]
303    pub email_confirmed_at: Option<DateTime<Utc>>,
304
305    /// User's primary contact phone number.
306    #[serde(rename = "phone")]
307    #[builder(setter(strip_option), default)]
308    pub phone: Option<String>,
309
310    /// Timestamp when the phone number was confirmed.
311    #[serde(rename = "phone_confirmed_at")]
312    #[builder(setter(strip_option), default)]
313    pub phone_confirmed_at: Option<DateTime<Utc>>,
314
315    /// Timestamp when the confirmation was sent.
316    #[serde(rename = "confirmation_sent_at")]
317    #[builder(setter(strip_option), default)]
318    pub confirmation_sent_at: Option<DateTime<Utc>>,
319
320    /// Timestamp when the user was confirmed.
321    #[serde(rename = "confirmed_at")]
322    #[builder(setter(strip_option), default)]
323    pub confirmed_at: Option<DateTime<Utc>>,
324
325    /// Timestamp when the recovery email was sent.
326    #[serde(rename = "recovery_sent_at")]
327    #[builder(setter(strip_option), default)]
328    pub recovery_sent_at: Option<DateTime<Utc>>,
329
330    /// New email address if the user is changing it.
331    #[serde(rename = "new_email")]
332    #[builder(setter(strip_option), default)]
333    pub new_email: Option<String>,
334
335    /// Timestamp when the email change was sent.
336    #[serde(rename = "email_change_sent_at")]
337    #[builder(setter(strip_option), default)]
338    pub email_change_sent_at: Option<DateTime<Utc>>,
339
340    /// New phone number if the user is changing it.
341    #[serde(rename = "new_phone")]
342    #[builder(setter(strip_option), default)]
343    pub new_phone: Option<String>,
344
345    /// Timestamp when the phone change was sent.
346    #[serde(rename = "phone_change_sent_at")]
347    #[builder(setter(strip_option), default)]
348    pub phone_change_sent_at: Option<DateTime<Utc>>,
349
350    /// Timestamp when reauthentication was sent.
351    #[serde(rename = "reauthentication_sent_at")]
352    #[builder(setter(strip_option), default)]
353    pub reauthentication_sent_at: Option<DateTime<Utc>>,
354
355    /// Timestamp of the last sign-in.
356    #[serde(rename = "last_sign_in_at")]
357    #[builder(setter(strip_option), default)]
358    pub last_sign_in_at: Option<DateTime<Utc>>,
359
360    /// Application-specific metadata.
361    #[serde(rename = "app_metadata")]
362    #[builder(setter(strip_option), default)]
363    pub app_metadata: Option<OwnedValue>,
364
365    /// User-specific metadata.
366    #[serde(rename = "user_metadata")]
367    #[builder(setter(strip_option), default)]
368    pub user_metadata: Option<OwnedValue>,
369
370    /// Multi-factor authentication factors.
371    #[serde(rename = "factors")]
372    #[builder(setter(strip_option), default)]
373    pub factors: Option<Vec<MFAFactorSchema>>,
374
375    /// External identities linked to the user.
376    #[serde(rename = "identities")]
377    #[builder(setter(strip_option), default)]
378    pub identities: Option<Vec<IdentitySchema>>,
379
380    /// Timestamp until which the user is banned.
381    #[serde(rename = "banned_until")]
382    #[builder(setter(strip_option), default)]
383    pub banned_until: Option<DateTime<Utc>>,
384
385    /// Timestamp when the user was created.
386    #[serde(rename = "created_at")]
387    #[builder(setter(strip_option), default)]
388    pub created_at: Option<DateTime<Utc>>,
389
390    /// Timestamp when the user was last updated.
391    #[serde(rename = "updated_at")]
392    #[builder(setter(strip_option), default)]
393    pub updated_at: Option<DateTime<Utc>>,
394
395    /// Timestamp when the user was deleted.
396    #[serde(rename = "deleted_at")]
397    #[builder(setter(strip_option), default)]
398    pub deleted_at: Option<DateTime<Utc>>,
399
400    /// Indicates if the user is anonymous.
401    #[serde(rename = "is_anonymous")]
402    #[builder(setter(strip_option), default)]
403    pub is_anonymous: Option<bool>,
404}
405
406/// Schema for SAML attribute mapping.
407#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
408pub struct SAMLAttributeMappingSchema {
409    /// Mapping of SAML attributes.
410    #[serde(rename = "keys")]
411    #[builder(setter(strip_option), default)]
412    pub keys: Option<HashMap<String, SAMLAttributeMappingKey>>,
413}
414
415/// Key-value pairs for SAML attribute mapping.
416#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
417pub struct SAMLAttributeMappingKey {
418    #[serde(rename = "name")]
419    #[builder(setter(strip_option), default)]
420    pub name: Option<String>,
421    #[serde(rename = "names")]
422    #[builder(setter(strip_option), default)]
423    pub names: Option<Vec<String>>,
424    #[serde(rename = "default")]
425    #[builder(setter(strip_option), default)]
426    pub default: Option<OwnedValue>,
427}
428
429/// Schema representing an SSO provider.
430#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
431pub struct SSOProviderSchema {
432    /// SSO provider ID.
433    #[serde(rename = "id")]
434    #[builder(setter(strip_option), default)]
435    pub id: Option<String>,
436
437    /// List of SSO domains.
438    #[serde(rename = "sso_domains")]
439    #[builder(setter(strip_option), default)]
440    pub sso_domains: Option<Vec<SSODomain>>,
441
442    /// SAML configuration details.
443    #[serde(rename = "saml")]
444    #[builder(setter(strip_option), default)]
445    pub saml: Option<SAMLConfiguration>,
446}
447
448/// Domain associated with SSO.
449#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
450pub struct SSODomain {
451    /// Domain name.
452    #[serde(rename = "domain")]
453    #[builder(setter(strip_option), default)]
454    pub domain: Option<String>,
455}
456
457/// SAML configuration details.
458#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
459pub struct SAMLConfiguration {
460    /// Entity ID.
461    #[serde(rename = "entity_id")]
462    #[builder(setter(strip_option), default)]
463    pub entity_id: Option<String>,
464
465    /// SAML metadata XML.
466    #[serde(rename = "metadata_xml")]
467    #[builder(setter(strip_option), default)]
468    pub metadata_xml: Option<String>,
469
470    /// SAML metadata URL.
471    #[serde(rename = "metadata_url")]
472    #[builder(setter(strip_option), default)]
473    pub metadata_url: Option<String>,
474
475    /// Attribute mapping configuration.
476    #[serde(rename = "attribute_mapping")]
477    #[builder(setter(strip_option), default)]
478    pub attribute_mapping: Option<SAMLAttributeMappingSchema>,
479}
480
481/// Response schema for access and refresh tokens.
482#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
483pub struct AccessTokenResponseSchema {
484    /// A valid JWT that will expire in `expires_in` seconds.
485    #[serde(rename = "access_token")]
486    #[builder(setter(strip_option), default)]
487    pub access_token: Option<String>,
488
489    /// An opaque string that can be used once to obtain new tokens.
490    #[serde(rename = "refresh_token")]
491    #[builder(setter(strip_option), default)]
492    pub refresh_token: Option<String>,
493
494    /// Token type, usually `bearer`.
495    #[serde(rename = "token_type")]
496    #[builder(setter(strip_option), default)]
497    pub token_type: Option<String>,
498
499    /// Number of seconds until the `access_token` expires.
500    #[serde(rename = "expires_in")]
501    #[builder(setter(strip_option), default)]
502    pub expires_in: Option<i64>,
503
504    /// UNIX timestamp when the `access_token` expires.
505    #[serde(rename = "expires_at")]
506    #[builder(setter(strip_option), default)]
507    pub expires_at: Option<i64>,
508
509    /// Indicates if the password used is weak.
510    #[serde(rename = "weak_password")]
511    #[builder(setter(strip_option), default)]
512    pub weak_password: Option<WeakPasswordResponse>,
513
514    /// User information.
515    #[serde(rename = "user")]
516    #[builder(setter(strip_option), default)]
517    pub user: Option<UserSchema>,
518}
519
520/// Response indicating a weak password.
521#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
522pub struct WeakPasswordResponse {
523    /// Reasons why the password is weak.
524    #[serde(rename = "reasons")]
525    #[builder(setter(strip_option), default)]
526    pub reasons: Option<Vec<WeakPasswordReason>>,
527
528    /// Message describing the weakness.
529    #[serde(rename = "message")]
530    #[builder(setter(strip_option), default)]
531    pub message: Option<String>,
532}
533
534/// Represents a MFA factor.
535#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
536pub struct MFAFactorSchema {
537    /// Factor ID.
538    #[serde(rename = "id")]
539    #[builder(setter(strip_option), default)]
540    pub id: Option<String>,
541
542    /// Status of the factor.
543    ///
544    /// Usually one of:
545    /// - `verified`
546    /// - `unverified`
547    #[serde(rename = "status")]
548    #[builder(setter(strip_option), default)]
549    pub status: Option<MFAFactorStatus>,
550
551    /// Friendly name for the factor.
552    #[serde(rename = "friendly_name")]
553    #[builder(setter(strip_option), default)]
554    pub friendly_name: Option<String>,
555
556    /// Type of the factor.
557    ///
558    /// Usually one of:
559    /// - `totp`
560    /// - `phone`
561    /// - `webauthn`
562    #[serde(rename = "factor_type")]
563    #[builder(setter(strip_option), default)]
564    pub factor_type: Option<MFAFactorType>,
565
566    /// `WebAuthn` credential details.
567    #[serde(rename = "web_authn_credential")]
568    #[builder(setter(strip_option), default)]
569    pub web_authn_credential: Option<OwnedValue>,
570
571    /// Phone number associated with the factor.
572    #[serde(rename = "phone")]
573    #[builder(setter(strip_option), default)]
574    pub phone: Option<String>,
575
576    /// Timestamp when the factor was created.
577    #[serde(rename = "created_at")]
578    #[builder(setter(strip_option), default)]
579    pub created_at: Option<DateTime<Utc>>,
580
581    /// Timestamp when the factor was last updated.
582    #[serde(rename = "updated_at")]
583    #[builder(setter(strip_option), default)]
584    pub updated_at: Option<DateTime<Utc>>,
585
586    /// Timestamp when the factor was last challenged.
587    #[serde(rename = "last_challenged_at")]
588    #[builder(setter(strip_option), default)]
589    pub last_challenged_at: Option<DateTime<Utc>>,
590}
591
592/// Status of the MFA factor.
593#[derive(Debug, Serialize, Deserialize, Clone)]
594#[serde(rename_all = "lowercase")]
595pub enum MFAFactorStatus {
596    Verified,
597    Unverified,
598}
599
600/// Type of the MFA factor.
601#[derive(Debug, Serialize, Deserialize, Clone)]
602#[serde(rename_all = "lowercase")]
603pub enum MFAFactorType {
604    Totp,
605    Phone,
606    Webauthn,
607}
608
609/// Schema representing an identity.
610#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
611pub struct IdentitySchema {
612    #[serde(rename = "identity_id")]
613    #[builder(setter(strip_option), default)]
614    pub identity_id: Option<String>,
615
616    #[serde(rename = "id")]
617    #[builder(setter(strip_option), default)]
618    pub id: Option<String>,
619
620    #[serde(rename = "user_id")]
621    #[builder(setter(strip_option), default)]
622    pub user_id: Option<String>,
623
624    #[serde(rename = "identity_data")]
625    #[builder(setter(strip_option), default)]
626    pub identity_data: Option<OwnedValue>,
627
628    #[serde(rename = "provider")]
629    #[builder(setter(strip_option), default)]
630    pub provider: Option<String>,
631
632    #[serde(rename = "last_sign_in_at")]
633    #[builder(setter(strip_option), default)]
634    pub last_sign_in_at: Option<DateTime<Utc>>,
635
636    #[serde(rename = "created_at")]
637    #[builder(setter(strip_option), default)]
638    pub created_at: Option<DateTime<Utc>>,
639
640    #[serde(rename = "updated_at")]
641    #[builder(setter(strip_option), default)]
642    pub updated_at: Option<DateTime<Utc>>,
643
644    #[serde(rename = "email")]
645    #[builder(setter(strip_option), default)]
646    pub email: Option<String>,
647}
648
649/// Response for TOTP or phone challenge.
650#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
651pub struct TOTPPhoneChallengeResponse {
652    /// ID of the challenge.
653    #[serde(rename = "id")]
654    pub id: String,
655
656    /// Type of the challenge.
657    #[serde(rename = "type")]
658    pub challenge_type: TOTPPhoneChallengeType,
659
660    /// UNIX timestamp when the challenge expires.
661    #[serde(rename = "expires_at")]
662    pub expires_at: i64,
663}
664
665/// Type of the TOTP or phone challenge.
666#[derive(Debug, Serialize, Deserialize, Clone)]
667#[serde(rename_all = "lowercase")]
668pub enum TOTPPhoneChallengeType {
669    Totp,
670    Phone,
671}
672
673/// Response for `WebAuthn` challenge.
674#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
675pub struct WebAuthnChallengeResponse {
676    /// ID of the challenge.
677    #[serde(rename = "id")]
678    pub id: String,
679
680    /// Type of the challenge.
681    #[serde(rename = "type")]
682    pub challenge_type: WebAuthnChallengeType,
683
684    /// UNIX timestamp when the challenge expires.
685    #[serde(rename = "expires_at")]
686    pub expires_at: i64,
687
688    /// Credential request options.
689    #[serde(rename = "credential_request_options")]
690    #[builder(setter(strip_option), default)]
691    pub credential_request_options: Option<CredentialRequestOptions>,
692
693    /// Credential creation options.
694    #[serde(rename = "credential_creation_options")]
695    #[builder(setter(strip_option), default)]
696    pub credential_creation_options: Option<CredentialCreationOptions>,
697}
698
699/// Type of the `WebAuthn` challenge.
700#[derive(Debug, Serialize, Deserialize, Clone)]
701#[serde(rename_all = "lowercase")]
702pub enum WebAuthnChallengeType {
703    Webauthn,
704}
705
706/// `WebAuthn` credential assertion options.
707#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
708pub struct CredentialAssertion {
709    /// A random challenge generated by the server, base64url encoded.
710    #[serde(rename = "challenge")]
711    pub challenge: String,
712
713    /// The relying party's identifier (usually the domain name).
714    #[serde(rename = "rpId")]
715    pub rp_id: String,
716
717    /// List of credentials acceptable for this authentication.
718    #[serde(rename = "allowCredentials")]
719    pub allow_credentials: Vec<PublicKeyCredentialDescriptor>,
720
721    /// Time (in milliseconds) that the user has to respond to the authentication prompt.
722    #[serde(rename = "timeout")]
723    pub timeout: i64,
724
725    /// The relying party's requirements for user verification.
726    #[serde(rename = "userVerification")]
727    #[builder(setter(strip_option), default)]
728    pub user_verification: Option<UserVerificationRequirement>,
729
730    /// Additional parameters requesting additional processing by the client.
731    #[serde(rename = "extensions")]
732    #[builder(setter(strip_option), default)]
733    pub extensions: Option<OwnedValue>,
734
735    /// Status of the credential assertion.
736    #[serde(rename = "status")]
737    #[builder(setter(strip_option), default)]
738    pub status: Option<CredentialAssertionStatus>,
739
740    /// Error message if the assertion failed.
741    #[serde(rename = "errorMessage")]
742    #[builder(setter(strip_option), default)]
743    pub error_message: Option<String>,
744
745    /// User handle, base64url encoded.
746    #[serde(rename = "userHandle")]
747    #[builder(setter(strip_option), default)]
748    pub user_handle: Option<String>,
749
750    /// Type of authenticator to use.
751    #[serde(rename = "authenticatorAttachment")]
752    #[builder(setter(strip_option), default)]
753    pub authenticator_attachment: Option<AuthenticatorAttachment>,
754}
755
756/// Options for requesting a credential assertion.
757#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
758pub struct CredentialRequestOptions {
759    /// A challenge to be signed by the authenticator.
760    #[serde(rename = "challenge")]
761    #[builder(setter(strip_option), default)]
762    pub challenge: Option<String>,
763
764    /// Time (in milliseconds) that the caller is willing to wait for the call to complete.
765    #[serde(rename = "timeout")]
766    #[builder(setter(strip_option), default)]
767    pub timeout: Option<i64>,
768
769    /// Relying Party ID.
770    #[serde(rename = "rpId")]
771    #[builder(setter(strip_option), default)]
772    pub rp_id: Option<String>,
773
774    /// List of credentials acceptable for this authentication.
775    #[serde(rename = "allowCredentials")]
776    #[builder(setter(strip_option), default)]
777    pub allow_credentials: Option<Vec<PublicKeyCredentialDescriptor>>,
778
779    /// User verification requirement.
780    #[serde(rename = "userVerification")]
781    #[builder(setter(strip_option), default)]
782    pub user_verification: Option<UserVerificationRequirement>,
783}
784
785/// Options for creating a new credential.
786#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
787pub struct CredentialCreationOptions {
788    /// Relying Party information.
789    #[serde(rename = "rp")]
790    #[builder(setter(strip_option), default)]
791    pub rp: Option<RelyingPartyInfo>,
792
793    /// User information.
794    #[serde(rename = "user")]
795    #[builder(setter(strip_option), default)]
796    pub user: Option<UserInfo>,
797
798    /// A challenge to be signed by the authenticator.
799    #[serde(rename = "challenge")]
800    #[builder(setter(strip_option), default)]
801    pub challenge: Option<String>,
802
803    /// Public key credential parameters.
804    #[serde(rename = "pubKeyCredParams")]
805    #[builder(setter(strip_option), default)]
806    pub pub_key_cred_params: Option<Vec<PublicKeyCredentialParameters>>,
807
808    /// Time (in milliseconds) that the caller is willing to wait for the call to complete.
809    #[serde(rename = "timeout")]
810    #[builder(setter(strip_option), default)]
811    pub timeout: Option<i64>,
812
813    /// List of credentials to exclude.
814    #[serde(rename = "excludeCredentials")]
815    #[builder(setter(strip_option), default)]
816    pub exclude_credentials: Option<Vec<PublicKeyCredentialDescriptor>>,
817
818    /// Authenticator selection criteria.
819    #[serde(rename = "authenticatorSelection")]
820    #[builder(setter(strip_option), default)]
821    pub authenticator_selection: Option<AuthenticatorSelectionCriteria>,
822
823    /// Preferred attestation conveyance.
824    #[serde(rename = "attestation")]
825    #[builder(setter(strip_option), default)]
826    pub attestation: Option<AttestationConveyancePreference>,
827}
828
829/// Information about the relying party.
830#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
831pub struct RelyingPartyInfo {
832    #[serde(rename = "id")]
833    #[builder(setter(strip_option), default)]
834    pub id: Option<String>,
835    #[serde(rename = "name")]
836    #[builder(setter(strip_option), default)]
837    pub name: Option<String>,
838}
839
840/// Information about the user.
841#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
842pub struct UserInfo {
843    #[serde(rename = "name")]
844    #[builder(setter(strip_option), default)]
845    pub name: Option<String>,
846    // Include other user fields as necessary
847}
848
849/// Parameters for public key credentials.
850#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
851pub struct PublicKeyCredentialParameters {
852    #[serde(rename = "type")]
853    #[builder(setter(strip_option), default)]
854    pub cred_type: Option<String>,
855    #[serde(rename = "alg")]
856    #[builder(setter(strip_option), default)]
857    pub alg: Option<i32>,
858}
859
860/// Descriptor for public key credentials.
861#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
862pub struct PublicKeyCredentialDescriptor {
863    #[serde(rename = "type")]
864    #[builder(setter(strip_option), default)]
865    pub cred_type: Option<String>,
866    #[serde(rename = "id")]
867    #[builder(setter(strip_option), default)]
868    pub id: Option<String>,
869    #[serde(rename = "transports")]
870    #[builder(setter(strip_option), default)]
871    pub transports: Option<Vec<String>>,
872}
873
874/// Criteria for authenticator selection.
875#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
876pub struct AuthenticatorSelectionCriteria {
877    #[serde(rename = "authenticatorAttachment")]
878    #[builder(setter(strip_option), default)]
879    pub authenticator_attachment: Option<AuthenticatorAttachment>,
880    #[serde(rename = "requireResidentKey")]
881    #[builder(setter(strip_option), default)]
882    pub require_resident_key: Option<bool>,
883    #[serde(rename = "userVerification")]
884    #[builder(setter(strip_option), default)]
885    pub user_verification: Option<UserVerificationRequirement>,
886}
887
888/// User verification requirement.
889#[derive(Debug, Serialize, Deserialize, Clone)]
890#[serde(rename_all = "lowercase")]
891pub enum UserVerificationRequirement {
892    Required,
893    Preferred,
894    Discouraged,
895}
896
897/// Status of the credential assertion.
898#[derive(Debug, Serialize, Deserialize, Clone)]
899#[serde(rename_all = "lowercase")]
900pub enum CredentialAssertionStatus {
901    Ok,
902    Failed,
903}
904
905/// Type of authenticator attachment.
906#[derive(Debug, Serialize, Deserialize, Clone)]
907#[serde(rename_all = "kebab-case")]
908pub enum AuthenticatorAttachment {
909    Platform,
910    CrossPlatform,
911}
912
913/// Preferred attestation conveyance.
914#[derive(Debug, Serialize, Deserialize, Clone)]
915#[serde(rename_all = "lowercase")]
916pub enum AttestationConveyancePreference {
917    None,
918    Indirect,
919    Direct,
920}
921
922/// Response from admin generate link
923#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
924pub struct AdminGenerateLinkResponse {
925    pub action_link: String,
926    #[builder(setter(strip_option), default)]
927    pub email_otp: Option<String>,
928    #[builder(setter(strip_option), default)]
929    pub hashed_token: Option<String>,
930    #[builder(setter(strip_option), default)]
931    pub verification_type: Option<String>,
932    #[builder(setter(strip_option), default)]
933    pub redirect_to: Option<String>,
934    // Include any additional properties
935}
936
937/// Response for settings endpoint
938#[expect(clippy::struct_excessive_bools, reason = "this struct is a DTO")]
939#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
940pub struct SettingsResponse {
941    pub disable_signup: bool,
942    pub mailer_autoconfirm: bool,
943    pub phone_autoconfirm: bool,
944    #[builder(setter(strip_option), default)]
945    pub sms_provider: Option<String>,
946    pub saml_enabled: bool,
947    pub external: std::collections::HashMap<String, bool>,
948}
949
950/// Audit log entry
951#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
952pub struct AuditLogEntry {
953    pub id: String,
954    pub payload: AuditLogPayload,
955    pub created_at: DateTime<Utc>,
956    #[builder(setter(strip_option), default)]
957    pub ip_address: Option<String>,
958}
959
960/// Audit log payload
961#[derive(Debug, Serialize, Deserialize, Clone, TypedBuilder)]
962pub struct AuditLogPayload {
963    #[builder(setter(strip_option), default)]
964    pub actor_id: Option<String>,
965    #[builder(setter(strip_option), default)]
966    pub actor_via_sso: Option<bool>,
967    #[builder(setter(strip_option), default)]
968    pub actor_username: Option<String>,
969    #[builder(setter(strip_option), default)]
970    pub actor_name: Option<String>,
971    #[builder(setter(strip_option), default)]
972    pub traits: Option<OwnedValue>,
973    #[builder(setter(strip_option), default)]
974    pub action: Option<String>,
975    #[builder(setter(strip_option), default)]
976    pub log_type: Option<String>,
977}