1use crate::app::FirebaseApp;
2use crate::auth::error::{AuthError, AuthResult};
3use crate::auth::token_manager::{TokenManager, TokenUpdate};
4use crate::util::PartialObserver;
5use serde::{Deserialize, Serialize};
6use serde_json::json;
7use std::sync::{Arc, Mutex};
8use std::time::Duration;
9
10#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
11pub struct UserInfo {
12 pub uid: String,
13 pub display_name: Option<String>,
14 pub email: Option<String>,
15 pub phone_number: Option<String>,
16 pub photo_url: Option<String>,
17 pub provider_id: String,
18}
19
20#[derive(Clone, Debug)]
21pub struct User {
22 app: FirebaseApp,
23 info: UserInfo,
24 email_verified: bool,
25 is_anonymous: bool,
26 token_manager: TokenManager,
27}
28
29impl User {
30 pub fn new(app: FirebaseApp, info: UserInfo) -> Self {
32 Self {
33 app,
34 info,
35 email_verified: false,
36 is_anonymous: false,
37 token_manager: TokenManager::default(),
38 }
39 }
40
41 pub fn app(&self) -> &FirebaseApp {
43 &self.app
44 }
45
46 pub fn is_anonymous(&self) -> bool {
48 self.is_anonymous
49 }
50
51 pub fn set_anonymous(&mut self, anonymous: bool) {
53 self.is_anonymous = anonymous;
54 }
55
56 pub fn uid(&self) -> &str {
58 &self.info.uid
59 }
60
61 pub fn email_verified(&self) -> bool {
63 self.email_verified
64 }
65
66 pub fn refresh_token(&self) -> Option<String> {
68 self.token_manager.refresh_token()
69 }
70
71 pub fn get_id_token(&self, _force_refresh: bool) -> AuthResult<String> {
73 self.token_manager
74 .access_token()
75 .ok_or_else(|| AuthError::InvalidCredential("Missing ID token".into()))
76 }
77
78 pub fn token_manager(&self) -> &TokenManager {
80 &self.token_manager
81 }
82
83 pub fn update_tokens(
85 &self,
86 access_token: Option<String>,
87 refresh_token: Option<String>,
88 expires_in: Option<Duration>,
89 ) {
90 let update = TokenUpdate::new(access_token, refresh_token, expires_in);
91 self.token_manager.update(update);
92 }
93
94 pub fn info(&self) -> &UserInfo {
96 &self.info
97 }
98}
99
100#[derive(Clone, Debug)]
101pub struct UserCredential {
102 pub user: Arc<User>,
103 pub provider_id: Option<String>,
104 pub operation_type: Option<String>,
105}
106
107#[derive(Debug, Clone)]
108pub struct AuthCredential {
109 pub provider_id: String,
110 pub sign_in_method: String,
111 pub token_response: serde_json::Value,
112}
113
114#[derive(Debug, Clone, Default)]
115pub struct AuthConfig {
116 pub api_key: Option<String>,
117 pub identity_toolkit_endpoint: Option<String>,
118 pub secure_token_endpoint: Option<String>,
119}
120
121#[derive(Clone)]
122pub struct EmailAuthProvider;
123
124impl EmailAuthProvider {
125 pub const PROVIDER_ID: &'static str = "password";
126
127 pub fn credential(email: &str, password: &str) -> AuthCredential {
129 AuthCredential {
130 provider_id: Self::PROVIDER_ID.to_string(),
131 sign_in_method: Self::PROVIDER_ID.to_string(),
132 token_response: json!({
133 "email": email,
134 "password": password,
135 "returnSecureToken": true,
136 }),
137 }
138 }
139}
140
141#[derive(Default)]
142pub struct AuthStateListeners {
143 observers: Mutex<Vec<PartialObserver<Arc<User>>>>,
144}
145
146impl AuthStateListeners {
147 pub fn add_observer(&self, observer: PartialObserver<Arc<User>>) {
149 self.observers.lock().unwrap().push(observer);
150 }
151
152 pub fn notify(&self, user: Arc<User>) {
154 for observer in self.observers.lock().unwrap().iter() {
155 if let Some(next) = observer.next.clone() {
156 next(&user);
157 }
158 }
159 }
160}
161
162#[derive(Debug, Serialize)]
163pub struct SignInWithPasswordRequest {
164 pub email: String,
165 pub password: String,
166 #[serde(rename = "returnSecureToken")]
167 pub return_secure_token: bool,
168}
169
170#[derive(Debug, Deserialize)]
171pub struct SignInWithPasswordResponse {
172 #[serde(rename = "idToken")]
173 pub id_token: String,
174 #[serde(rename = "refreshToken")]
175 pub refresh_token: String,
176 #[serde(rename = "localId")]
177 pub local_id: String,
178 pub email: String,
179 #[serde(rename = "expiresIn")]
180 pub expires_in: String,
181}
182
183#[derive(Debug, Serialize)]
184pub struct SignUpRequest {
185 pub email: String,
186 pub password: String,
187 #[serde(rename = "returnSecureToken")]
188 pub return_secure_token: bool,
189}
190
191#[derive(Debug, Deserialize)]
192pub struct SignUpResponse {
193 #[serde(rename = "idToken")]
194 pub id_token: String,
195 #[serde(rename = "refreshToken")]
196 pub refresh_token: String,
197 #[serde(rename = "localId")]
198 pub local_id: String,
199 pub email: String,
200 #[serde(rename = "expiresIn")]
201 pub expires_in: Option<String>,
202}
203
204#[derive(Debug, Clone, Deserialize)]
205pub struct ProviderUserInfo {
206 #[serde(rename = "providerId")]
207 pub provider_id: Option<String>,
208 #[serde(rename = "rawId")]
209 pub raw_id: Option<String>,
210 #[serde(rename = "email")]
211 pub email: Option<String>,
212 #[serde(rename = "displayName")]
213 pub display_name: Option<String>,
214 #[serde(rename = "photoUrl")]
215 pub photo_url: Option<String>,
216 #[serde(rename = "phoneNumber")]
217 pub phone_number: Option<String>,
218}
219
220#[derive(Debug, Clone, Deserialize)]
221pub struct AccountInfoUser {
222 #[serde(rename = "localId")]
223 pub local_id: Option<String>,
224 #[serde(rename = "displayName")]
225 pub display_name: Option<String>,
226 #[serde(rename = "photoUrl")]
227 pub photo_url: Option<String>,
228 #[serde(rename = "email")]
229 pub email: Option<String>,
230 #[serde(rename = "emailVerified")]
231 pub email_verified: Option<bool>,
232 #[serde(rename = "phoneNumber")]
233 pub phone_number: Option<String>,
234 #[serde(rename = "providerUserInfo")]
235 pub provider_user_info: Option<Vec<ProviderUserInfo>>,
236}
237
238#[derive(Debug, Clone, Deserialize)]
239pub struct GetAccountInfoResponse {
240 pub users: Vec<AccountInfoUser>,
241}