@dereekb/firebase-server 13.2.0 → 13.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,17 @@ import { type Milliseconds, type AuthClaims, type AuthRoleSet, type ArrayOrValue
4
4
  import { type CallableContextWithAuthData } from '../function/context';
5
5
  import { type AuthDataRef } from './auth.context';
6
6
  import { type CallableContext } from '../type';
7
+ /**
8
+ * Generates a random 6-digit number for use as a temporary password or reset token.
9
+ *
10
+ * Used internally by {@link AbstractFirebaseServerAuthUserContext.beginResetPassword} and
11
+ * {@link AbstractFirebaseServerNewUserService.generateRandomSetupPassword} for one-time codes.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const pin = DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR(); // e.g. 482910
16
+ * ```
17
+ */
7
18
  export declare const DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR: import("@dereekb/util").NumberFactory;
8
19
  export interface FirebaseServerAuthUserIdentifierContext {
9
20
  /**
@@ -11,84 +22,142 @@ export interface FirebaseServerAuthUserIdentifierContext {
11
22
  */
12
23
  readonly uid: FirebaseAuthUserId;
13
24
  }
25
+ /**
26
+ * Custom claims stored on a user during a password reset flow.
27
+ *
28
+ * Contains the temporary reset password and the timestamp of when the reset was initiated.
29
+ */
14
30
  export interface FirebaseServerAuthResetUserPasswordClaims extends FirebaseAuthResetUserPasswordClaimsData, AuthClaimsObject {
15
31
  }
32
+ /**
33
+ * Provides operations for managing a single Firebase Auth user's record, claims, roles, and password.
34
+ *
35
+ * Acts as a scoped context bound to a specific user UID, enabling direct manipulation of that user's
36
+ * authentication state without requiring the caller to repeatedly pass the UID.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const userCtx = authService.userContext(uid);
41
+ * const exists = await userCtx.exists();
42
+ * const roles = await userCtx.loadRoles();
43
+ * await userCtx.addRoles(AUTH_ADMIN_ROLE);
44
+ * ```
45
+ */
16
46
  export interface FirebaseServerAuthUserContext extends FirebaseServerAuthUserIdentifierContext {
17
47
  /**
18
- * Returns true if the user exists.
48
+ * Checks whether the user exists in Firebase Auth.
19
49
  */
20
50
  exists(): Promise<boolean>;
21
51
  /**
22
- * Loads the record of the user.
52
+ * Loads the full Firebase Auth {@link admin.auth.UserRecord} for this user.
53
+ *
54
+ * @throws Throws if the user does not exist.
23
55
  */
24
56
  loadRecord(): Promise<admin.auth.UserRecord>;
25
57
  /**
26
- * Loads the details object of the user.
58
+ * Loads a normalized {@link FirebaseAuthDetails} snapshot of the user's auth profile.
59
+ *
60
+ * @throws Throws if the user does not exist.
27
61
  */
28
62
  loadDetails(): Promise<FirebaseAuthDetails>;
29
63
  /**
30
- * Generates a random reset token and updates the user's password to start a password reset flow.
64
+ * Initiates a password reset flow by generating a random temporary password,
65
+ * storing reset claims on the user, and updating the user's password.
66
+ *
67
+ * The returned claims contain the generated password and a timestamp, which can be
68
+ * communicated to the user through an external channel (e.g., email).
31
69
  */
32
70
  beginResetPassword(): Promise<FirebaseServerAuthResetUserPasswordClaims>;
33
71
  /**
34
- * Returns the reset password claims if it exists.
72
+ * Loads the reset password claims if a password reset is currently active.
73
+ *
74
+ * @returns The reset claims, or `undefined` if no reset is in progress.
35
75
  */
36
76
  loadResetPasswordClaims<T extends FirebaseServerAuthResetUserPasswordClaims = FirebaseServerAuthResetUserPasswordClaims>(): Promise<Maybe<T>>;
37
77
  /**
38
- * Changes the user's password. Will also clear any claims data related to resetting a password.
78
+ * Updates the user's password and clears any active password reset claims.
79
+ *
80
+ * Intended to be called after the user has verified their identity with a reset token.
81
+ *
82
+ * @param password - The new password to set.
39
83
  */
40
84
  setPassword(password: PasswordString): Promise<admin.auth.UserRecord>;
41
85
  /**
42
- * Updates a user's information.
86
+ * Applies an arbitrary update to the user's Firebase Auth record.
87
+ *
88
+ * @param template - The update fields to apply.
43
89
  */
44
90
  updateUser(template: admin.auth.UpdateRequest): Promise<admin.auth.UserRecord>;
45
91
  /**
46
- * Loads the roles of the user.
92
+ * Loads the user's current {@link AuthRoleSet} by reading and converting their custom claims.
47
93
  */
48
94
  loadRoles(): Promise<AuthRoleSet>;
49
95
  /**
50
- * Adds the given roles to the user.
96
+ * Merges the given roles into the user's existing roles via claim updates.
51
97
  *
52
- * @param roles
98
+ * Does not affect roles not associated with the given input.
99
+ *
100
+ * @param roles - One or more roles to add.
53
101
  */
54
102
  addRoles(roles: ArrayOrValue<AuthRole>): Promise<void>;
55
103
  /**
56
- * Removes the given roles from the user.
104
+ * Removes the given roles from the user by nullifying their corresponding claims.
105
+ *
106
+ * Does not affect claims belonging to other roles.
57
107
  *
58
- * @param roles
108
+ * @param roles - One or more roles to remove.
59
109
  */
60
110
  removeRoles(roles: ArrayOrValue<AuthRole>): Promise<void>;
61
111
  /**
62
- * Sets all the roles for the user.
112
+ * Replaces all of the user's role-based claims with those derived from the given roles.
63
113
  *
64
- * @param roles
114
+ * All previous claims are cleared before the new role claims are applied.
115
+ *
116
+ * @param roles - The complete set of roles the user should have.
65
117
  */
66
118
  setRoles(roles: AuthRole[] | AuthRoleSet): Promise<void>;
67
119
  /**
68
- * Loads the claims from the user.
120
+ * Loads the user's raw custom claims object from their Firebase Auth record.
121
+ *
122
+ * @throws Throws if the user does not exist.
69
123
  */
70
124
  loadClaims<T extends AuthClaimsObject = AuthClaimsObject>(): Promise<AuthClaims<T>>;
71
125
  /**
72
- * Updates the claims for a user by merging existing claims in with the input.
126
+ * Merges the input claims into the user's existing custom claims.
73
127
  *
74
- * All null values are cleared from the existing claims. Undefined values are ignored.
128
+ * - Keys with `null` values are removed from the resulting claims.
129
+ * - Keys with `undefined` values are ignored (existing values are preserved).
75
130
  *
76
- * @param claims
131
+ * @param claims - Partial claims to merge. Use `null` to delete a key.
77
132
  */
78
133
  updateClaims<T extends AuthClaimsObject = AuthClaimsObject>(claims: AuthClaimsUpdate<T>): Promise<void>;
79
134
  /**
80
- * Sets the claims for a user. All previous claims are cleared.
135
+ * Replaces the user's entire custom claims object. All previous claims are discarded.
81
136
  *
82
- * @param claims
137
+ * @param claims - The new claims to set.
83
138
  */
84
139
  setClaims<T extends AuthClaimsObject = AuthClaimsObject>(claims: AuthClaimsUpdate<T>): Promise<void>;
85
140
  /**
86
- * Clears all claims for the user.
87
- *
88
- * @param claims
141
+ * Removes all custom claims from the user.
89
142
  */
90
143
  clearClaims(): Promise<void>;
91
144
  }
145
+ /**
146
+ * Base implementation of {@link FirebaseServerAuthUserContext} that manages a single user's
147
+ * auth state (record, claims, roles, password) through the Firebase Admin Auth API.
148
+ *
149
+ * Caches the user record on first load and resets the cache automatically when claims are modified
150
+ * via {@link setClaims}. Subclass this to bind it to a specific {@link FirebaseServerAuthService} type.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * export class MyAuthUserContext extends AbstractFirebaseServerAuthUserContext<MyAuthService> {}
155
+ *
156
+ * const ctx = new MyAuthUserContext(authService, 'some-uid');
157
+ * const roles = await ctx.loadRoles();
158
+ * await ctx.addRoles(AUTH_ADMIN_ROLE);
159
+ * ```
160
+ */
92
161
  export declare abstract class AbstractFirebaseServerAuthUserContext<S extends FirebaseServerAuthService> implements FirebaseServerAuthUserContext {
93
162
  private readonly _service;
94
163
  private readonly _uid;
@@ -99,29 +168,37 @@ export declare abstract class AbstractFirebaseServerAuthUserContext<S extends Fi
99
168
  exists(): Promise<boolean>;
100
169
  loadRecord(): Promise<admin.auth.UserRecord>;
101
170
  loadDetails(): Promise<FirebaseAuthDetails>;
171
+ /**
172
+ * Generates a random numeric string for use as a temporary reset password.
173
+ */
102
174
  protected _generateResetPasswordKey(): string;
103
175
  beginResetPassword(): Promise<FirebaseServerAuthResetUserPasswordClaims>;
104
176
  loadResetPasswordClaims<T extends FirebaseServerAuthResetUserPasswordClaims = FirebaseServerAuthResetUserPasswordClaims>(): Promise<Maybe<T>>;
105
- /**
106
- * Sets the user's password.
107
- */
108
177
  setPassword(password: PasswordString): Promise<admin.auth.UserRecord>;
109
178
  updateUser(template: admin.auth.UpdateRequest): Promise<admin.auth.UserRecord>;
110
179
  loadRoles(): Promise<AuthRoleSet>;
111
180
  addRoles(roles: ArrayOrValue<AuthRole>): Promise<void>;
112
181
  removeRoles(roles: ArrayOrValue<AuthRole>): Promise<void>;
113
182
  /**
114
- * Sets the claims using the input roles and roles set.
183
+ * Replaces all role-based claims with those derived from the given roles.
115
184
  *
116
- * All other claims are cleared.
185
+ * All existing claims are cleared first. Use `claimsToRetain` to preserve non-role claims
186
+ * (e.g., setup or application-specific claims) through the replacement.
117
187
  *
118
- * Use the claimsToRetain input to retain other claims that are outside of the roles.
188
+ * @param roles - The complete set of roles to assign.
189
+ * @param claimsToRetain - Additional claims to merge in alongside the role-derived claims.
119
190
  *
120
- * @param roles
121
- * @param claimsToRetain
122
- * @returns
191
+ * @example
192
+ * ```typescript
193
+ * // Set roles while preserving a custom claim
194
+ * await userCtx.setRoles([AUTH_ADMIN_ROLE], { customFlag: 1 });
195
+ * ```
123
196
  */
124
197
  setRoles<T extends AuthClaimsObject = AuthClaimsObject>(roles: AuthRole[] | AuthRoleSet, claimsToRetain?: Partial<T>): Promise<void>;
198
+ /**
199
+ * Converts roles to their corresponding claim keys, filtering out null/undefined entries
200
+ * that represent unrelated claims in the service's {@link FirebaseServerAuthService.claimsForRoles} output.
201
+ */
125
202
  protected _claimsForRolesChange(roles: ArrayOrValue<AuthRole>): Partial<{
126
203
  [x: string]: import("@dereekb/util").AuthClaimValue | null;
127
204
  [x: number]: null;
@@ -132,36 +209,61 @@ export declare abstract class AbstractFirebaseServerAuthUserContext<S extends Fi
132
209
  clearClaims(): Promise<void>;
133
210
  setClaims<T extends AuthClaimsObject = AuthClaimsObject>(claims: AuthClaimsUpdate<T> | null): Promise<void>;
134
211
  }
212
+ /**
213
+ * Read-only auth context derived from a Firebase callable function request.
214
+ *
215
+ * Provides access to the caller's identity, decoded token, roles, and admin/ToS status
216
+ * without requiring additional async lookups. Created by {@link FirebaseServerAuthService.context}
217
+ * after asserting that the request contains valid auth data.
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * const authCtx = authService.context(callableContext);
222
+ * if (authCtx.isAdmin) {
223
+ * // handle admin-only logic
224
+ * }
225
+ * const roles = authCtx.authRoles;
226
+ * ```
227
+ */
135
228
  export interface FirebaseServerAuthContext<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext> extends FirebaseServerAuthUserIdentifierContext {
136
229
  /**
137
- * The wrapped context.
230
+ * The original callable function context containing the authenticated request data.
138
231
  */
139
232
  readonly context: CallableContextWithAuthData;
140
233
  /**
141
- * Returns the user context for this type.
234
+ * A {@link FirebaseServerAuthUserContext} for performing mutations on this user's auth record.
142
235
  */
143
236
  readonly userContext: U;
144
237
  /**
145
- * Whether or not the context sees the user as an admin of the system.
238
+ * Whether the caller has the {@link AUTH_ADMIN_ROLE} based on their token claims.
146
239
  */
147
240
  readonly isAdmin: boolean;
148
241
  /**
149
- * Whether or not the context sees the user as having signed the terms of service.
242
+ * Whether the caller has signed the terms of service based on their token claims.
150
243
  */
151
244
  readonly hasSignedTos: boolean;
152
245
  /**
153
- * The auth roles provided by the token in this context.
246
+ * The full set of auth roles derived from the caller's token claims.
154
247
  */
155
248
  readonly authRoles: AuthRoleSet;
156
249
  /**
157
- * The token in the context.
250
+ * The decoded ID token from the request.
158
251
  */
159
252
  readonly token: admin.auth.DecodedIdToken;
160
253
  /**
161
- * The claims in the context.
254
+ * The raw custom claims from the decoded ID token.
162
255
  */
163
256
  readonly claims: AuthClaims;
164
257
  }
258
+ /**
259
+ * Base implementation of {@link FirebaseServerAuthContext} with cached getters for roles, admin status,
260
+ * and ToS status to avoid redundant computation within a single request.
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * export class MyAuthContext extends AbstractFirebaseServerAuthContext<MyAuthContext, MyUserContext, MyAuthService> {}
265
+ * ```
266
+ */
165
267
  export declare abstract class AbstractFirebaseServerAuthContext<C extends FirebaseServerAuthContext, U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext, S extends FirebaseServerAuthService<U, C> = FirebaseServerAuthService<U, C>> implements FirebaseServerAuthContext {
166
268
  private readonly _service;
167
269
  private readonly _context;
@@ -180,8 +282,27 @@ export declare abstract class AbstractFirebaseServerAuthContext<C extends Fireba
180
282
  get claims(): AuthClaims;
181
283
  get uid(): string;
182
284
  }
285
+ /**
286
+ * Custom claims stored on a user during account setup, containing the setup password
287
+ * and the last communication timestamp.
288
+ */
183
289
  export interface FirebaseServerAuthNewUserClaims extends FirebaseAuthNewUserClaimsData, AuthClaimsObject {
184
290
  }
291
+ /**
292
+ * Configuration for creating and initializing a new Firebase Auth user.
293
+ *
294
+ * Supports creating users by email or phone, assigning a temporary setup password,
295
+ * and optionally sending setup content (e.g., an invitation email) immediately after creation.
296
+ *
297
+ * @example
298
+ * ```typescript
299
+ * await newUserService.initializeNewUser({
300
+ * email: 'user@example.com',
301
+ * sendSetupContent: true,
302
+ * sendSetupThrowErrors: true
303
+ * });
304
+ * ```
305
+ */
185
306
  export interface FirebaseServerAuthInitializeNewUser<D = unknown> {
186
307
  /**
187
308
  * Specific user identifier to use.
@@ -200,9 +321,9 @@ export interface FirebaseServerAuthInitializeNewUser<D = unknown> {
200
321
  */
201
322
  readonly phone?: E164PhoneNumber;
202
323
  /**
203
- * Password to set on the user if not created yet.
324
+ * Temporary setup password assigned during account creation.
204
325
  *
205
- * This is a setup password and should not be the user's permenant/final password.
326
+ * This is not the user's permanent password; it is replaced when the user completes setup.
206
327
  */
207
328
  readonly setupPassword?: FirebaseAuthSetupPassword;
208
329
  /**
@@ -234,10 +355,18 @@ export interface FirebaseServerAuthInitializeNewUser<D = unknown> {
234
355
  */
235
356
  readonly data?: D;
236
357
  }
358
+ /**
359
+ * Result of creating a new Firebase Auth user, including the generated temporary setup password.
360
+ */
237
361
  export interface FirebaseServerAuthCreateNewUserResult {
238
362
  readonly user: admin.auth.UserRecord;
239
363
  readonly password: FirebaseAuthSetupPassword;
240
364
  }
365
+ /**
366
+ * Configuration options for sending setup content (e.g., invitation emails) to a new user.
367
+ *
368
+ * Controls throttling, send-once behavior, and error handling for the delivery process.
369
+ */
241
370
  export interface FirebaseServerAuthNewUserSendSetupDetailsConfig<D = unknown> {
242
371
  /**
243
372
  * Whether or not to force sending the test details. Usage differs between providers.
@@ -263,49 +392,133 @@ export interface FirebaseServerAuthNewUserSendSetupDetailsConfig<D = unknown> {
263
392
  */
264
393
  readonly data?: D;
265
394
  }
395
+ /**
396
+ * Details about a user that is in the setup phase, including their user context,
397
+ * setup claims data, and the send configuration that was used.
398
+ */
266
399
  export interface FirebaseServerAuthNewUserSetupDetails<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext, D = unknown> extends FirebaseServerAuthNewUserSendSetupDetailsConfig<D> {
267
400
  readonly userContext: U;
268
401
  readonly claims: FirebaseAuthNewUserClaimsData;
269
402
  }
403
+ /**
404
+ * Service for programmatically creating new Firebase Auth users and managing their setup lifecycle.
405
+ *
406
+ * Handles user creation, setup password assignment, setup content delivery (with throttling),
407
+ * and marking user setup as complete by clearing setup-related claims.
408
+ *
409
+ * @example
410
+ * ```typescript
411
+ * const newUserSvc = authService.newUser();
412
+ * const record = await newUserSvc.initializeNewUser({ email: 'user@example.com', sendSetupContent: true });
413
+ * // Later, after the user completes onboarding:
414
+ * await newUserSvc.markUserSetupAsComplete(record.uid);
415
+ * ```
416
+ */
270
417
  export interface FirebaseServerNewUserService<D = unknown, U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext> {
418
+ /**
419
+ * Creates a new user (or finds an existing one) and optionally sends setup content.
420
+ *
421
+ * If the user already exists, no new account is created. Setup content is only sent
422
+ * when explicitly requested via the input flags.
423
+ *
424
+ * @param input - Configuration for the new user and setup content delivery.
425
+ * @throws Throws if neither email, phone, nor uid is provided.
426
+ */
271
427
  initializeNewUser(input: FirebaseServerAuthInitializeNewUser<D>): Promise<admin.auth.UserRecord>;
272
428
  /**
273
- * Adds setup claims to a user.
429
+ * Writes the setup password claim to the user's custom claims.
274
430
  *
275
- * @param userContextOrUid
276
- * @param setupPassword
431
+ * If no password is provided, a random one is generated.
432
+ *
433
+ * @param userContextOrUid - The user to update, as a context or UID string.
434
+ * @param setupPassword - Optional explicit setup password; auto-generated if omitted.
277
435
  */
278
436
  addNewUserSetupClaims(userContextOrUid: U | FirebaseAuthUserId, setupPassword?: FirebaseAuthSetupPassword): Promise<U>;
279
437
  /**
280
- * Sends the setup content to the user. Returns true if content was sent or was already recently sent.
438
+ * Sends setup content (e.g., an invitation email) to the user.
439
+ *
440
+ * Respects throttling and send-once constraints from the config. Returns `true` if
441
+ * content was actually sent, `false` if skipped due to throttling or send-once rules.
281
442
  *
282
- * @param uid
443
+ * @param uid - The target user's UID.
444
+ * @param data - Optional delivery configuration.
445
+ * @throws {FirebaseServerAuthNewUserSendSetupDetailsThrottleError} When throttled and `throwErrors` is true.
446
+ * @throws {FirebaseServerAuthNewUserSendSetupDetailsSendOnceError} When already sent and `sendSetupDetailsOnce` + `throwErrors` are true.
447
+ * @throws {FirebaseServerAuthNewUserSendSetupDetailsNoSetupConfigError} When no setup claims exist and `throwErrors` is true.
283
448
  */
284
449
  sendSetupContent(uid: FirebaseAuthUserId, data?: FirebaseServerAuthNewUserSendSetupDetailsConfig<D>): Promise<boolean>;
285
450
  /**
286
- * Loads the setup details for the user. If the user does not exist or does not need to be setup then undefined is returned.
451
+ * Loads the setup details for the user if they are in the setup phase.
287
452
  *
288
- * @param uid
289
- * @param config
453
+ * @param uid - The target user's UID.
454
+ * @param config - Optional config to forward to the details.
455
+ * @returns The setup details, or `undefined` if the user does not exist or has no setup claims.
290
456
  */
291
457
  loadSetupDetails(uid: FirebaseAuthUserId, config?: FirebaseServerAuthNewUserSendSetupDetailsConfig<D>): Promise<Maybe<FirebaseServerAuthNewUserSetupDetails<U, D>>>;
292
458
  /**
293
- * Loads the setup details for the input user context. If the user does not exist or does not need to be setup then undefined is returned.
459
+ * Loads the setup details for a user context that is already resolved.
294
460
  *
295
- * @param uid
296
- * @param config
461
+ * @param userContext - The resolved user context.
462
+ * @param config - Optional config to forward to the details.
463
+ * @returns The setup details, or `undefined` if the user has no setup claims.
297
464
  */
298
465
  loadSetupDetailsForUserContext(userContext: U, config?: FirebaseServerAuthNewUserSendSetupDetailsConfig<D>): Promise<Maybe<FirebaseServerAuthNewUserSetupDetails<U, D>>>;
466
+ /**
467
+ * Clears all setup-related claims from the user, marking their setup as complete.
468
+ *
469
+ * @param uid - The target user's UID.
470
+ * @returns `true` if the user existed and was updated, `false` if the user was not found.
471
+ */
299
472
  markUserSetupAsComplete(uid: FirebaseAuthUserId): Promise<boolean>;
300
473
  }
301
474
  /**
302
- * 1 hour
475
+ * Default throttle duration (1 hour) between setup content sends to prevent spam.
476
+ *
477
+ * Used by {@link AbstractFirebaseServerNewUserService.sendSetupContent} to rate-limit delivery.
303
478
  */
304
479
  export declare const DEFAULT_SETUP_COM_THROTTLE_TIME: number;
480
+ /**
481
+ * A user context instance or a raw UID string that can be resolved to one.
482
+ */
305
483
  export type UserContextOrUid<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext> = U | FirebaseAuthUserId;
484
+ /**
485
+ * Resolves a {@link UserContextOrUid} to a concrete user context instance.
486
+ *
487
+ * If a string UID is provided, creates a new user context via the auth service.
488
+ * If an existing context is provided, returns it as-is.
489
+ *
490
+ * @param authService - The auth service to create a context from if needed.
491
+ * @param userContextOrUid - A user context or UID string.
492
+ *
493
+ * @example
494
+ * ```typescript
495
+ * const ctx = userContextFromUid(authService, 'some-uid');
496
+ * const sameCtx = userContextFromUid(authService, ctx); // returns ctx unchanged
497
+ * ```
498
+ */
306
499
  export declare function userContextFromUid<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext>(authService: FirebaseServerAuthService<U>, userContextOrUid: UserContextOrUid<U>): U;
500
+ /**
501
+ * Base implementation of {@link FirebaseServerNewUserService} that handles user creation,
502
+ * setup claims management, throttled setup content delivery, and setup completion.
503
+ *
504
+ * Subclasses must implement {@link sendSetupContentToUser} to define how setup content
505
+ * (e.g., invitation email, SMS) is delivered to the user.
506
+ *
507
+ * @example
508
+ * ```typescript
509
+ * export class MyNewUserService extends AbstractFirebaseServerNewUserService<MyUserContext> {
510
+ * protected async sendSetupContentToUser(details: FirebaseServerAuthNewUserSetupDetails<MyUserContext>): Promise<void> {
511
+ * await this.emailService.sendInvite(details.userContext.uid, details.claims.setupPassword);
512
+ * }
513
+ * }
514
+ * ```
515
+ */
307
516
  export declare abstract class AbstractFirebaseServerNewUserService<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext, C extends FirebaseServerAuthContext = FirebaseServerAuthContext, D = unknown> implements FirebaseServerNewUserService<D, U> {
308
517
  private readonly _authService;
518
+ /**
519
+ * Minimum time between setup content sends. Defaults to {@link DEFAULT_SETUP_COM_THROTTLE_TIME} (1 hour).
520
+ * Override in subclasses to customize the throttle window.
521
+ */
309
522
  protected setupThrottleTime: Milliseconds;
310
523
  constructor(authService: FirebaseServerAuthService<U, C>);
311
524
  get authService(): FirebaseServerAuthService<U, C>;
@@ -314,22 +527,40 @@ export declare abstract class AbstractFirebaseServerNewUserService<U extends Fir
314
527
  sendSetupContent(userContextOrUid: U | FirebaseAuthUserId, config?: FirebaseServerAuthNewUserSendSetupDetailsConfig<D>): Promise<boolean>;
315
528
  loadSetupDetails(userContextOrUid: U | FirebaseAuthUserId, config?: FirebaseServerAuthNewUserSendSetupDetailsConfig<D>): Promise<Maybe<FirebaseServerAuthNewUserSetupDetails<U, D>>>;
316
529
  loadSetupDetailsForUserContext(userContext: U, config?: FirebaseServerAuthNewUserSendSetupDetailsConfig<D>): Promise<Maybe<FirebaseServerAuthNewUserSetupDetails<U, D>>>;
530
+ /**
531
+ * Records the current timestamp as the last setup content communication date in the user's claims.
532
+ */
317
533
  protected updateSetupContentSentTime(details: FirebaseServerAuthNewUserSetupDetails<U, D>): Promise<void>;
534
+ markUserSetupAsComplete(uid: FirebaseAuthUserId): Promise<boolean>;
318
535
  /**
319
- * Update a user's claims to clear any setup-related content.
536
+ * Creates a new Firebase Auth user from the initialization input.
320
537
  *
321
- * Returns true if a user was updated.
538
+ * Generates a random setup password if none is provided. Override to customize user creation behavior.
322
539
  *
323
- * @param uid
540
+ * @throws Throws if the Firebase Admin SDK rejects the user creation.
324
541
  */
325
- markUserSetupAsComplete(uid: FirebaseAuthUserId): Promise<boolean>;
326
542
  protected createNewUser(input: FirebaseServerAuthInitializeNewUser<D>): Promise<FirebaseServerAuthCreateNewUserResult>;
327
543
  protected generateRandomSetupPassword(): FirebaseAuthSetupPassword;
328
- protected abstract sendSetupContentToUser(user: FirebaseServerAuthNewUserSetupDetails<U, D>): Promise<void>;
544
+ /**
545
+ * Delivers setup content (e.g., invitation email, SMS) to the user.
546
+ *
547
+ * Subclasses must implement this to define the actual delivery mechanism.
548
+ *
549
+ * @param details - The user's setup details, including their context and setup claims.
550
+ */
551
+ protected abstract sendSetupContentToUser(details: FirebaseServerAuthNewUserSetupDetails<U, D>): Promise<void>;
552
+ /**
553
+ * Clears setup-related claims (setup password and last communication date) from the user.
554
+ */
329
555
  protected updateClaimsToClearUser(userContext: U): Promise<void>;
330
556
  }
557
+ /**
558
+ * No-op implementation of {@link AbstractFirebaseServerNewUserService} that skips sending setup content.
559
+ *
560
+ * Used as the default {@link FirebaseServerNewUserService} when no custom delivery mechanism is configured.
561
+ */
331
562
  export declare class NoSetupContentFirebaseServerNewUserService<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext> extends AbstractFirebaseServerNewUserService<U> {
332
- protected sendSetupContentToUser(user: FirebaseServerAuthNewUserSetupDetails<U>): Promise<void>;
563
+ protected sendSetupContentToUser(_details: FirebaseServerAuthNewUserSetupDetails<U>): Promise<void>;
333
564
  }
334
565
  /**
335
566
  * Reference to a FirebaseServerAuthService
@@ -338,82 +569,136 @@ export interface FirebaseServerAuthServiceRef<S extends FirebaseServerAuthServic
338
569
  readonly authService: S;
339
570
  }
340
571
  /**
341
- * FirebaseServer auth service that provides accessors to auth-related components.
572
+ * Abstract contract for a Firebase Server authentication service.
573
+ *
574
+ * Provides the core API for creating auth contexts from callable requests, managing user contexts,
575
+ * checking admin/ToS status, converting between roles and claims, and creating new users.
576
+ *
577
+ * Implement this by extending {@link AbstractFirebaseServerAuthService}, which provides default
578
+ * implementations for most methods and only requires `readRoles`, `claimsForRoles`,
579
+ * `userContext`, and `_context` to be defined.
580
+ *
581
+ * @example
582
+ * ```typescript
583
+ * class MyAuthService extends AbstractFirebaseServerAuthService<MyUserContext, MyAuthContext> {
584
+ * readRoles(claims: AuthClaims): AuthRoleSet { ... }
585
+ * claimsForRoles(roles: AuthRoleSet): AuthClaimsUpdate { ... }
586
+ * userContext(uid: string): MyUserContext { ... }
587
+ * protected _context(ctx: CallableContextWithAuthData): MyAuthContext { ... }
588
+ * }
589
+ * ```
342
590
  */
343
591
  export declare abstract class FirebaseServerAuthService<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext, C extends FirebaseServerAuthContext = FirebaseServerAuthContext> {
592
+ /**
593
+ * The underlying Firebase Admin Auth instance.
594
+ */
344
595
  abstract readonly auth: admin.auth.Auth;
345
596
  /**
346
- * Creates a context with the input CallableContext. This creation also asserts that a uid is available to the request.
597
+ * Creates a {@link FirebaseServerAuthContext} from a callable function request.
347
598
  *
348
- * If the input context is not a CallableContextWithAuthData, an exception is thrown.
599
+ * Asserts that the request contains valid auth data (a UID is present).
349
600
  *
350
- * @param context
601
+ * @param context - The callable function context from a Firebase function invocation.
602
+ * @throws Throws if the context does not contain authenticated user data.
351
603
  */
352
604
  abstract context(context: CallableContext): C;
353
605
  /**
354
- * Creates a FirebaseServerAuthUserContext instance for the input uid.
606
+ * Creates a {@link FirebaseServerAuthUserContext} for direct user manipulation.
355
607
  *
356
- * The user's existence is not checked.
608
+ * Does not verify that the user exists; existence should be checked separately if needed.
357
609
  *
358
- * @param uid
610
+ * @param uid - The Firebase Auth UID of the target user.
359
611
  */
360
612
  abstract userContext(uid: FirebaseAuthUserId): U;
361
613
  /**
362
- * Whether or not the input claims indicate admin priviledges.
614
+ * Determines whether the given claims indicate admin privileges by converting
615
+ * claims to roles and checking for {@link AUTH_ADMIN_ROLE}.
363
616
  *
364
- * @param claims
617
+ * @param claims - The user's custom claims.
365
618
  */
366
619
  abstract isAdmin(claims: AuthClaims): boolean;
367
620
  /**
368
- * Whether or not the input claims indiciate the user has signed the ToS.
621
+ * Determines whether the given claims indicate the user has signed the Terms of Service
622
+ * by converting claims to roles and checking for {@link AUTH_TOS_SIGNED_ROLE}.
369
623
  *
370
- * @param claims
624
+ * @param claims - The user's custom claims.
371
625
  */
372
626
  abstract hasSignedTos(claims: AuthClaims): boolean;
373
627
  /**
374
- * Whether or not the input roles indicate admin priviledges.
628
+ * Checks whether the given role set includes the {@link AUTH_ADMIN_ROLE}.
375
629
  *
376
- * @param roles
630
+ * @param roles - The pre-computed role set to check.
377
631
  */
378
632
  abstract isAdminInRoles(roles: AuthRoleSet): boolean;
379
633
  /**
380
- * Whether or not the input roles indiciate the user has signed the ToS.
634
+ * Checks whether the given role set includes the {@link AUTH_TOS_SIGNED_ROLE}.
381
635
  *
382
- * @param claims
636
+ * @param roles - The pre-computed role set to check.
383
637
  */
384
638
  abstract hasSignedTosInRoles(roles: AuthRoleSet): boolean;
385
639
  /**
386
- * Reads the AuthRoleSet from the input claims.
640
+ * Converts raw custom claims into the application's {@link AuthRoleSet}.
387
641
  *
388
- * @param claims
642
+ * This is the inverse of {@link claimsForRoles} and defines the claims-to-roles mapping.
643
+ *
644
+ * @param claims - The user's custom claims.
389
645
  */
390
646
  abstract readRoles(claims: AuthClaims): AuthRoleSet;
391
647
  /**
392
- * Creates the claims that reflect the input roles.
648
+ * Converts an {@link AuthRoleSet} into the corresponding claims update object.
393
649
  *
394
- * The resultant claims value should include ALL claim values, with those that are unset to be null.
650
+ * The result should include ALL known claim keys, with unset claims set to `null`
651
+ * so they can be cleared from the user's custom claims.
395
652
  *
396
- * @param roles
653
+ * @param roles - The roles to convert to claims.
397
654
  */
398
655
  abstract claimsForRoles(roles: AuthRoleSet): AuthClaimsUpdate;
399
656
  /**
400
- * Builds a FirebaseAuthContextInfo for the input auth data context.
657
+ * Builds a {@link FirebaseAuthContextInfo} from an auth data reference, providing
658
+ * lazy accessors for roles, admin status, and claims.
401
659
  *
402
- * @param context
660
+ * @param context - A reference containing auth data (e.g., from a request).
661
+ * @returns The context info, or `undefined` if no auth data is present.
403
662
  */
404
663
  abstract authContextInfo(context: AuthDataRef): Maybe<FirebaseAuthContextInfo>;
405
664
  /**
406
- * Returns the new user service to create a new user programmatically.
665
+ * Returns a {@link FirebaseServerNewUserService} for programmatic user creation and setup management.
407
666
  */
408
667
  abstract newUser(): FirebaseServerNewUserService;
409
668
  /**
410
- * Returns the auth details for the given UserRecord.
411
- * @param record
669
+ * Converts a Firebase Admin {@link admin.auth.UserRecord} into a normalized {@link FirebaseAuthDetails} object.
670
+ *
671
+ * @param record - The user record to convert.
412
672
  */
413
673
  abstract authDetailsForRecord(record: admin.auth.UserRecord): FirebaseAuthDetails;
414
674
  }
415
675
  /**
416
- * Abstract FirebaseServerAuthService implementation.
676
+ * Base implementation of {@link FirebaseServerAuthService} providing standard admin/ToS checks,
677
+ * auth context creation with assertion, and a default no-op new user service.
678
+ *
679
+ * Subclasses must implement:
680
+ * - {@link _context} - to create the concrete auth context type.
681
+ * - {@link userContext} - to create the concrete user context type.
682
+ * - {@link readRoles} - to define the claims-to-roles mapping.
683
+ * - {@link claimsForRoles} - to define the roles-to-claims mapping.
684
+ *
685
+ * @example
686
+ * ```typescript
687
+ * export class MyAuthService extends AbstractFirebaseServerAuthService<MyUserContext, MyAuthContext> {
688
+ * protected _context(context: CallableContextWithAuthData): MyAuthContext {
689
+ * return new MyAuthContext(this, context);
690
+ * }
691
+ * userContext(uid: string): MyUserContext {
692
+ * return new MyUserContext(this, uid);
693
+ * }
694
+ * readRoles(claims: AuthClaims): AuthRoleSet {
695
+ * return MY_CLAIMS_SERVICE.toRoles(claims);
696
+ * }
697
+ * claimsForRoles(roles: AuthRoleSet): AuthClaimsUpdate {
698
+ * return MY_CLAIMS_SERVICE.toClaims(roles);
699
+ * }
700
+ * }
701
+ * ```
417
702
  */
418
703
  export declare abstract class AbstractFirebaseServerAuthService<U extends FirebaseServerAuthUserContext = FirebaseServerAuthUserContext, C extends FirebaseServerAuthContext<U> = FirebaseServerAuthContext<U>> implements FirebaseServerAuthService<U, C> {
419
704
  private readonly _auth;