UNPKG

46.5 kBJavaScriptView Raw
1/*! firebase-admin v10.0.0 */
2"use strict";
3/*!
4 * Copyright 2021 Google Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18Object.defineProperty(exports, "__esModule", { value: true });
19exports.BaseAuth = exports.createFirebaseTokenGenerator = void 0;
20var error_1 = require("../utils/error");
21var deep_copy_1 = require("../utils/deep-copy");
22var validator = require("../utils/validator");
23var auth_api_request_1 = require("./auth-api-request");
24var token_generator_1 = require("./token-generator");
25var token_verifier_1 = require("./token-verifier");
26var auth_config_1 = require("./auth-config");
27var user_record_1 = require("./user-record");
28var identifier_1 = require("./identifier");
29var crypto_signer_1 = require("../utils/crypto-signer");
30/**
31 * @internal
32 */
33function createFirebaseTokenGenerator(app, tenantId) {
34 try {
35 var signer = auth_api_request_1.useEmulator() ? new token_generator_1.EmulatedSigner() : crypto_signer_1.cryptoSignerFromApp(app);
36 return new token_generator_1.FirebaseTokenGenerator(signer, tenantId);
37 }
38 catch (err) {
39 throw token_generator_1.handleCryptoSignerError(err);
40 }
41}
42exports.createFirebaseTokenGenerator = createFirebaseTokenGenerator;
43/**
44 * Common parent interface for both `Auth` and `TenantAwareAuth` APIs.
45 */
46var BaseAuth = /** @class */ (function () {
47 /**
48 * The BaseAuth class constructor.
49 *
50 * @param app - The FirebaseApp to associate with this Auth instance.
51 * @param authRequestHandler - The RPC request handler for this instance.
52 * @param tokenGenerator - Optional token generator. If not specified, a
53 * (non-tenant-aware) instance will be created. Use this paramter to
54 * specify a tenant-aware tokenGenerator.
55 * @constructor
56 * @internal
57 */
58 function BaseAuth(app,
59 /** @internal */ authRequestHandler, tokenGenerator) {
60 this.authRequestHandler = authRequestHandler;
61 if (tokenGenerator) {
62 this.tokenGenerator = tokenGenerator;
63 }
64 else {
65 this.tokenGenerator = createFirebaseTokenGenerator(app);
66 }
67 this.sessionCookieVerifier = token_verifier_1.createSessionCookieVerifier(app);
68 this.idTokenVerifier = token_verifier_1.createIdTokenVerifier(app);
69 }
70 /**
71 * Creates a new Firebase custom token (JWT) that can be sent back to a client
72 * device to use to sign in with the client SDKs' `signInWithCustomToken()`
73 * methods. (Tenant-aware instances will also embed the tenant ID in the
74 * token.)
75 *
76 * See {@link https://firebase.google.com/docs/auth/admin/create-custom-tokens | Create Custom Tokens}
77 * for code samples and detailed documentation.
78 *
79 * @param uid - The `uid` to use as the custom token's subject.
80 * @param developerClaims - Optional additional claims to include
81 * in the custom token's payload.
82 *
83 * @returns A promise fulfilled with a custom token for the
84 * provided `uid` and payload.
85 */
86 BaseAuth.prototype.createCustomToken = function (uid, developerClaims) {
87 return this.tokenGenerator.createCustomToken(uid, developerClaims);
88 };
89 /**
90 * Verifies a Firebase ID token (JWT). If the token is valid, the promise is
91 * fulfilled with the token's decoded claims; otherwise, the promise is
92 * rejected.
93 *
94 * If `checkRevoked` is set to true, first verifies whether the corresponding
95 * user is disabled. If yes, an `auth/user-disabled` error is thrown. If no,
96 * verifies if the session corresponding to the ID token was revoked. If the
97 * corresponding user's session was invalidated, an `auth/id-token-revoked`
98 * error is thrown. If not specified the check is not applied.
99 *
100 * See {@link https://firebase.google.com/docs/auth/admin/verify-id-tokens | Verify ID Tokens}
101 * for code samples and detailed documentation.
102 *
103 * @param idToken - The ID token to verify.
104 * @param checkRevoked - Whether to check if the ID token was revoked.
105 * This requires an extra request to the Firebase Auth backend to check
106 * the `tokensValidAfterTime` time for the corresponding user.
107 * When not specified, this additional check is not applied.
108 *
109 * @returns A promise fulfilled with the
110 * token's decoded claims if the ID token is valid; otherwise, a rejected
111 * promise.
112 */
113 BaseAuth.prototype.verifyIdToken = function (idToken, checkRevoked) {
114 var _this = this;
115 if (checkRevoked === void 0) { checkRevoked = false; }
116 var isEmulator = auth_api_request_1.useEmulator();
117 return this.idTokenVerifier.verifyJWT(idToken, isEmulator)
118 .then(function (decodedIdToken) {
119 // Whether to check if the token was revoked.
120 if (checkRevoked || isEmulator) {
121 return _this.verifyDecodedJWTNotRevokedOrDisabled(decodedIdToken, error_1.AuthClientErrorCode.ID_TOKEN_REVOKED);
122 }
123 return decodedIdToken;
124 });
125 };
126 /**
127 * Gets the user data for the user corresponding to a given `uid`.
128 *
129 * See {@link https://firebase.google.com/docs/auth/admin/manage-users#retrieve_user_data | Retrieve user data}
130 * for code samples and detailed documentation.
131 *
132 * @param uid - The `uid` corresponding to the user whose data to fetch.
133 *
134 * @returns A promise fulfilled with the user
135 * data corresponding to the provided `uid`.
136 */
137 BaseAuth.prototype.getUser = function (uid) {
138 return this.authRequestHandler.getAccountInfoByUid(uid)
139 .then(function (response) {
140 // Returns the user record populated with server response.
141 return new user_record_1.UserRecord(response.users[0]);
142 });
143 };
144 /**
145 * Gets the user data for the user corresponding to a given email.
146 *
147 * See {@link https://firebase.google.com/docs/auth/admin/manage-users#retrieve_user_data | Retrieve user data}
148 * for code samples and detailed documentation.
149 *
150 * @param email - The email corresponding to the user whose data to
151 * fetch.
152 *
153 * @returns A promise fulfilled with the user
154 * data corresponding to the provided email.
155 */
156 BaseAuth.prototype.getUserByEmail = function (email) {
157 return this.authRequestHandler.getAccountInfoByEmail(email)
158 .then(function (response) {
159 // Returns the user record populated with server response.
160 return new user_record_1.UserRecord(response.users[0]);
161 });
162 };
163 /**
164 * Gets the user data for the user corresponding to a given phone number. The
165 * phone number has to conform to the E.164 specification.
166 *
167 * See {@link https://firebase.google.com/docs/auth/admin/manage-users#retrieve_user_data | Retrieve user data}
168 * for code samples and detailed documentation.
169 *
170 * @param phoneNumber - The phone number corresponding to the user whose
171 * data to fetch.
172 *
173 * @returns A promise fulfilled with the user
174 * data corresponding to the provided phone number.
175 */
176 BaseAuth.prototype.getUserByPhoneNumber = function (phoneNumber) {
177 return this.authRequestHandler.getAccountInfoByPhoneNumber(phoneNumber)
178 .then(function (response) {
179 // Returns the user record populated with server response.
180 return new user_record_1.UserRecord(response.users[0]);
181 });
182 };
183 /**
184 * Gets the user data for the user corresponding to a given provider id.
185 *
186 * See {@link https://firebase.google.com/docs/auth/admin/manage-users#retrieve_user_data | Retrieve user data}
187 * for code samples and detailed documentation.
188 *
189 * @param providerId - The provider ID, for example, "google.com" for the
190 * Google provider.
191 * @param uid - The user identifier for the given provider.
192 *
193 * @returns A promise fulfilled with the user data corresponding to the
194 * given provider id.
195 */
196 BaseAuth.prototype.getUserByProviderUid = function (providerId, uid) {
197 // Although we don't really advertise it, we want to also handle
198 // non-federated idps with this call. So if we detect one of them, we'll
199 // reroute this request appropriately.
200 if (providerId === 'phone') {
201 return this.getUserByPhoneNumber(uid);
202 }
203 else if (providerId === 'email') {
204 return this.getUserByEmail(uid);
205 }
206 return this.authRequestHandler.getAccountInfoByFederatedUid(providerId, uid)
207 .then(function (response) {
208 // Returns the user record populated with server response.
209 return new user_record_1.UserRecord(response.users[0]);
210 });
211 };
212 /**
213 * Gets the user data corresponding to the specified identifiers.
214 *
215 * There are no ordering guarantees; in particular, the nth entry in the result list is not
216 * guaranteed to correspond to the nth entry in the input parameters list.
217 *
218 * Only a maximum of 100 identifiers may be supplied. If more than 100 identifiers are supplied,
219 * this method throws a FirebaseAuthError.
220 *
221 * @param identifiers - The identifiers used to indicate which user records should be returned.
222 * Must not have more than 100 entries.
223 * @returns A promise that resolves to the corresponding user records.
224 * @throws FirebaseAuthError If any of the identifiers are invalid or if more than 100
225 * identifiers are specified.
226 */
227 BaseAuth.prototype.getUsers = function (identifiers) {
228 if (!validator.isArray(identifiers)) {
229 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, '`identifiers` parameter must be an array');
230 }
231 return this.authRequestHandler
232 .getAccountInfoByIdentifiers(identifiers)
233 .then(function (response) {
234 /**
235 * Checks if the specified identifier is within the list of
236 * UserRecords.
237 */
238 var isUserFound = (function (id, userRecords) {
239 return !!userRecords.find(function (userRecord) {
240 if (identifier_1.isUidIdentifier(id)) {
241 return id.uid === userRecord.uid;
242 }
243 else if (identifier_1.isEmailIdentifier(id)) {
244 return id.email === userRecord.email;
245 }
246 else if (identifier_1.isPhoneIdentifier(id)) {
247 return id.phoneNumber === userRecord.phoneNumber;
248 }
249 else if (identifier_1.isProviderIdentifier(id)) {
250 var matchingUserInfo = userRecord.providerData.find(function (userInfo) {
251 return id.providerId === userInfo.providerId;
252 });
253 return !!matchingUserInfo && id.providerUid === matchingUserInfo.uid;
254 }
255 else {
256 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, 'Unhandled identifier type');
257 }
258 });
259 });
260 var users = response.users ? response.users.map(function (user) { return new user_record_1.UserRecord(user); }) : [];
261 var notFound = identifiers.filter(function (id) { return !isUserFound(id, users); });
262 return { users: users, notFound: notFound };
263 });
264 };
265 /**
266 * Retrieves a list of users (single batch only) with a size of `maxResults`
267 * starting from the offset as specified by `pageToken`. This is used to
268 * retrieve all the users of a specified project in batches.
269 *
270 * See {@link https://firebase.google.com/docs/auth/admin/manage-users#list_all_users | List all users}
271 * for code samples and detailed documentation.
272 *
273 * @param maxResults - The page size, 1000 if undefined. This is also
274 * the maximum allowed limit.
275 * @param pageToken - The next page token. If not specified, returns
276 * users starting without any offset.
277 * @returns A promise that resolves with
278 * the current batch of downloaded users and the next page token.
279 */
280 BaseAuth.prototype.listUsers = function (maxResults, pageToken) {
281 return this.authRequestHandler.downloadAccount(maxResults, pageToken)
282 .then(function (response) {
283 // List of users to return.
284 var users = [];
285 // Convert each user response to a UserRecord.
286 response.users.forEach(function (userResponse) {
287 users.push(new user_record_1.UserRecord(userResponse));
288 });
289 // Return list of user records and the next page token if available.
290 var result = {
291 users: users,
292 pageToken: response.nextPageToken,
293 };
294 // Delete result.pageToken if undefined.
295 if (typeof result.pageToken === 'undefined') {
296 delete result.pageToken;
297 }
298 return result;
299 });
300 };
301 /**
302 * Creates a new user.
303 *
304 * See {@link https://firebase.google.com/docs/auth/admin/manage-users#create_a_user | Create a user}
305 * for code samples and detailed documentation.
306 *
307 * @param properties - The properties to set on the
308 * new user record to be created.
309 *
310 * @returns A promise fulfilled with the user
311 * data corresponding to the newly created user.
312 */
313 BaseAuth.prototype.createUser = function (properties) {
314 var _this = this;
315 return this.authRequestHandler.createNewAccount(properties)
316 .then(function (uid) {
317 // Return the corresponding user record.
318 return _this.getUser(uid);
319 })
320 .catch(function (error) {
321 if (error.code === 'auth/user-not-found') {
322 // Something must have happened after creating the user and then retrieving it.
323 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, 'Unable to create the user record provided.');
324 }
325 throw error;
326 });
327 };
328 /**
329 * Deletes an existing user.
330 *
331 * See {@link https://firebase.google.com/docs/auth/admin/manage-users#delete_a_user | Delete a user}
332 * for code samples and detailed documentation.
333 *
334 * @param uid - The `uid` corresponding to the user to delete.
335 *
336 * @returns An empty promise fulfilled once the user has been
337 * deleted.
338 */
339 BaseAuth.prototype.deleteUser = function (uid) {
340 return this.authRequestHandler.deleteAccount(uid)
341 .then(function () {
342 // Return nothing on success.
343 });
344 };
345 /**
346 * Deletes the users specified by the given uids.
347 *
348 * Deleting a non-existing user won't generate an error (i.e. this method
349 * is idempotent.) Non-existing users are considered to be successfully
350 * deleted, and are therefore counted in the
351 * `DeleteUsersResult.successCount` value.
352 *
353 * Only a maximum of 1000 identifiers may be supplied. If more than 1000
354 * identifiers are supplied, this method throws a FirebaseAuthError.
355 *
356 * This API is currently rate limited at the server to 1 QPS. If you exceed
357 * this, you may get a quota exceeded error. Therefore, if you want to
358 * delete more than 1000 users, you may need to add a delay to ensure you
359 * don't go over this limit.
360 *
361 * @param uids - The `uids` corresponding to the users to delete.
362 *
363 * @returns A Promise that resolves to the total number of successful/failed
364 * deletions, as well as the array of errors that corresponds to the
365 * failed deletions.
366 */
367 BaseAuth.prototype.deleteUsers = function (uids) {
368 if (!validator.isArray(uids)) {
369 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, '`uids` parameter must be an array');
370 }
371 return this.authRequestHandler.deleteAccounts(uids, /*force=*/ true)
372 .then(function (batchDeleteAccountsResponse) {
373 var result = {
374 failureCount: 0,
375 successCount: uids.length,
376 errors: [],
377 };
378 if (!validator.isNonEmptyArray(batchDeleteAccountsResponse.errors)) {
379 return result;
380 }
381 result.failureCount = batchDeleteAccountsResponse.errors.length;
382 result.successCount = uids.length - batchDeleteAccountsResponse.errors.length;
383 result.errors = batchDeleteAccountsResponse.errors.map(function (batchDeleteErrorInfo) {
384 if (batchDeleteErrorInfo.index === undefined) {
385 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INTERNAL_ERROR, 'Corrupt BatchDeleteAccountsResponse detected');
386 }
387 var errMsgToError = function (msg) {
388 // We unconditionally set force=true, so the 'NOT_DISABLED' error
389 // should not be possible.
390 var code = msg && msg.startsWith('NOT_DISABLED') ?
391 error_1.AuthClientErrorCode.USER_NOT_DISABLED : error_1.AuthClientErrorCode.INTERNAL_ERROR;
392 return new error_1.FirebaseAuthError(code, batchDeleteErrorInfo.message);
393 };
394 return {
395 index: batchDeleteErrorInfo.index,
396 error: errMsgToError(batchDeleteErrorInfo.message),
397 };
398 });
399 return result;
400 });
401 };
402 /**
403 * Updates an existing user.
404 *
405 * See {@link https://firebsae.google.com/docs/auth/admin/manage-users#update_a_user | Update a user}
406 * for code samples and detailed documentation.
407 *
408 * @param uid - The `uid` corresponding to the user to update.
409 * @param properties - The properties to update on
410 * the provided user.
411 *
412 * @returns A promise fulfilled with the
413 * updated user data.
414 */
415 BaseAuth.prototype.updateUser = function (uid, properties) {
416 var _this = this;
417 // Although we don't really advertise it, we want to also handle linking of
418 // non-federated idps with this call. So if we detect one of them, we'll
419 // adjust the properties parameter appropriately. This *does* imply that a
420 // conflict could arise, e.g. if the user provides a phoneNumber property,
421 // but also provides a providerToLink with a 'phone' provider id. In that
422 // case, we'll throw an error.
423 properties = deep_copy_1.deepCopy(properties);
424 if (properties === null || properties === void 0 ? void 0 : properties.providerToLink) {
425 if (properties.providerToLink.providerId === 'email') {
426 if (typeof properties.email !== 'undefined') {
427 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "Both UpdateRequest.email and UpdateRequest.providerToLink.providerId='email' were set. To "
428 + 'link to the email/password provider, only specify the UpdateRequest.email field.');
429 }
430 properties.email = properties.providerToLink.uid;
431 delete properties.providerToLink;
432 }
433 else if (properties.providerToLink.providerId === 'phone') {
434 if (typeof properties.phoneNumber !== 'undefined') {
435 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "Both UpdateRequest.phoneNumber and UpdateRequest.providerToLink.providerId='phone' were set. To "
436 + 'link to a phone provider, only specify the UpdateRequest.phoneNumber field.');
437 }
438 properties.phoneNumber = properties.providerToLink.uid;
439 delete properties.providerToLink;
440 }
441 }
442 if (properties === null || properties === void 0 ? void 0 : properties.providersToUnlink) {
443 if (properties.providersToUnlink.indexOf('phone') !== -1) {
444 // If we've been told to unlink the phone provider both via setting
445 // phoneNumber to null *and* by setting providersToUnlink to include
446 // 'phone', then we'll reject that. Though it might also be reasonable
447 // to relax this restriction and just unlink it.
448 if (properties.phoneNumber === null) {
449 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, "Both UpdateRequest.phoneNumber=null and UpdateRequest.providersToUnlink=['phone'] were set. To "
450 + 'unlink from a phone provider, only specify the UpdateRequest.phoneNumber=null field.');
451 }
452 }
453 }
454 return this.authRequestHandler.updateExistingAccount(uid, properties)
455 .then(function (existingUid) {
456 // Return the corresponding user record.
457 return _this.getUser(existingUid);
458 });
459 };
460 /**
461 * Sets additional developer claims on an existing user identified by the
462 * provided `uid`, typically used to define user roles and levels of
463 * access. These claims should propagate to all devices where the user is
464 * already signed in (after token expiration or when token refresh is forced)
465 * and the next time the user signs in. If a reserved OIDC claim name
466 * is used (sub, iat, iss, etc), an error is thrown. They are set on the
467 * authenticated user's ID token JWT.
468 *
469 * See {@link https://firebase.google.com/docs/auth/admin/custom-claims |
470 * Defining user roles and access levels}
471 * for code samples and detailed documentation.
472 *
473 * @param uid - The `uid` of the user to edit.
474 * @param customUserClaims - The developer claims to set. If null is
475 * passed, existing custom claims are deleted. Passing a custom claims payload
476 * larger than 1000 bytes will throw an error. Custom claims are added to the
477 * user's ID token which is transmitted on every authenticated request.
478 * For profile non-access related user attributes, use database or other
479 * separate storage systems.
480 * @returns A promise that resolves when the operation completes
481 * successfully.
482 */
483 BaseAuth.prototype.setCustomUserClaims = function (uid, customUserClaims) {
484 return this.authRequestHandler.setCustomUserClaims(uid, customUserClaims)
485 .then(function () {
486 // Return nothing on success.
487 });
488 };
489 /**
490 * Revokes all refresh tokens for an existing user.
491 *
492 * This API will update the user's {@link UserRecord.tokensValidAfterTime} to
493 * the current UTC. It is important that the server on which this is called has
494 * its clock set correctly and synchronized.
495 *
496 * While this will revoke all sessions for a specified user and disable any
497 * new ID tokens for existing sessions from getting minted, existing ID tokens
498 * may remain active until their natural expiration (one hour). To verify that
499 * ID tokens are revoked, use {@link BaseAuth.verifyIdToken}
500 * where `checkRevoked` is set to true.
501 *
502 * @param uid - The `uid` corresponding to the user whose refresh tokens
503 * are to be revoked.
504 *
505 * @returns An empty promise fulfilled once the user's refresh
506 * tokens have been revoked.
507 */
508 BaseAuth.prototype.revokeRefreshTokens = function (uid) {
509 return this.authRequestHandler.revokeRefreshTokens(uid)
510 .then(function () {
511 // Return nothing on success.
512 });
513 };
514 /**
515 * Imports the provided list of users into Firebase Auth.
516 * A maximum of 1000 users are allowed to be imported one at a time.
517 * When importing users with passwords,
518 * {@link UserImportOptions} are required to be
519 * specified.
520 * This operation is optimized for bulk imports and will ignore checks on `uid`,
521 * `email` and other identifier uniqueness which could result in duplications.
522 *
523 * @param users - The list of user records to import to Firebase Auth.
524 * @param options - The user import options, required when the users provided include
525 * password credentials.
526 * @returns A promise that resolves when
527 * the operation completes with the result of the import. This includes the
528 * number of successful imports, the number of failed imports and their
529 * corresponding errors.
530 */
531 BaseAuth.prototype.importUsers = function (users, options) {
532 return this.authRequestHandler.uploadAccount(users, options);
533 };
534 /**
535 * Creates a new Firebase session cookie with the specified options. The created
536 * JWT string can be set as a server-side session cookie with a custom cookie
537 * policy, and be used for session management. The session cookie JWT will have
538 * the same payload claims as the provided ID token.
539 *
540 * See {@link https://firebase.google.com/docs/auth/admin/manage-cookies | Manage Session Cookies}
541 * for code samples and detailed documentation.
542 *
543 * @param idToken - The Firebase ID token to exchange for a session
544 * cookie.
545 * @param sessionCookieOptions - The session
546 * cookie options which includes custom session duration.
547 *
548 * @returns A promise that resolves on success with the
549 * created session cookie.
550 */
551 BaseAuth.prototype.createSessionCookie = function (idToken, sessionCookieOptions) {
552 // Return rejected promise if expiresIn is not available.
553 if (!validator.isNonNullObject(sessionCookieOptions) ||
554 !validator.isNumber(sessionCookieOptions.expiresIn)) {
555 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_SESSION_COOKIE_DURATION));
556 }
557 return this.authRequestHandler.createSessionCookie(idToken, sessionCookieOptions.expiresIn);
558 };
559 /**
560 * Verifies a Firebase session cookie. Returns a Promise with the cookie claims.
561 * Rejects the promise if the cookie could not be verified.
562 *
563 * If `checkRevoked` is set to true, first verifies whether the corresponding
564 * user is disabled: If yes, an `auth/user-disabled` error is thrown. If no,
565 * verifies if the session corresponding to the session cookie was revoked.
566 * If the corresponding user's session was invalidated, an
567 * `auth/session-cookie-revoked` error is thrown. If not specified the check
568 * is not performed.
569 *
570 * See {@link https://firebase.google.com/docs/auth/admin/manage-cookies#verify_session_cookie_and_check_permissions |
571 * Verify Session Cookies}
572 * for code samples and detailed documentation
573 *
574 * @param sessionCookie - The session cookie to verify.
575 * @param checkForRevocation - Whether to check if the session cookie was
576 * revoked. This requires an extra request to the Firebase Auth backend to
577 * check the `tokensValidAfterTime` time for the corresponding user.
578 * When not specified, this additional check is not performed.
579 *
580 * @returns A promise fulfilled with the
581 * session cookie's decoded claims if the session cookie is valid; otherwise,
582 * a rejected promise.
583 */
584 BaseAuth.prototype.verifySessionCookie = function (sessionCookie, checkRevoked) {
585 var _this = this;
586 if (checkRevoked === void 0) { checkRevoked = false; }
587 var isEmulator = auth_api_request_1.useEmulator();
588 return this.sessionCookieVerifier.verifyJWT(sessionCookie, isEmulator)
589 .then(function (decodedIdToken) {
590 // Whether to check if the token was revoked.
591 if (checkRevoked || isEmulator) {
592 return _this.verifyDecodedJWTNotRevokedOrDisabled(decodedIdToken, error_1.AuthClientErrorCode.SESSION_COOKIE_REVOKED);
593 }
594 return decodedIdToken;
595 });
596 };
597 /**
598 * Generates the out of band email action link to reset a user's password.
599 * The link is generated for the user with the specified email address. The
600 * optional {@link ActionCodeSettings} object
601 * defines whether the link is to be handled by a mobile app or browser and the
602 * additional state information to be passed in the deep link, etc.
603 *
604 * @example
605 * ```javascript
606 * var actionCodeSettings = {
607 * url: 'https://www.example.com/?email=user@example.com',
608 * iOS: {
609 * bundleId: 'com.example.ios'
610 * },
611 * android: {
612 * packageName: 'com.example.android',
613 * installApp: true,
614 * minimumVersion: '12'
615 * },
616 * handleCodeInApp: true,
617 * dynamicLinkDomain: 'custom.page.link'
618 * };
619 * admin.auth()
620 * .generatePasswordResetLink('user@example.com', actionCodeSettings)
621 * .then(function(link) {
622 * // The link was successfully generated.
623 * })
624 * .catch(function(error) {
625 * // Some error occurred, you can inspect the code: error.code
626 * });
627 * ```
628 *
629 * @param email - The email address of the user whose password is to be
630 * reset.
631 * @param actionCodeSettings - The action
632 * code settings. If specified, the state/continue URL is set as the
633 * "continueUrl" parameter in the password reset link. The default password
634 * reset landing page will use this to display a link to go back to the app
635 * if it is installed.
636 * If the actionCodeSettings is not specified, no URL is appended to the
637 * action URL.
638 * The state URL provided must belong to a domain that is whitelisted by the
639 * developer in the console. Otherwise an error is thrown.
640 * Mobile app redirects are only applicable if the developer configures
641 * and accepts the Firebase Dynamic Links terms of service.
642 * The Android package name and iOS bundle ID are respected only if they
643 * are configured in the same Firebase Auth project.
644 * @returns A promise that resolves with the generated link.
645 */
646 BaseAuth.prototype.generatePasswordResetLink = function (email, actionCodeSettings) {
647 return this.authRequestHandler.getEmailActionLink('PASSWORD_RESET', email, actionCodeSettings);
648 };
649 /**
650 * Generates the out of band email action link to verify the user's ownership
651 * of the specified email. The {@link ActionCodeSettings} object provided
652 * as an argument to this method defines whether the link is to be handled by a
653 * mobile app or browser along with additional state information to be passed in
654 * the deep link, etc.
655 *
656 * @example
657 * ```javascript
658 * var actionCodeSettings = {
659 * url: 'https://www.example.com/cart?email=user@example.com&cartId=123',
660 * iOS: {
661 * bundleId: 'com.example.ios'
662 * },
663 * android: {
664 * packageName: 'com.example.android',
665 * installApp: true,
666 * minimumVersion: '12'
667 * },
668 * handleCodeInApp: true,
669 * dynamicLinkDomain: 'custom.page.link'
670 * };
671 * admin.auth()
672 * .generateEmailVerificationLink('user@example.com', actionCodeSettings)
673 * .then(function(link) {
674 * // The link was successfully generated.
675 * })
676 * .catch(function(error) {
677 * // Some error occurred, you can inspect the code: error.code
678 * });
679 * ```
680 *
681 * @param email - The email account to verify.
682 * @param actionCodeSettings - The action
683 * code settings. If specified, the state/continue URL is set as the
684 * "continueUrl" parameter in the email verification link. The default email
685 * verification landing page will use this to display a link to go back to
686 * the app if it is installed.
687 * If the actionCodeSettings is not specified, no URL is appended to the
688 * action URL.
689 * The state URL provided must belong to a domain that is whitelisted by the
690 * developer in the console. Otherwise an error is thrown.
691 * Mobile app redirects are only applicable if the developer configures
692 * and accepts the Firebase Dynamic Links terms of service.
693 * The Android package name and iOS bundle ID are respected only if they
694 * are configured in the same Firebase Auth project.
695 * @returns A promise that resolves with the generated link.
696 */
697 BaseAuth.prototype.generateEmailVerificationLink = function (email, actionCodeSettings) {
698 return this.authRequestHandler.getEmailActionLink('VERIFY_EMAIL', email, actionCodeSettings);
699 };
700 /**
701 * Generates the out of band email action link to verify the user's ownership
702 * of the specified email. The {@link ActionCodeSettings} object provided
703 * as an argument to this method defines whether the link is to be handled by a
704 * mobile app or browser along with additional state information to be passed in
705 * the deep link, etc.
706 *
707 * @example
708 * ```javascript
709 * var actionCodeSettings = {
710 * url: 'https://www.example.com/cart?email=user@example.com&cartId=123',
711 * iOS: {
712 * bundleId: 'com.example.ios'
713 * },
714 * android: {
715 * packageName: 'com.example.android',
716 * installApp: true,
717 * minimumVersion: '12'
718 * },
719 * handleCodeInApp: true,
720 * dynamicLinkDomain: 'custom.page.link'
721 * };
722 * admin.auth()
723 * .generateEmailVerificationLink('user@example.com', actionCodeSettings)
724 * .then(function(link) {
725 * // The link was successfully generated.
726 * })
727 * .catch(function(error) {
728 * // Some error occurred, you can inspect the code: error.code
729 * });
730 * ```
731 *
732 * @param email - The email account to verify.
733 * @param actionCodeSettings - The action
734 * code settings. If specified, the state/continue URL is set as the
735 * "continueUrl" parameter in the email verification link. The default email
736 * verification landing page will use this to display a link to go back to
737 * the app if it is installed.
738 * If the actionCodeSettings is not specified, no URL is appended to the
739 * action URL.
740 * The state URL provided must belong to a domain that is whitelisted by the
741 * developer in the console. Otherwise an error is thrown.
742 * Mobile app redirects are only applicable if the developer configures
743 * and accepts the Firebase Dynamic Links terms of service.
744 * The Android package name and iOS bundle ID are respected only if they
745 * are configured in the same Firebase Auth project.
746 * @returns A promise that resolves with the generated link.
747 */
748 BaseAuth.prototype.generateSignInWithEmailLink = function (email, actionCodeSettings) {
749 return this.authRequestHandler.getEmailActionLink('EMAIL_SIGNIN', email, actionCodeSettings);
750 };
751 /**
752 * Returns the list of existing provider configurations matching the filter
753 * provided. At most, 100 provider configs can be listed at a time.
754 *
755 * SAML and OIDC provider support requires Google Cloud's Identity Platform
756 * (GCIP). To learn more about GCIP, including pricing and features,
757 * see the {@link https://cloud.google.com/identity-platform | GCIP documentation}.
758 *
759 * @param options - The provider config filter to apply.
760 * @returns A promise that resolves with the list of provider configs meeting the
761 * filter requirements.
762 */
763 BaseAuth.prototype.listProviderConfigs = function (options) {
764 var processResponse = function (response, providerConfigs) {
765 // Return list of provider configuration and the next page token if available.
766 var result = {
767 providerConfigs: providerConfigs,
768 };
769 // Delete result.pageToken if undefined.
770 if (Object.prototype.hasOwnProperty.call(response, 'nextPageToken')) {
771 result.pageToken = response.nextPageToken;
772 }
773 return result;
774 };
775 if (options && options.type === 'oidc') {
776 return this.authRequestHandler.listOAuthIdpConfigs(options.maxResults, options.pageToken)
777 .then(function (response) {
778 // List of provider configurations to return.
779 var providerConfigs = [];
780 // Convert each provider config response to a OIDCConfig.
781 response.oauthIdpConfigs.forEach(function (configResponse) {
782 providerConfigs.push(new auth_config_1.OIDCConfig(configResponse));
783 });
784 // Return list of provider configuration and the next page token if available.
785 return processResponse(response, providerConfigs);
786 });
787 }
788 else if (options && options.type === 'saml') {
789 return this.authRequestHandler.listInboundSamlConfigs(options.maxResults, options.pageToken)
790 .then(function (response) {
791 // List of provider configurations to return.
792 var providerConfigs = [];
793 // Convert each provider config response to a SAMLConfig.
794 response.inboundSamlConfigs.forEach(function (configResponse) {
795 providerConfigs.push(new auth_config_1.SAMLConfig(configResponse));
796 });
797 // Return list of provider configuration and the next page token if available.
798 return processResponse(response, providerConfigs);
799 });
800 }
801 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_ARGUMENT, '"AuthProviderConfigFilter.type" must be either "saml" or "oidc"'));
802 };
803 /**
804 * Looks up an Auth provider configuration by the provided ID.
805 * Returns a promise that resolves with the provider configuration
806 * corresponding to the provider ID specified. If the specified ID does not
807 * exist, an `auth/configuration-not-found` error is thrown.
808 *
809 * SAML and OIDC provider support requires Google Cloud's Identity Platform
810 * (GCIP). To learn more about GCIP, including pricing and features,
811 * see the {@link https://cloud.google.com/identity-platform | GCIP documentation}.
812 *
813 * @param providerId - The provider ID corresponding to the provider
814 * config to return.
815 * @returns A promise that resolves
816 * with the configuration corresponding to the provided ID.
817 */
818 BaseAuth.prototype.getProviderConfig = function (providerId) {
819 if (auth_config_1.OIDCConfig.isProviderId(providerId)) {
820 return this.authRequestHandler.getOAuthIdpConfig(providerId)
821 .then(function (response) {
822 return new auth_config_1.OIDCConfig(response);
823 });
824 }
825 else if (auth_config_1.SAMLConfig.isProviderId(providerId)) {
826 return this.authRequestHandler.getInboundSamlConfig(providerId)
827 .then(function (response) {
828 return new auth_config_1.SAMLConfig(response);
829 });
830 }
831 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_PROVIDER_ID));
832 };
833 /**
834 * Deletes the provider configuration corresponding to the provider ID passed.
835 * If the specified ID does not exist, an `auth/configuration-not-found` error
836 * is thrown.
837 *
838 * SAML and OIDC provider support requires Google Cloud's Identity Platform
839 * (GCIP). To learn more about GCIP, including pricing and features,
840 * see the {@link https://cloud.google.com/identity-platform | GCIP documentation}.
841 *
842 * @param providerId - The provider ID corresponding to the provider
843 * config to delete.
844 * @returns A promise that resolves on completion.
845 */
846 BaseAuth.prototype.deleteProviderConfig = function (providerId) {
847 if (auth_config_1.OIDCConfig.isProviderId(providerId)) {
848 return this.authRequestHandler.deleteOAuthIdpConfig(providerId);
849 }
850 else if (auth_config_1.SAMLConfig.isProviderId(providerId)) {
851 return this.authRequestHandler.deleteInboundSamlConfig(providerId);
852 }
853 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_PROVIDER_ID));
854 };
855 /**
856 * Returns a promise that resolves with the updated `AuthProviderConfig`
857 * corresponding to the provider ID specified.
858 * If the specified ID does not exist, an `auth/configuration-not-found` error
859 * is thrown.
860 *
861 * SAML and OIDC provider support requires Google Cloud's Identity Platform
862 * (GCIP). To learn more about GCIP, including pricing and features,
863 * see the {@link https://cloud.google.com/identity-platform | GCIP documentation}.
864 *
865 * @param providerId - The provider ID corresponding to the provider
866 * config to update.
867 * @param updatedConfig - The updated configuration.
868 * @returns A promise that resolves with the updated provider configuration.
869 */
870 BaseAuth.prototype.updateProviderConfig = function (providerId, updatedConfig) {
871 if (!validator.isNonNullObject(updatedConfig)) {
872 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_CONFIG, 'Request is missing "UpdateAuthProviderRequest" configuration.'));
873 }
874 if (auth_config_1.OIDCConfig.isProviderId(providerId)) {
875 return this.authRequestHandler.updateOAuthIdpConfig(providerId, updatedConfig)
876 .then(function (response) {
877 return new auth_config_1.OIDCConfig(response);
878 });
879 }
880 else if (auth_config_1.SAMLConfig.isProviderId(providerId)) {
881 return this.authRequestHandler.updateInboundSamlConfig(providerId, updatedConfig)
882 .then(function (response) {
883 return new auth_config_1.SAMLConfig(response);
884 });
885 }
886 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_PROVIDER_ID));
887 };
888 /**
889 * Returns a promise that resolves with the newly created `AuthProviderConfig`
890 * when the new provider configuration is created.
891 *
892 * SAML and OIDC provider support requires Google Cloud's Identity Platform
893 * (GCIP). To learn more about GCIP, including pricing and features,
894 * see the {@link https://cloud.google.com/identity-platform | GCIP documentation}.
895 *
896 * @param config - The provider configuration to create.
897 * @returns A promise that resolves with the created provider configuration.
898 */
899 BaseAuth.prototype.createProviderConfig = function (config) {
900 if (!validator.isNonNullObject(config)) {
901 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_CONFIG, 'Request is missing "AuthProviderConfig" configuration.'));
902 }
903 if (auth_config_1.OIDCConfig.isProviderId(config.providerId)) {
904 return this.authRequestHandler.createOAuthIdpConfig(config)
905 .then(function (response) {
906 return new auth_config_1.OIDCConfig(response);
907 });
908 }
909 else if (auth_config_1.SAMLConfig.isProviderId(config.providerId)) {
910 return this.authRequestHandler.createInboundSamlConfig(config)
911 .then(function (response) {
912 return new auth_config_1.SAMLConfig(response);
913 });
914 }
915 return Promise.reject(new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.INVALID_PROVIDER_ID));
916 };
917 /**
918 * Verifies the decoded Firebase issued JWT is not revoked or disabled. Returns a promise that
919 * resolves with the decoded claims on success. Rejects the promise with revocation error if revoked
920 * or user disabled.
921 *
922 * @param decodedIdToken - The JWT's decoded claims.
923 * @param revocationErrorInfo - The revocation error info to throw on revocation
924 * detection.
925 * @returns A promise that will be fulfilled after a successful verification.
926 */
927 BaseAuth.prototype.verifyDecodedJWTNotRevokedOrDisabled = function (decodedIdToken, revocationErrorInfo) {
928 // Get tokens valid after time for the corresponding user.
929 return this.getUser(decodedIdToken.sub)
930 .then(function (user) {
931 if (user.disabled) {
932 throw new error_1.FirebaseAuthError(error_1.AuthClientErrorCode.USER_DISABLED, 'The user record is disabled.');
933 }
934 // If no tokens valid after time available, token is not revoked.
935 if (user.tokensValidAfterTime) {
936 // Get the ID token authentication time and convert to milliseconds UTC.
937 var authTimeUtc = decodedIdToken.auth_time * 1000;
938 // Get user tokens valid after time in milliseconds UTC.
939 var validSinceUtc = new Date(user.tokensValidAfterTime).getTime();
940 // Check if authentication time is older than valid since time.
941 if (authTimeUtc < validSinceUtc) {
942 throw new error_1.FirebaseAuthError(revocationErrorInfo);
943 }
944 }
945 // All checks above passed. Return the decoded token.
946 return decodedIdToken;
947 });
948 };
949 return BaseAuth;
950}());
951exports.BaseAuth = BaseAuth;