firebase_rs_sdk/auth/phone/
mod.rs

1use std::sync::Arc;
2
3use crate::auth::api::Auth;
4use crate::auth::error::AuthResult;
5use crate::auth::types::{ApplicationVerifier, ConfirmationResult, MultiFactorAssertion};
6
7/// Provider ID for phone authentication.
8pub const PHONE_PROVIDER_ID: &str = "phone";
9
10/// Represents a credential produced during a phone verification flow.
11#[derive(Clone, Debug)]
12pub struct PhoneAuthCredential {
13    verification_id: String,
14    verification_code: String,
15}
16
17impl PhoneAuthCredential {
18    /// Creates a credential from a verification ID and SMS verification code.
19    pub fn new(verification_id: impl Into<String>, verification_code: impl Into<String>) -> Self {
20        Self {
21            verification_id: verification_id.into(),
22            verification_code: verification_code.into(),
23        }
24    }
25
26    /// Returns the verification identifier issued by Firebase Auth.
27    pub fn verification_id(&self) -> &str {
28        &self.verification_id
29    }
30
31    /// Returns the SMS verification code supplied by the user.
32    pub fn verification_code(&self) -> &str {
33        &self.verification_code
34    }
35
36    pub(crate) fn into_parts(self) -> (String, String) {
37        (self.verification_id, self.verification_code)
38    }
39}
40
41/// Utility for interacting with phone authentication flows via [`Auth`].
42pub struct PhoneAuthProvider {
43    auth: Arc<Auth>,
44}
45
46impl PhoneAuthProvider {
47    /// Creates a provider bound to the supplied [`Auth`] instance.
48    pub fn new(auth: Arc<Auth>) -> Self {
49        Self { auth }
50    }
51
52    /// Sends a verification code to the given phone number and returns the verification ID.
53    pub async fn verify_phone_number(
54        &self,
55        phone_number: &str,
56        verifier: Arc<dyn ApplicationVerifier>,
57    ) -> AuthResult<String> {
58        self.auth
59            .send_phone_verification_code(phone_number, verifier)
60            .await
61    }
62
63    /// Builds a credential from a verification ID/code pair.
64    pub fn credential(
65        verification_id: impl Into<String>,
66        verification_code: impl Into<String>,
67    ) -> PhoneAuthCredential {
68        PhoneAuthCredential::new(verification_id, verification_code)
69    }
70
71    /// Derives a credential from a [`ConfirmationResult`].
72    pub fn credential_from_confirmation(
73        confirmation: &ConfirmationResult,
74        verification_code: impl Into<String>,
75    ) -> PhoneAuthCredential {
76        PhoneAuthCredential::new(confirmation.verification_id(), verification_code.into())
77    }
78
79    /// Signs the user in with the provided credential.
80    pub async fn sign_in_with_credential(
81        &self,
82        credential: PhoneAuthCredential,
83    ) -> AuthResult<crate::auth::UserCredential> {
84        self.auth.sign_in_with_phone_credential(credential).await
85    }
86
87    /// Links the current user with the provided credential.
88    pub async fn link_with_credential(
89        &self,
90        credential: PhoneAuthCredential,
91    ) -> AuthResult<crate::auth::UserCredential> {
92        self.auth.link_with_phone_credential(credential).await
93    }
94
95    /// Reauthenticates the current user with the provided credential.
96    pub async fn reauthenticate_with_credential(
97        &self,
98        credential: PhoneAuthCredential,
99    ) -> AuthResult<Arc<crate::auth::User>> {
100        self.auth
101            .reauthenticate_with_phone_credential(credential)
102            .await
103    }
104}
105
106/// Provides helpers for creating phone-based multi-factor assertions.
107///
108/// Mirrors the JavaScript implementation in
109/// `packages/auth/src/platform_browser/mfa/assertions/phone.ts`.
110pub struct PhoneMultiFactorGenerator;
111
112impl PhoneMultiFactorGenerator {
113    /// Builds a multi-factor assertion from a [`PhoneAuthCredential`].
114    pub fn assertion(credential: PhoneAuthCredential) -> MultiFactorAssertion {
115        MultiFactorAssertion::from_phone_credential(credential)
116    }
117
118    /// The identifier of the phone second factor (`"phone"`).
119    pub const FACTOR_ID: &'static str = PHONE_PROVIDER_ID;
120}