firebase_admin_sdk/auth/
models.rs

1//! Data models for Firebase Authentication.
2
3use serde::{Deserialize, Serialize};
4
5/// Represents a user in the Firebase project.
6#[derive(Debug, Serialize, Deserialize, Default)]
7#[serde(rename_all = "camelCase")]
8pub struct UserRecord {
9    /// The user's unique ID.
10    pub local_id: String,
11    /// The user's email address.
12    pub email: Option<String>,
13    /// Whether the user's email has been verified.
14    pub email_verified: bool,
15    /// The user's display name.
16    pub display_name: Option<String>,
17    /// The user's photo URL.
18    pub photo_url: Option<String>,
19    /// The user's phone number.
20    pub phone_number: Option<String>,
21    /// Whether the user is disabled.
22    pub disabled: bool,
23    /// Additional metadata about the user.
24    pub metadata: Option<UserMetadata>,
25    /// Information about the user's providers (Google, Facebook, etc.).
26    pub provider_user_info: Option<Vec<ProviderUserInfo>>,
27    /// The user's password hash.
28    pub password_hash: Option<String>,
29    /// The user's password salt.
30    pub password_salt: Option<String>,
31    /// Custom claims set on the user (JSON string).
32    pub custom_attributes: Option<String>,
33    /// The user's tenant ID (for multi-tenancy).
34    pub tenant_id: Option<String>,
35    /// Multi-factor authentication info.
36    pub mfa_info: Option<Vec<MfaInfo>>,
37}
38
39/// Metadata associated with a user account.
40#[derive(Debug, Serialize, Deserialize, Default)]
41#[serde(rename_all = "camelCase")]
42pub struct UserMetadata {
43    /// The date and time the user last signed in.
44    pub last_sign_in_time: Option<String>,
45    /// The date and time the account was created.
46    pub creation_time: Option<String>,
47    /// The date and time the user last refreshed their token.
48    pub last_refresh_time: Option<String>,
49}
50
51/// Information about a user's identity provider.
52#[derive(Debug, Serialize, Deserialize, Default)]
53#[serde(rename_all = "camelCase")]
54pub struct ProviderUserInfo {
55    /// The ID of the identity provider (e.g., google.com).
56    pub provider_id: String,
57    /// The user's display name linked to this provider.
58    pub display_name: Option<String>,
59    /// The user's photo URL linked to this provider.
60    pub photo_url: Option<String>,
61    /// The user's federated ID.
62    pub federated_id: Option<String>,
63    /// The user's email linked to this provider.
64    pub email: Option<String>,
65    /// The user's raw ID.
66    pub raw_id: Option<String>,
67    /// The user's screen name.
68    pub screen_name: Option<String>,
69}
70
71/// Multi-factor authentication information.
72#[derive(Debug, Serialize, Deserialize, Default)]
73#[serde(rename_all = "camelCase")]
74pub struct MfaInfo {
75    /// The MFA enrollment ID.
76    pub mfa_enrollment_id: Option<String>,
77    /// The display name for this MFA method.
78    pub display_name: Option<String>,
79    /// The phone number info for this MFA method.
80    pub phone_info: Option<String>,
81    /// The date and time this MFA method was enrolled.
82    pub enrolled_at: Option<String>,
83}
84
85/// Request to create a new user.
86#[derive(Debug, Serialize, Default)]
87#[serde(rename_all = "camelCase")]
88pub struct CreateUserRequest {
89    /// The UID to assign to the new user. If not provided, one will be generated.
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub local_id: Option<String>,
92    /// The user's email address.
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub email: Option<String>,
95    /// Whether the user's email is verified.
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub email_verified: Option<bool>,
98    /// The user's password.
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub password: Option<String>,
101    /// The user's display name.
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub display_name: Option<String>,
104    /// The user's photo URL.
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub photo_url: Option<String>,
107    /// Whether the user is disabled.
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub disabled: Option<bool>,
110    /// The user's phone number.
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub phone_number: Option<String>,
113}
114
115/// Request to update an existing user.
116#[derive(Debug, Serialize, Default)]
117#[serde(rename_all = "camelCase")]
118pub struct UpdateUserRequest {
119    /// The UID of the user to update.
120    pub local_id: String,
121    /// The new email address.
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub email: Option<String>,
124    /// The new email verification status.
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub email_verified: Option<bool>,
127    /// The new password.
128    #[serde(skip_serializing_if = "Option::is_none")]
129    pub password: Option<String>,
130    /// The new display name.
131    #[serde(skip_serializing_if = "Option::is_none")]
132    pub display_name: Option<String>,
133    /// The new photo URL.
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub photo_url: Option<String>,
136    /// The new disabled status.
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub disabled: Option<bool>,
139    /// The new phone number.
140    #[serde(skip_serializing_if = "Option::is_none")]
141    pub phone_number: Option<String>,
142    /// The new custom claims (JSON string).
143    #[serde(skip_serializing_if = "Option::is_none")]
144    pub custom_attributes: Option<String>,
145    /// Force token expiration (set validSince to now).
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub valid_since: Option<String>,
148    /// List of attributes to delete.
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub delete_attribute: Option<Vec<String>>,
151    /// List of providers to unlink.
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub delete_provider: Option<Vec<String>>,
154}
155
156/// Response from listing users.
157#[derive(Debug, Deserialize)]
158#[serde(rename_all = "camelCase")]
159pub struct ListUsersResponse {
160    /// The list of users.
161    pub users: Option<Vec<UserRecord>>,
162    /// The token for the next page of results.
163    pub next_page_token: Option<String>,
164}
165
166/// Internal request to get account info.
167#[derive(Debug, Serialize)]
168#[serde(rename_all = "camelCase")]
169pub struct GetAccountInfoRequest {
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub local_id: Option<Vec<String>>,
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub email: Option<Vec<String>>,
174    #[serde(skip_serializing_if = "Option::is_none")]
175    pub phone_number: Option<Vec<String>>,
176}
177
178/// Internal response from getting account info.
179#[derive(Debug, Deserialize)]
180#[serde(rename_all = "camelCase")]
181pub struct GetAccountInfoResponse {
182    pub users: Option<Vec<UserRecord>>,
183}
184
185/// Internal request to delete an account.
186#[derive(Debug, Serialize)]
187#[serde(rename_all = "camelCase")]
188pub struct DeleteAccountRequest {
189    pub local_id: String,
190}
191
192/// Internal request for email actions.
193#[derive(Debug, Serialize, Default)]
194#[serde(rename_all = "camelCase")]
195pub struct EmailLinkRequest {
196    pub request_type: String,
197    #[serde(skip_serializing_if = "Option::is_none")]
198    pub email: Option<String>,
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub continue_url: Option<String>,
201    #[serde(skip_serializing_if = "Option::is_none")]
202    pub can_handle_code_in_app: Option<bool>,
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub dynamic_link_domain: Option<String>,
205    #[serde(skip_serializing_if = "Option::is_none")]
206    pub android_package_name: Option<String>,
207    #[serde(skip_serializing_if = "Option::is_none")]
208    pub android_minimum_version: Option<String>,
209    #[serde(skip_serializing_if = "Option::is_none")]
210    pub android_install_app: Option<bool>,
211    #[serde(rename = "iOSBundleId", skip_serializing_if = "Option::is_none")]
212    pub ios_bundle_id: Option<String>,
213}
214
215/// Internal response for email actions.
216#[derive(Debug, Deserialize)]
217#[serde(rename_all = "camelCase")]
218pub struct EmailLinkResponse {
219    pub email: Option<String>,
220    pub oob_link: String,
221}
222
223/// A user record used for bulk import.
224#[derive(Debug, Serialize, Default)]
225#[serde(rename_all = "camelCase")]
226pub struct UserImportRecord {
227    /// The user's UID.
228    pub local_id: String,
229    /// The user's email.
230    #[serde(skip_serializing_if = "Option::is_none")]
231    pub email: Option<String>,
232    /// Whether the user's email is verified.
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub email_verified: Option<bool>,
235    /// The user's password hash.
236    #[serde(skip_serializing_if = "Option::is_none")]
237    pub password_hash: Option<String>,
238    /// The user's password salt.
239    #[serde(skip_serializing_if = "Option::is_none")]
240    pub password_salt: Option<String>,
241    /// The user's display name.
242    #[serde(skip_serializing_if = "Option::is_none")]
243    pub display_name: Option<String>,
244    /// The user's photo URL.
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub photo_url: Option<String>,
247    /// Whether the user is disabled.
248    #[serde(skip_serializing_if = "Option::is_none")]
249    pub disabled: Option<bool>,
250    /// The user's phone number.
251    #[serde(skip_serializing_if = "Option::is_none")]
252    pub phone_number: Option<String>,
253    /// The user's custom claims (JSON string).
254    #[serde(skip_serializing_if = "Option::is_none")]
255    pub custom_attributes: Option<String>,
256}
257
258/// Request to import users in bulk.
259#[derive(Debug, Serialize)]
260#[serde(rename_all = "camelCase")]
261pub struct ImportUsersRequest {
262    /// The list of users to import.
263    pub users: Vec<UserImportRecord>,
264    /// The hashing algorithm used for passwords (if any).
265    #[serde(skip_serializing_if = "Option::is_none")]
266    pub hash: Option<UserImportHash>,
267}
268
269/// Password hashing configuration for user import.
270#[derive(Debug, Serialize)]
271#[serde(rename_all = "camelCase")]
272pub struct UserImportHash {
273    /// The hashing algorithm (e.g., "SCRYPT").
274    pub hash_algorithm: String,
275    /// The signing key (base64 encoded).
276    pub key: String,
277    /// The salt separator (base64 encoded).
278    pub salt_separator: String,
279    /// The number of rounds.
280    pub rounds: i32,
281    /// The memory cost.
282    pub memory_cost: i32,
283}
284
285/// Response from user import.
286#[derive(Debug, Deserialize)]
287#[serde(rename_all = "camelCase")]
288pub struct ImportUsersResponse {
289    /// List of errors encountered during import.
290    pub error: Option<Vec<ImportUserError>>,
291}
292
293/// Error detail for a failed user import.
294#[derive(Debug, Deserialize)]
295#[serde(rename_all = "camelCase")]
296pub struct ImportUserError {
297    /// The index of the user in the request list.
298    pub index: usize,
299    /// The error message.
300    pub message: String,
301}
302
303/// Request to create a session cookie.
304#[derive(Debug, Serialize)]
305#[serde(rename_all = "camelCase")]
306pub struct CreateSessionCookieRequest {
307    /// The ID token to exchange for a session cookie.
308    pub id_token: String,
309    /// The number of seconds until the session cookie expires.
310    #[serde(rename = "validDuration")]
311    pub valid_duration_seconds: u64,
312}
313
314/// Response from creating a session cookie.
315#[derive(Debug, Deserialize)]
316#[serde(rename_all = "camelCase")]
317pub struct CreateSessionCookieResponse {
318    /// The created session cookie.
319    pub session_cookie: String,
320}
321
322// --- Action Code Settings ---
323
324/// Settings for generating email action links.
325#[derive(Debug, Serialize, Deserialize, Default, Clone)]
326#[serde(rename_all = "camelCase")]
327pub struct ActionCodeSettings {
328    /// The URL to continue to after the user clicks the link.
329    pub url: String,
330    /// Whether to open the link via a mobile app if installed.
331    #[serde(skip_serializing_if = "Option::is_none")]
332    pub handle_code_in_app: Option<bool>,
333    /// iOS specific settings.
334    #[serde(rename = "iOS", skip_serializing_if = "Option::is_none")]
335    pub ios: Option<IosSettings>,
336    /// Android specific settings.
337    #[serde(skip_serializing_if = "Option::is_none")]
338    pub android: Option<AndroidSettings>,
339    /// The dynamic link domain to use.
340    #[serde(skip_serializing_if = "Option::is_none")]
341    pub dynamic_link_domain: Option<String>,
342}
343
344/// iOS specific settings for action code.
345#[derive(Debug, Serialize, Deserialize, Default, Clone)]
346#[serde(rename_all = "camelCase")]
347pub struct IosSettings {
348    /// The iOS bundle ID.
349    pub bundle_id: String,
350}
351
352/// Android specific settings for action code.
353#[derive(Debug, Serialize, Deserialize, Default, Clone)]
354#[serde(rename_all = "camelCase")]
355pub struct AndroidSettings {
356    /// The Android package name.
357    pub package_name: String,
358    /// Whether to install the app if not already installed.
359    #[serde(skip_serializing_if = "Option::is_none")]
360    pub install_app: Option<bool>,
361    /// The minimum version of the app required.
362    #[serde(skip_serializing_if = "Option::is_none")]
363    pub minimum_version: Option<String>,
364}