UNPKG

255 kBJavaScriptView Raw
1import { ErrorFactory, deepEqual, isBrowserExtension, isMobileCordova, isReactNative, FirebaseError, querystring, getModularInstance, base64Decode, getUA, isIE, createSubscribe, querystringDecode, extractQuerystring } from '@firebase/util';
2import { SDK_VERSION, _getProvider, _registerComponent, registerVersion, getApp } from '@firebase/app';
3import { __rest } from 'tslib';
4import { Logger, LogLevel } from '@firebase/logger';
5import { Component } from '@firebase/component';
6import * as fetchImpl from 'node-fetch';
7
8/**
9 * @license
10 * Copyright 2021 Google LLC
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 */
24/**
25 * An enum of factors that may be used for multifactor authentication.
26 *
27 * @public
28 */
29const FactorId = {
30 /** Phone as second factor */
31 PHONE: 'phone'
32};
33/**
34 * Enumeration of supported providers.
35 *
36 * @public
37 */
38const ProviderId = {
39 /** Facebook provider ID */
40 FACEBOOK: 'facebook.com',
41 /** GitHub provider ID */
42 GITHUB: 'github.com',
43 /** Google provider ID */
44 GOOGLE: 'google.com',
45 /** Password provider */
46 PASSWORD: 'password',
47 /** Phone provider */
48 PHONE: 'phone',
49 /** Twitter provider ID */
50 TWITTER: 'twitter.com'
51};
52/**
53 * Enumeration of supported sign-in methods.
54 *
55 * @public
56 */
57const SignInMethod = {
58 /** Email link sign in method */
59 EMAIL_LINK: 'emailLink',
60 /** Email/password sign in method */
61 EMAIL_PASSWORD: 'password',
62 /** Facebook sign in method */
63 FACEBOOK: 'facebook.com',
64 /** GitHub sign in method */
65 GITHUB: 'github.com',
66 /** Google sign in method */
67 GOOGLE: 'google.com',
68 /** Phone sign in method */
69 PHONE: 'phone',
70 /** Twitter sign in method */
71 TWITTER: 'twitter.com'
72};
73/**
74 * Enumeration of supported operation types.
75 *
76 * @public
77 */
78const OperationType = {
79 /** Operation involving linking an additional provider to an already signed-in user. */
80 LINK: 'link',
81 /** Operation involving using a provider to reauthenticate an already signed-in user. */
82 REAUTHENTICATE: 'reauthenticate',
83 /** Operation involving signing in a user. */
84 SIGN_IN: 'signIn'
85};
86/**
87 * An enumeration of the possible email action types.
88 *
89 * @public
90 */
91const ActionCodeOperation = {
92 /** The email link sign-in action. */
93 EMAIL_SIGNIN: 'EMAIL_SIGNIN',
94 /** The password reset action. */
95 PASSWORD_RESET: 'PASSWORD_RESET',
96 /** The email revocation action. */
97 RECOVER_EMAIL: 'RECOVER_EMAIL',
98 /** The revert second factor addition email action. */
99 REVERT_SECOND_FACTOR_ADDITION: 'REVERT_SECOND_FACTOR_ADDITION',
100 /** The revert second factor addition email action. */
101 VERIFY_AND_CHANGE_EMAIL: 'VERIFY_AND_CHANGE_EMAIL',
102 /** The email verification action. */
103 VERIFY_EMAIL: 'VERIFY_EMAIL'
104};
105
106/**
107 * @license
108 * Copyright 2020 Google LLC
109 *
110 * Licensed under the Apache License, Version 2.0 (the "License");
111 * you may not use this file except in compliance with the License.
112 * You may obtain a copy of the License at
113 *
114 * http://www.apache.org/licenses/LICENSE-2.0
115 *
116 * Unless required by applicable law or agreed to in writing, software
117 * distributed under the License is distributed on an "AS IS" BASIS,
118 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119 * See the License for the specific language governing permissions and
120 * limitations under the License.
121 */
122function _debugErrorMap() {
123 return {
124 ["admin-restricted-operation" /* ADMIN_ONLY_OPERATION */]: 'This operation is restricted to administrators only.',
125 ["argument-error" /* ARGUMENT_ERROR */]: '',
126 ["app-not-authorized" /* APP_NOT_AUTHORIZED */]: "This app, identified by the domain where it's hosted, is not " +
127 'authorized to use Firebase Authentication with the provided API key. ' +
128 'Review your key configuration in the Google API console.',
129 ["app-not-installed" /* APP_NOT_INSTALLED */]: 'The requested mobile application corresponding to the identifier (' +
130 'Android package name or iOS bundle ID) provided is not installed on ' +
131 'this device.',
132 ["captcha-check-failed" /* CAPTCHA_CHECK_FAILED */]: 'The reCAPTCHA response token provided is either invalid, expired, ' +
133 'already used or the domain associated with it does not match the list ' +
134 'of whitelisted domains.',
135 ["code-expired" /* CODE_EXPIRED */]: 'The SMS code has expired. Please re-send the verification code to try ' +
136 'again.',
137 ["cordova-not-ready" /* CORDOVA_NOT_READY */]: 'Cordova framework is not ready.',
138 ["cors-unsupported" /* CORS_UNSUPPORTED */]: 'This browser is not supported.',
139 ["credential-already-in-use" /* CREDENTIAL_ALREADY_IN_USE */]: 'This credential is already associated with a different user account.',
140 ["custom-token-mismatch" /* CREDENTIAL_MISMATCH */]: 'The custom token corresponds to a different audience.',
141 ["requires-recent-login" /* CREDENTIAL_TOO_OLD_LOGIN_AGAIN */]: 'This operation is sensitive and requires recent authentication. Log in ' +
142 'again before retrying this request.',
143 ["dependent-sdk-initialized-before-auth" /* DEPENDENT_SDK_INIT_BEFORE_AUTH */]: 'Another Firebase SDK was initialized and is trying to use Auth before Auth is ' +
144 'initialized. Please be sure to call `initializeAuth` or `getAuth` before ' +
145 'starting any other Firebase SDK.',
146 ["dynamic-link-not-activated" /* DYNAMIC_LINK_NOT_ACTIVATED */]: 'Please activate Dynamic Links in the Firebase Console and agree to the terms and ' +
147 'conditions.',
148 ["email-change-needs-verification" /* EMAIL_CHANGE_NEEDS_VERIFICATION */]: 'Multi-factor users must always have a verified email.',
149 ["email-already-in-use" /* EMAIL_EXISTS */]: 'The email address is already in use by another account.',
150 ["emulator-config-failed" /* EMULATOR_CONFIG_FAILED */]: 'Auth instance has already been used to make a network call. Auth can ' +
151 'no longer be configured to use the emulator. Try calling ' +
152 '"connectAuthEmulator()" sooner.',
153 ["expired-action-code" /* EXPIRED_OOB_CODE */]: 'The action code has expired.',
154 ["cancelled-popup-request" /* EXPIRED_POPUP_REQUEST */]: 'This operation has been cancelled due to another conflicting popup being opened.',
155 ["internal-error" /* INTERNAL_ERROR */]: 'An internal AuthError has occurred.',
156 ["invalid-app-credential" /* INVALID_APP_CREDENTIAL */]: 'The phone verification request contains an invalid application verifier.' +
157 ' The reCAPTCHA token response is either invalid or expired.',
158 ["invalid-app-id" /* INVALID_APP_ID */]: 'The mobile app identifier is not registed for the current project.',
159 ["invalid-user-token" /* INVALID_AUTH */]: "This user's credential isn't valid for this project. This can happen " +
160 "if the user's token has been tampered with, or if the user isn't for " +
161 'the project associated with this API key.',
162 ["invalid-auth-event" /* INVALID_AUTH_EVENT */]: 'An internal AuthError has occurred.',
163 ["invalid-verification-code" /* INVALID_CODE */]: 'The SMS verification code used to create the phone auth credential is ' +
164 'invalid. Please resend the verification code sms and be sure to use the ' +
165 'verification code provided by the user.',
166 ["invalid-continue-uri" /* INVALID_CONTINUE_URI */]: 'The continue URL provided in the request is invalid.',
167 ["invalid-cordova-configuration" /* INVALID_CORDOVA_CONFIGURATION */]: 'The following Cordova plugins must be installed to enable OAuth sign-in: ' +
168 'cordova-plugin-buildinfo, cordova-universal-links-plugin, ' +
169 'cordova-plugin-browsertab, cordova-plugin-inappbrowser and ' +
170 'cordova-plugin-customurlscheme.',
171 ["invalid-custom-token" /* INVALID_CUSTOM_TOKEN */]: 'The custom token format is incorrect. Please check the documentation.',
172 ["invalid-dynamic-link-domain" /* INVALID_DYNAMIC_LINK_DOMAIN */]: 'The provided dynamic link domain is not configured or authorized for the current project.',
173 ["invalid-email" /* INVALID_EMAIL */]: 'The email address is badly formatted.',
174 ["invalid-emulator-scheme" /* INVALID_EMULATOR_SCHEME */]: 'Emulator URL must start with a valid scheme (http:// or https://).',
175 ["invalid-api-key" /* INVALID_API_KEY */]: 'Your API key is invalid, please check you have copied it correctly.',
176 ["invalid-cert-hash" /* INVALID_CERT_HASH */]: 'The SHA-1 certificate hash provided is invalid.',
177 ["invalid-credential" /* INVALID_IDP_RESPONSE */]: 'The supplied auth credential is malformed or has expired.',
178 ["invalid-message-payload" /* INVALID_MESSAGE_PAYLOAD */]: 'The email template corresponding to this action contains invalid characters in its message. ' +
179 'Please fix by going to the Auth email templates section in the Firebase Console.',
180 ["invalid-multi-factor-session" /* INVALID_MFA_SESSION */]: 'The request does not contain a valid proof of first factor successful sign-in.',
181 ["invalid-oauth-provider" /* INVALID_OAUTH_PROVIDER */]: 'EmailAuthProvider is not supported for this operation. This operation ' +
182 'only supports OAuth providers.',
183 ["invalid-oauth-client-id" /* INVALID_OAUTH_CLIENT_ID */]: 'The OAuth client ID provided is either invalid or does not match the ' +
184 'specified API key.',
185 ["unauthorized-domain" /* INVALID_ORIGIN */]: 'This domain is not authorized for OAuth operations for your Firebase ' +
186 'project. Edit the list of authorized domains from the Firebase console.',
187 ["invalid-action-code" /* INVALID_OOB_CODE */]: 'The action code is invalid. This can happen if the code is malformed, ' +
188 'expired, or has already been used.',
189 ["wrong-password" /* INVALID_PASSWORD */]: 'The password is invalid or the user does not have a password.',
190 ["invalid-persistence-type" /* INVALID_PERSISTENCE */]: 'The specified persistence type is invalid. It can only be local, session or none.',
191 ["invalid-phone-number" /* INVALID_PHONE_NUMBER */]: 'The format of the phone number provided is incorrect. Please enter the ' +
192 'phone number in a format that can be parsed into E.164 format. E.164 ' +
193 'phone numbers are written in the format [+][country code][subscriber ' +
194 'number including area code].',
195 ["invalid-provider-id" /* INVALID_PROVIDER_ID */]: 'The specified provider ID is invalid.',
196 ["invalid-recipient-email" /* INVALID_RECIPIENT_EMAIL */]: 'The email corresponding to this action failed to send as the provided ' +
197 'recipient email address is invalid.',
198 ["invalid-sender" /* INVALID_SENDER */]: 'The email template corresponding to this action contains an invalid sender email or name. ' +
199 'Please fix by going to the Auth email templates section in the Firebase Console.',
200 ["invalid-verification-id" /* INVALID_SESSION_INFO */]: 'The verification ID used to create the phone auth credential is invalid.',
201 ["invalid-tenant-id" /* INVALID_TENANT_ID */]: "The Auth instance's tenant ID is invalid.",
202 ["login-blocked" /* LOGIN_BLOCKED */]: "Login blocked by user-provided method: {$originalMessage}",
203 ["missing-android-pkg-name" /* MISSING_ANDROID_PACKAGE_NAME */]: 'An Android Package Name must be provided if the Android App is required to be installed.',
204 ["auth-domain-config-required" /* MISSING_AUTH_DOMAIN */]: 'Be sure to include authDomain when calling firebase.initializeApp(), ' +
205 'by following the instructions in the Firebase console.',
206 ["missing-app-credential" /* MISSING_APP_CREDENTIAL */]: 'The phone verification request is missing an application verifier ' +
207 'assertion. A reCAPTCHA response token needs to be provided.',
208 ["missing-verification-code" /* MISSING_CODE */]: 'The phone auth credential was created with an empty SMS verification code.',
209 ["missing-continue-uri" /* MISSING_CONTINUE_URI */]: 'A continue URL must be provided in the request.',
210 ["missing-iframe-start" /* MISSING_IFRAME_START */]: 'An internal AuthError has occurred.',
211 ["missing-ios-bundle-id" /* MISSING_IOS_BUNDLE_ID */]: 'An iOS Bundle ID must be provided if an App Store ID is provided.',
212 ["missing-or-invalid-nonce" /* MISSING_OR_INVALID_NONCE */]: 'The request does not contain a valid nonce. This can occur if the ' +
213 'SHA-256 hash of the provided raw nonce does not match the hashed nonce ' +
214 'in the ID token payload.',
215 ["missing-multi-factor-info" /* MISSING_MFA_INFO */]: 'No second factor identifier is provided.',
216 ["missing-multi-factor-session" /* MISSING_MFA_SESSION */]: 'The request is missing proof of first factor successful sign-in.',
217 ["missing-phone-number" /* MISSING_PHONE_NUMBER */]: 'To send verification codes, provide a phone number for the recipient.',
218 ["missing-verification-id" /* MISSING_SESSION_INFO */]: 'The phone auth credential was created with an empty verification ID.',
219 ["app-deleted" /* MODULE_DESTROYED */]: 'This instance of FirebaseApp has been deleted.',
220 ["multi-factor-info-not-found" /* MFA_INFO_NOT_FOUND */]: 'The user does not have a second factor matching the identifier provided.',
221 ["multi-factor-auth-required" /* MFA_REQUIRED */]: 'Proof of ownership of a second factor is required to complete sign-in.',
222 ["account-exists-with-different-credential" /* NEED_CONFIRMATION */]: 'An account already exists with the same email address but different ' +
223 'sign-in credentials. Sign in using a provider associated with this ' +
224 'email address.',
225 ["network-request-failed" /* NETWORK_REQUEST_FAILED */]: 'A network AuthError (such as timeout, interrupted connection or unreachable host) has occurred.',
226 ["no-auth-event" /* NO_AUTH_EVENT */]: 'An internal AuthError has occurred.',
227 ["no-such-provider" /* NO_SUCH_PROVIDER */]: 'User was not linked to an account with the given provider.',
228 ["null-user" /* NULL_USER */]: 'A null user object was provided as the argument for an operation which ' +
229 'requires a non-null user object.',
230 ["operation-not-allowed" /* OPERATION_NOT_ALLOWED */]: 'The given sign-in provider is disabled for this Firebase project. ' +
231 'Enable it in the Firebase console, under the sign-in method tab of the ' +
232 'Auth section.',
233 ["operation-not-supported-in-this-environment" /* OPERATION_NOT_SUPPORTED */]: 'This operation is not supported in the environment this application is ' +
234 'running on. "location.protocol" must be http, https or chrome-extension' +
235 ' and web storage must be enabled.',
236 ["popup-blocked" /* POPUP_BLOCKED */]: 'Unable to establish a connection with the popup. It may have been blocked by the browser.',
237 ["popup-closed-by-user" /* POPUP_CLOSED_BY_USER */]: 'The popup has been closed by the user before finalizing the operation.',
238 ["provider-already-linked" /* PROVIDER_ALREADY_LINKED */]: 'User can only be linked to one identity for the given provider.',
239 ["quota-exceeded" /* QUOTA_EXCEEDED */]: "The project's quota for this operation has been exceeded.",
240 ["redirect-cancelled-by-user" /* REDIRECT_CANCELLED_BY_USER */]: 'The redirect operation has been cancelled by the user before finalizing.',
241 ["redirect-operation-pending" /* REDIRECT_OPERATION_PENDING */]: 'A redirect sign-in operation is already pending.',
242 ["rejected-credential" /* REJECTED_CREDENTIAL */]: 'The request contains malformed or mismatching credentials.',
243 ["second-factor-already-in-use" /* SECOND_FACTOR_ALREADY_ENROLLED */]: 'The second factor is already enrolled on this account.',
244 ["maximum-second-factor-count-exceeded" /* SECOND_FACTOR_LIMIT_EXCEEDED */]: 'The maximum allowed number of second factors on a user has been exceeded.',
245 ["tenant-id-mismatch" /* TENANT_ID_MISMATCH */]: "The provided tenant ID does not match the Auth instance's tenant ID",
246 ["timeout" /* TIMEOUT */]: 'The operation has timed out.',
247 ["user-token-expired" /* TOKEN_EXPIRED */]: "The user's credential is no longer valid. The user must sign in again.",
248 ["too-many-requests" /* TOO_MANY_ATTEMPTS_TRY_LATER */]: 'We have blocked all requests from this device due to unusual activity. ' +
249 'Try again later.',
250 ["unauthorized-continue-uri" /* UNAUTHORIZED_DOMAIN */]: 'The domain of the continue URL is not whitelisted. Please whitelist ' +
251 'the domain in the Firebase console.',
252 ["unsupported-first-factor" /* UNSUPPORTED_FIRST_FACTOR */]: 'Enrolling a second factor or signing in with a multi-factor account requires sign-in with a supported first factor.',
253 ["unsupported-persistence-type" /* UNSUPPORTED_PERSISTENCE */]: 'The current environment does not support the specified persistence type.',
254 ["unsupported-tenant-operation" /* UNSUPPORTED_TENANT_OPERATION */]: 'This operation is not supported in a multi-tenant context.',
255 ["unverified-email" /* UNVERIFIED_EMAIL */]: 'The operation requires a verified email.',
256 ["user-cancelled" /* USER_CANCELLED */]: 'The user did not grant your application the permissions it requested.',
257 ["user-not-found" /* USER_DELETED */]: 'There is no user record corresponding to this identifier. The user may ' +
258 'have been deleted.',
259 ["user-disabled" /* USER_DISABLED */]: 'The user account has been disabled by an administrator.',
260 ["user-mismatch" /* USER_MISMATCH */]: 'The supplied credentials do not correspond to the previously signed in user.',
261 ["user-signed-out" /* USER_SIGNED_OUT */]: '',
262 ["weak-password" /* WEAK_PASSWORD */]: 'The password must be 6 characters long or more.',
263 ["web-storage-unsupported" /* WEB_STORAGE_UNSUPPORTED */]: 'This browser is not supported or 3rd party cookies and data may be disabled.',
264 ["already-initialized" /* ALREADY_INITIALIZED */]: 'initializeAuth() has already been called with ' +
265 'different options. To avoid this error, call initializeAuth() with the ' +
266 'same options as when it was originally called, or call getAuth() to return the' +
267 ' already initialized instance.'
268 };
269}
270function _prodErrorMap() {
271 // We will include this one message in the prod error map since by the very
272 // nature of this error, developers will never be able to see the message
273 // using the debugErrorMap (which is installed during auth initialization).
274 return {
275 ["dependent-sdk-initialized-before-auth" /* DEPENDENT_SDK_INIT_BEFORE_AUTH */]: 'Another Firebase SDK was initialized and is trying to use Auth before Auth is ' +
276 'initialized. Please be sure to call `initializeAuth` or `getAuth` before ' +
277 'starting any other Firebase SDK.'
278 };
279}
280/**
281 * A verbose error map with detailed descriptions for most error codes.
282 *
283 * See discussion at {@link AuthErrorMap}
284 *
285 * @public
286 */
287const debugErrorMap = _debugErrorMap;
288/**
289 * A minimal error map with all verbose error messages stripped.
290 *
291 * See discussion at {@link AuthErrorMap}
292 *
293 * @public
294 */
295const prodErrorMap = _prodErrorMap;
296const _DEFAULT_AUTH_ERROR_FACTORY = new ErrorFactory('auth', 'Firebase', _prodErrorMap());
297/**
298 * A map of potential `Auth` error codes, for easier comparison with errors
299 * thrown by the SDK.
300 *
301 * @remarks
302 * Note that you can't tree-shake individual keys
303 * in the map, so by using the map you might substantially increase your
304 * bundle size.
305 *
306 * @public
307 */
308const AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY = {
309 ADMIN_ONLY_OPERATION: 'auth/admin-restricted-operation',
310 ARGUMENT_ERROR: 'auth/argument-error',
311 APP_NOT_AUTHORIZED: 'auth/app-not-authorized',
312 APP_NOT_INSTALLED: 'auth/app-not-installed',
313 CAPTCHA_CHECK_FAILED: 'auth/captcha-check-failed',
314 CODE_EXPIRED: 'auth/code-expired',
315 CORDOVA_NOT_READY: 'auth/cordova-not-ready',
316 CORS_UNSUPPORTED: 'auth/cors-unsupported',
317 CREDENTIAL_ALREADY_IN_USE: 'auth/credential-already-in-use',
318 CREDENTIAL_MISMATCH: 'auth/custom-token-mismatch',
319 CREDENTIAL_TOO_OLD_LOGIN_AGAIN: 'auth/requires-recent-login',
320 DEPENDENT_SDK_INIT_BEFORE_AUTH: 'auth/dependent-sdk-initialized-before-auth',
321 DYNAMIC_LINK_NOT_ACTIVATED: 'auth/dynamic-link-not-activated',
322 EMAIL_CHANGE_NEEDS_VERIFICATION: 'auth/email-change-needs-verification',
323 EMAIL_EXISTS: 'auth/email-already-in-use',
324 EMULATOR_CONFIG_FAILED: 'auth/emulator-config-failed',
325 EXPIRED_OOB_CODE: 'auth/expired-action-code',
326 EXPIRED_POPUP_REQUEST: 'auth/cancelled-popup-request',
327 INTERNAL_ERROR: 'auth/internal-error',
328 INVALID_API_KEY: 'auth/invalid-api-key',
329 INVALID_APP_CREDENTIAL: 'auth/invalid-app-credential',
330 INVALID_APP_ID: 'auth/invalid-app-id',
331 INVALID_AUTH: 'auth/invalid-user-token',
332 INVALID_AUTH_EVENT: 'auth/invalid-auth-event',
333 INVALID_CERT_HASH: 'auth/invalid-cert-hash',
334 INVALID_CODE: 'auth/invalid-verification-code',
335 INVALID_CONTINUE_URI: 'auth/invalid-continue-uri',
336 INVALID_CORDOVA_CONFIGURATION: 'auth/invalid-cordova-configuration',
337 INVALID_CUSTOM_TOKEN: 'auth/invalid-custom-token',
338 INVALID_DYNAMIC_LINK_DOMAIN: 'auth/invalid-dynamic-link-domain',
339 INVALID_EMAIL: 'auth/invalid-email',
340 INVALID_EMULATOR_SCHEME: 'auth/invalid-emulator-scheme',
341 INVALID_IDP_RESPONSE: 'auth/invalid-credential',
342 INVALID_MESSAGE_PAYLOAD: 'auth/invalid-message-payload',
343 INVALID_MFA_SESSION: 'auth/invalid-multi-factor-session',
344 INVALID_OAUTH_CLIENT_ID: 'auth/invalid-oauth-client-id',
345 INVALID_OAUTH_PROVIDER: 'auth/invalid-oauth-provider',
346 INVALID_OOB_CODE: 'auth/invalid-action-code',
347 INVALID_ORIGIN: 'auth/unauthorized-domain',
348 INVALID_PASSWORD: 'auth/wrong-password',
349 INVALID_PERSISTENCE: 'auth/invalid-persistence-type',
350 INVALID_PHONE_NUMBER: 'auth/invalid-phone-number',
351 INVALID_PROVIDER_ID: 'auth/invalid-provider-id',
352 INVALID_RECIPIENT_EMAIL: 'auth/invalid-recipient-email',
353 INVALID_SENDER: 'auth/invalid-sender',
354 INVALID_SESSION_INFO: 'auth/invalid-verification-id',
355 INVALID_TENANT_ID: 'auth/invalid-tenant-id',
356 MFA_INFO_NOT_FOUND: 'auth/multi-factor-info-not-found',
357 MFA_REQUIRED: 'auth/multi-factor-auth-required',
358 MISSING_ANDROID_PACKAGE_NAME: 'auth/missing-android-pkg-name',
359 MISSING_APP_CREDENTIAL: 'auth/missing-app-credential',
360 MISSING_AUTH_DOMAIN: 'auth/auth-domain-config-required',
361 MISSING_CODE: 'auth/missing-verification-code',
362 MISSING_CONTINUE_URI: 'auth/missing-continue-uri',
363 MISSING_IFRAME_START: 'auth/missing-iframe-start',
364 MISSING_IOS_BUNDLE_ID: 'auth/missing-ios-bundle-id',
365 MISSING_OR_INVALID_NONCE: 'auth/missing-or-invalid-nonce',
366 MISSING_MFA_INFO: 'auth/missing-multi-factor-info',
367 MISSING_MFA_SESSION: 'auth/missing-multi-factor-session',
368 MISSING_PHONE_NUMBER: 'auth/missing-phone-number',
369 MISSING_SESSION_INFO: 'auth/missing-verification-id',
370 MODULE_DESTROYED: 'auth/app-deleted',
371 NEED_CONFIRMATION: 'auth/account-exists-with-different-credential',
372 NETWORK_REQUEST_FAILED: 'auth/network-request-failed',
373 NULL_USER: 'auth/null-user',
374 NO_AUTH_EVENT: 'auth/no-auth-event',
375 NO_SUCH_PROVIDER: 'auth/no-such-provider',
376 OPERATION_NOT_ALLOWED: 'auth/operation-not-allowed',
377 OPERATION_NOT_SUPPORTED: 'auth/operation-not-supported-in-this-environment',
378 POPUP_BLOCKED: 'auth/popup-blocked',
379 POPUP_CLOSED_BY_USER: 'auth/popup-closed-by-user',
380 PROVIDER_ALREADY_LINKED: 'auth/provider-already-linked',
381 QUOTA_EXCEEDED: 'auth/quota-exceeded',
382 REDIRECT_CANCELLED_BY_USER: 'auth/redirect-cancelled-by-user',
383 REDIRECT_OPERATION_PENDING: 'auth/redirect-operation-pending',
384 REJECTED_CREDENTIAL: 'auth/rejected-credential',
385 SECOND_FACTOR_ALREADY_ENROLLED: 'auth/second-factor-already-in-use',
386 SECOND_FACTOR_LIMIT_EXCEEDED: 'auth/maximum-second-factor-count-exceeded',
387 TENANT_ID_MISMATCH: 'auth/tenant-id-mismatch',
388 TIMEOUT: 'auth/timeout',
389 TOKEN_EXPIRED: 'auth/user-token-expired',
390 TOO_MANY_ATTEMPTS_TRY_LATER: 'auth/too-many-requests',
391 UNAUTHORIZED_DOMAIN: 'auth/unauthorized-continue-uri',
392 UNSUPPORTED_FIRST_FACTOR: 'auth/unsupported-first-factor',
393 UNSUPPORTED_PERSISTENCE: 'auth/unsupported-persistence-type',
394 UNSUPPORTED_TENANT_OPERATION: 'auth/unsupported-tenant-operation',
395 UNVERIFIED_EMAIL: 'auth/unverified-email',
396 USER_CANCELLED: 'auth/user-cancelled',
397 USER_DELETED: 'auth/user-not-found',
398 USER_DISABLED: 'auth/user-disabled',
399 USER_MISMATCH: 'auth/user-mismatch',
400 USER_SIGNED_OUT: 'auth/user-signed-out',
401 WEAK_PASSWORD: 'auth/weak-password',
402 WEB_STORAGE_UNSUPPORTED: 'auth/web-storage-unsupported',
403 ALREADY_INITIALIZED: 'auth/already-initialized'
404};
405
406/**
407 * @license
408 * Copyright 2020 Google LLC
409 *
410 * Licensed under the Apache License, Version 2.0 (the "License");
411 * you may not use this file except in compliance with the License.
412 * You may obtain a copy of the License at
413 *
414 * http://www.apache.org/licenses/LICENSE-2.0
415 *
416 * Unless required by applicable law or agreed to in writing, software
417 * distributed under the License is distributed on an "AS IS" BASIS,
418 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
419 * See the License for the specific language governing permissions and
420 * limitations under the License.
421 */
422const logClient = new Logger('@firebase/auth');
423function _logError(msg, ...args) {
424 if (logClient.logLevel <= LogLevel.ERROR) {
425 logClient.error(`Auth (${SDK_VERSION}): ${msg}`, ...args);
426 }
427}
428
429/**
430 * @license
431 * Copyright 2020 Google LLC
432 *
433 * Licensed under the Apache License, Version 2.0 (the "License");
434 * you may not use this file except in compliance with the License.
435 * You may obtain a copy of the License at
436 *
437 * http://www.apache.org/licenses/LICENSE-2.0
438 *
439 * Unless required by applicable law or agreed to in writing, software
440 * distributed under the License is distributed on an "AS IS" BASIS,
441 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
442 * See the License for the specific language governing permissions and
443 * limitations under the License.
444 */
445function _fail(authOrCode, ...rest) {
446 throw createErrorInternal(authOrCode, ...rest);
447}
448function _createError(authOrCode, ...rest) {
449 return createErrorInternal(authOrCode, ...rest);
450}
451function _errorWithCustomMessage(auth, code, message) {
452 const errorMap = Object.assign(Object.assign({}, prodErrorMap()), { [code]: message });
453 const factory = new ErrorFactory('auth', 'Firebase', errorMap);
454 return factory.create(code, {
455 appName: auth.name,
456 });
457}
458function createErrorInternal(authOrCode, ...rest) {
459 if (typeof authOrCode !== 'string') {
460 const code = rest[0];
461 const fullParams = [...rest.slice(1)];
462 if (fullParams[0]) {
463 fullParams[0].appName = authOrCode.name;
464 }
465 return authOrCode._errorFactory.create(code, ...fullParams);
466 }
467 return _DEFAULT_AUTH_ERROR_FACTORY.create(authOrCode, ...rest);
468}
469function _assert(assertion, authOrCode, ...rest) {
470 if (!assertion) {
471 throw createErrorInternal(authOrCode, ...rest);
472 }
473}
474/**
475 * Unconditionally fails, throwing an internal error with the given message.
476 *
477 * @param failure type of failure encountered
478 * @throws Error
479 */
480function debugFail(failure) {
481 // Log the failure in addition to throw an exception, just in case the
482 // exception is swallowed.
483 const message = `INTERNAL ASSERTION FAILED: ` + failure;
484 _logError(message);
485 // NOTE: We don't use FirebaseError here because these are internal failures
486 // that cannot be handled by the user. (Also it would create a circular
487 // dependency between the error and assert modules which doesn't work.)
488 throw new Error(message);
489}
490/**
491 * Fails if the given assertion condition is false, throwing an Error with the
492 * given message if it did.
493 *
494 * @param assertion
495 * @param message
496 */
497function debugAssert(assertion, message) {
498 if (!assertion) {
499 debugFail(message);
500 }
501}
502
503/**
504 * @license
505 * Copyright 2020 Google LLC
506 *
507 * Licensed under the Apache License, Version 2.0 (the "License");
508 * you may not use this file except in compliance with the License.
509 * You may obtain a copy of the License at
510 *
511 * http://www.apache.org/licenses/LICENSE-2.0
512 *
513 * Unless required by applicable law or agreed to in writing, software
514 * distributed under the License is distributed on an "AS IS" BASIS,
515 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
516 * See the License for the specific language governing permissions and
517 * limitations under the License.
518 */
519const instanceCache = new Map();
520function _getInstance(cls) {
521 debugAssert(cls instanceof Function, 'Expected a class definition');
522 let instance = instanceCache.get(cls);
523 if (instance) {
524 debugAssert(instance instanceof cls, 'Instance stored in cache mismatched with class');
525 return instance;
526 }
527 instance = new cls();
528 instanceCache.set(cls, instance);
529 return instance;
530}
531
532/**
533 * @license
534 * Copyright 2020 Google LLC
535 *
536 * Licensed under the Apache License, Version 2.0 (the "License");
537 * you may not use this file except in compliance with the License.
538 * You may obtain a copy of the License at
539 *
540 * http://www.apache.org/licenses/LICENSE-2.0
541 *
542 * Unless required by applicable law or agreed to in writing, software
543 * distributed under the License is distributed on an "AS IS" BASIS,
544 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
545 * See the License for the specific language governing permissions and
546 * limitations under the License.
547 */
548/**
549 * Initializes an {@link Auth} instance with fine-grained control over
550 * {@link Dependencies}.
551 *
552 * @remarks
553 *
554 * This function allows more control over the {@link Auth} instance than
555 * {@link getAuth}. `getAuth` uses platform-specific defaults to supply
556 * the {@link Dependencies}. In general, `getAuth` is the easiest way to
557 * initialize Auth and works for most use cases. Use `initializeAuth` if you
558 * need control over which persistence layer is used, or to minimize bundle
559 * size if you're not using either `signInWithPopup` or `signInWithRedirect`.
560 *
561 * For example, if your app only uses anonymous accounts and you only want
562 * accounts saved for the current session, initialize `Auth` with:
563 *
564 * ```js
565 * const auth = initializeAuth(app, {
566 * persistence: browserSessionPersistence,
567 * popupRedirectResolver: undefined,
568 * });
569 * ```
570 *
571 * @public
572 */
573function initializeAuth(app, deps) {
574 const provider = _getProvider(app, 'auth');
575 if (provider.isInitialized()) {
576 const auth = provider.getImmediate();
577 const initialOptions = provider.getOptions();
578 if (deepEqual(initialOptions, deps !== null && deps !== void 0 ? deps : {})) {
579 return auth;
580 }
581 else {
582 _fail(auth, "already-initialized" /* ALREADY_INITIALIZED */);
583 }
584 }
585 const auth = provider.initialize({ options: deps });
586 return auth;
587}
588function _initializeAuthInstance(auth, deps) {
589 const persistence = (deps === null || deps === void 0 ? void 0 : deps.persistence) || [];
590 const hierarchy = (Array.isArray(persistence) ? persistence : [persistence]).map(_getInstance);
591 if (deps === null || deps === void 0 ? void 0 : deps.errorMap) {
592 auth._updateErrorMap(deps.errorMap);
593 }
594 // This promise is intended to float; auth initialization happens in the
595 // background, meanwhile the auth object may be used by the app.
596 // eslint-disable-next-line @typescript-eslint/no-floating-promises
597 auth._initializeWithPersistence(hierarchy, deps === null || deps === void 0 ? void 0 : deps.popupRedirectResolver);
598}
599
600/**
601 * @license
602 * Copyright 2020 Google LLC
603 *
604 * Licensed under the Apache License, Version 2.0 (the "License");
605 * you may not use this file except in compliance with the License.
606 * You may obtain a copy of the License at
607 *
608 * http://www.apache.org/licenses/LICENSE-2.0
609 *
610 * Unless required by applicable law or agreed to in writing, software
611 * distributed under the License is distributed on an "AS IS" BASIS,
612 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
613 * See the License for the specific language governing permissions and
614 * limitations under the License.
615 */
616function _getCurrentUrl() {
617 var _a;
618 return (typeof self !== 'undefined' && ((_a = self.location) === null || _a === void 0 ? void 0 : _a.href)) || '';
619}
620function _isHttpOrHttps() {
621 return _getCurrentScheme() === 'http:' || _getCurrentScheme() === 'https:';
622}
623function _getCurrentScheme() {
624 var _a;
625 return (typeof self !== 'undefined' && ((_a = self.location) === null || _a === void 0 ? void 0 : _a.protocol)) || null;
626}
627
628/**
629 * @license
630 * Copyright 2020 Google LLC
631 *
632 * Licensed under the Apache License, Version 2.0 (the "License");
633 * you may not use this file except in compliance with the License.
634 * You may obtain a copy of the License at
635 *
636 * http://www.apache.org/licenses/LICENSE-2.0
637 *
638 * Unless required by applicable law or agreed to in writing, software
639 * distributed under the License is distributed on an "AS IS" BASIS,
640 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
641 * See the License for the specific language governing permissions and
642 * limitations under the License.
643 */
644/**
645 * Determine whether the browser is working online
646 */
647function _isOnline() {
648 if (typeof navigator !== 'undefined' &&
649 navigator &&
650 'onLine' in navigator &&
651 typeof navigator.onLine === 'boolean' &&
652 // Apply only for traditional web apps and Chrome extensions.
653 // This is especially true for Cordova apps which have unreliable
654 // navigator.onLine behavior unless cordova-plugin-network-information is
655 // installed which overwrites the native navigator.onLine value and
656 // defines navigator.connection.
657 (_isHttpOrHttps() || isBrowserExtension() || 'connection' in navigator)) {
658 return navigator.onLine;
659 }
660 // If we can't determine the state, assume it is online.
661 return true;
662}
663function _getUserLanguage() {
664 if (typeof navigator === 'undefined') {
665 return null;
666 }
667 const navigatorLanguage = navigator;
668 return (
669 // Most reliable, but only supported in Chrome/Firefox.
670 (navigatorLanguage.languages && navigatorLanguage.languages[0]) ||
671 // Supported in most browsers, but returns the language of the browser
672 // UI, not the language set in browser settings.
673 navigatorLanguage.language ||
674 // Couldn't determine language.
675 null);
676}
677
678/**
679 * @license
680 * Copyright 2020 Google LLC
681 *
682 * Licensed under the Apache License, Version 2.0 (the "License");
683 * you may not use this file except in compliance with the License.
684 * You may obtain a copy of the License at
685 *
686 * http://www.apache.org/licenses/LICENSE-2.0
687 *
688 * Unless required by applicable law or agreed to in writing, software
689 * distributed under the License is distributed on an "AS IS" BASIS,
690 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
691 * See the License for the specific language governing permissions and
692 * limitations under the License.
693 */
694/**
695 * A structure to help pick between a range of long and short delay durations
696 * depending on the current environment. In general, the long delay is used for
697 * mobile environments whereas short delays are used for desktop environments.
698 */
699class Delay {
700 constructor(shortDelay, longDelay) {
701 this.shortDelay = shortDelay;
702 this.longDelay = longDelay;
703 // Internal error when improperly initialized.
704 debugAssert(longDelay > shortDelay, 'Short delay should be less than long delay!');
705 this.isMobile = isMobileCordova() || isReactNative();
706 }
707 get() {
708 if (!_isOnline()) {
709 // Pick the shorter timeout.
710 return Math.min(5000 /* OFFLINE */, this.shortDelay);
711 }
712 // If running in a mobile environment, return the long delay, otherwise
713 // return the short delay.
714 // This could be improved in the future to dynamically change based on other
715 // variables instead of just reading the current environment.
716 return this.isMobile ? this.longDelay : this.shortDelay;
717 }
718}
719
720/**
721 * @license
722 * Copyright 2020 Google LLC
723 *
724 * Licensed under the Apache License, Version 2.0 (the "License");
725 * you may not use this file except in compliance with the License.
726 * You may obtain a copy of the License at
727 *
728 * http://www.apache.org/licenses/LICENSE-2.0
729 *
730 * Unless required by applicable law or agreed to in writing, software
731 * distributed under the License is distributed on an "AS IS" BASIS,
732 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
733 * See the License for the specific language governing permissions and
734 * limitations under the License.
735 */
736function _emulatorUrl(config, path) {
737 debugAssert(config.emulator, 'Emulator should always be set here');
738 const { url } = config.emulator;
739 if (!path) {
740 return url;
741 }
742 return `${url}${path.startsWith('/') ? path.slice(1) : path}`;
743}
744
745/**
746 * @license
747 * Copyright 2020 Google LLC
748 *
749 * Licensed under the Apache License, Version 2.0 (the "License");
750 * you may not use this file except in compliance with the License.
751 * You may obtain a copy of the License at
752 *
753 * http://www.apache.org/licenses/LICENSE-2.0
754 *
755 * Unless required by applicable law or agreed to in writing, software
756 * distributed under the License is distributed on an "AS IS" BASIS,
757 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
758 * See the License for the specific language governing permissions and
759 * limitations under the License.
760 */
761class FetchProvider {
762 static initialize(fetchImpl, headersImpl, responseImpl) {
763 this.fetchImpl = fetchImpl;
764 if (headersImpl) {
765 this.headersImpl = headersImpl;
766 }
767 if (responseImpl) {
768 this.responseImpl = responseImpl;
769 }
770 }
771 static fetch() {
772 if (this.fetchImpl) {
773 return this.fetchImpl;
774 }
775 if (typeof self !== 'undefined' && 'fetch' in self) {
776 return self.fetch;
777 }
778 debugFail('Could not find fetch implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
779 }
780 static headers() {
781 if (this.headersImpl) {
782 return this.headersImpl;
783 }
784 if (typeof self !== 'undefined' && 'Headers' in self) {
785 return self.Headers;
786 }
787 debugFail('Could not find Headers implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
788 }
789 static response() {
790 if (this.responseImpl) {
791 return this.responseImpl;
792 }
793 if (typeof self !== 'undefined' && 'Response' in self) {
794 return self.Response;
795 }
796 debugFail('Could not find Response implementation, make sure you call FetchProvider.initialize() with an appropriate polyfill');
797 }
798}
799
800/**
801 * @license
802 * Copyright 2020 Google LLC
803 *
804 * Licensed under the Apache License, Version 2.0 (the "License");
805 * you may not use this file except in compliance with the License.
806 * You may obtain a copy of the License at
807 *
808 * http://www.apache.org/licenses/LICENSE-2.0
809 *
810 * Unless required by applicable law or agreed to in writing, software
811 * distributed under the License is distributed on an "AS IS" BASIS,
812 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
813 * See the License for the specific language governing permissions and
814 * limitations under the License.
815 */
816/**
817 * Map from errors returned by the server to errors to developer visible errors
818 */
819const SERVER_ERROR_MAP = {
820 // Custom token errors.
821 ["CREDENTIAL_MISMATCH" /* CREDENTIAL_MISMATCH */]: "custom-token-mismatch" /* CREDENTIAL_MISMATCH */,
822 // This can only happen if the SDK sends a bad request.
823 ["MISSING_CUSTOM_TOKEN" /* MISSING_CUSTOM_TOKEN */]: "internal-error" /* INTERNAL_ERROR */,
824 // Create Auth URI errors.
825 ["INVALID_IDENTIFIER" /* INVALID_IDENTIFIER */]: "invalid-email" /* INVALID_EMAIL */,
826 // This can only happen if the SDK sends a bad request.
827 ["MISSING_CONTINUE_URI" /* MISSING_CONTINUE_URI */]: "internal-error" /* INTERNAL_ERROR */,
828 // Sign in with email and password errors (some apply to sign up too).
829 ["INVALID_PASSWORD" /* INVALID_PASSWORD */]: "wrong-password" /* INVALID_PASSWORD */,
830 // This can only happen if the SDK sends a bad request.
831 ["MISSING_PASSWORD" /* MISSING_PASSWORD */]: "internal-error" /* INTERNAL_ERROR */,
832 // Sign up with email and password errors.
833 ["EMAIL_EXISTS" /* EMAIL_EXISTS */]: "email-already-in-use" /* EMAIL_EXISTS */,
834 ["PASSWORD_LOGIN_DISABLED" /* PASSWORD_LOGIN_DISABLED */]: "operation-not-allowed" /* OPERATION_NOT_ALLOWED */,
835 // Verify assertion for sign in with credential errors:
836 ["INVALID_IDP_RESPONSE" /* INVALID_IDP_RESPONSE */]: "invalid-credential" /* INVALID_IDP_RESPONSE */,
837 ["INVALID_PENDING_TOKEN" /* INVALID_PENDING_TOKEN */]: "invalid-credential" /* INVALID_IDP_RESPONSE */,
838 ["FEDERATED_USER_ID_ALREADY_LINKED" /* FEDERATED_USER_ID_ALREADY_LINKED */]: "credential-already-in-use" /* CREDENTIAL_ALREADY_IN_USE */,
839 // This can only happen if the SDK sends a bad request.
840 ["MISSING_REQ_TYPE" /* MISSING_REQ_TYPE */]: "internal-error" /* INTERNAL_ERROR */,
841 // Send Password reset email errors:
842 ["EMAIL_NOT_FOUND" /* EMAIL_NOT_FOUND */]: "user-not-found" /* USER_DELETED */,
843 ["RESET_PASSWORD_EXCEED_LIMIT" /* RESET_PASSWORD_EXCEED_LIMIT */]: "too-many-requests" /* TOO_MANY_ATTEMPTS_TRY_LATER */,
844 ["EXPIRED_OOB_CODE" /* EXPIRED_OOB_CODE */]: "expired-action-code" /* EXPIRED_OOB_CODE */,
845 ["INVALID_OOB_CODE" /* INVALID_OOB_CODE */]: "invalid-action-code" /* INVALID_OOB_CODE */,
846 // This can only happen if the SDK sends a bad request.
847 ["MISSING_OOB_CODE" /* MISSING_OOB_CODE */]: "internal-error" /* INTERNAL_ERROR */,
848 // Operations that require ID token in request:
849 ["CREDENTIAL_TOO_OLD_LOGIN_AGAIN" /* CREDENTIAL_TOO_OLD_LOGIN_AGAIN */]: "requires-recent-login" /* CREDENTIAL_TOO_OLD_LOGIN_AGAIN */,
850 ["INVALID_ID_TOKEN" /* INVALID_ID_TOKEN */]: "invalid-user-token" /* INVALID_AUTH */,
851 ["TOKEN_EXPIRED" /* TOKEN_EXPIRED */]: "user-token-expired" /* TOKEN_EXPIRED */,
852 ["USER_NOT_FOUND" /* USER_NOT_FOUND */]: "user-token-expired" /* TOKEN_EXPIRED */,
853 // Other errors.
854 ["TOO_MANY_ATTEMPTS_TRY_LATER" /* TOO_MANY_ATTEMPTS_TRY_LATER */]: "too-many-requests" /* TOO_MANY_ATTEMPTS_TRY_LATER */,
855 // Phone Auth related errors.
856 ["INVALID_CODE" /* INVALID_CODE */]: "invalid-verification-code" /* INVALID_CODE */,
857 ["INVALID_SESSION_INFO" /* INVALID_SESSION_INFO */]: "invalid-verification-id" /* INVALID_SESSION_INFO */,
858 ["INVALID_TEMPORARY_PROOF" /* INVALID_TEMPORARY_PROOF */]: "invalid-credential" /* INVALID_IDP_RESPONSE */,
859 ["MISSING_SESSION_INFO" /* MISSING_SESSION_INFO */]: "missing-verification-id" /* MISSING_SESSION_INFO */,
860 ["SESSION_EXPIRED" /* SESSION_EXPIRED */]: "code-expired" /* CODE_EXPIRED */,
861 // Other action code errors when additional settings passed.
862 // MISSING_CONTINUE_URI is getting mapped to INTERNAL_ERROR above.
863 // This is OK as this error will be caught by client side validation.
864 ["MISSING_ANDROID_PACKAGE_NAME" /* MISSING_ANDROID_PACKAGE_NAME */]: "missing-android-pkg-name" /* MISSING_ANDROID_PACKAGE_NAME */,
865 ["UNAUTHORIZED_DOMAIN" /* UNAUTHORIZED_DOMAIN */]: "unauthorized-continue-uri" /* UNAUTHORIZED_DOMAIN */,
866 // getProjectConfig errors when clientId is passed.
867 ["INVALID_OAUTH_CLIENT_ID" /* INVALID_OAUTH_CLIENT_ID */]: "invalid-oauth-client-id" /* INVALID_OAUTH_CLIENT_ID */,
868 // User actions (sign-up or deletion) disabled errors.
869 ["ADMIN_ONLY_OPERATION" /* ADMIN_ONLY_OPERATION */]: "admin-restricted-operation" /* ADMIN_ONLY_OPERATION */,
870 // Multi factor related errors.
871 ["INVALID_MFA_PENDING_CREDENTIAL" /* INVALID_MFA_PENDING_CREDENTIAL */]: "invalid-multi-factor-session" /* INVALID_MFA_SESSION */,
872 ["MFA_ENROLLMENT_NOT_FOUND" /* MFA_ENROLLMENT_NOT_FOUND */]: "multi-factor-info-not-found" /* MFA_INFO_NOT_FOUND */,
873 ["MISSING_MFA_ENROLLMENT_ID" /* MISSING_MFA_ENROLLMENT_ID */]: "missing-multi-factor-info" /* MISSING_MFA_INFO */,
874 ["MISSING_MFA_PENDING_CREDENTIAL" /* MISSING_MFA_PENDING_CREDENTIAL */]: "missing-multi-factor-session" /* MISSING_MFA_SESSION */,
875 ["SECOND_FACTOR_EXISTS" /* SECOND_FACTOR_EXISTS */]: "second-factor-already-in-use" /* SECOND_FACTOR_ALREADY_ENROLLED */,
876 ["SECOND_FACTOR_LIMIT_EXCEEDED" /* SECOND_FACTOR_LIMIT_EXCEEDED */]: "maximum-second-factor-count-exceeded" /* SECOND_FACTOR_LIMIT_EXCEEDED */,
877 // Blocking functions related errors.
878 ["BLOCKING_FUNCTION_ERROR_RESPONSE" /* BLOCKING_FUNCTION_ERROR_RESPONSE */]: "internal-error" /* INTERNAL_ERROR */,
879};
880
881/**
882 * @license
883 * Copyright 2020 Google LLC
884 *
885 * Licensed under the Apache License, Version 2.0 (the "License");
886 * you may not use this file except in compliance with the License.
887 * You may obtain a copy of the License at
888 *
889 * http://www.apache.org/licenses/LICENSE-2.0
890 *
891 * Unless required by applicable law or agreed to in writing, software
892 * distributed under the License is distributed on an "AS IS" BASIS,
893 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
894 * See the License for the specific language governing permissions and
895 * limitations under the License.
896 */
897const DEFAULT_API_TIMEOUT_MS = new Delay(30000, 60000);
898function _addTidIfNecessary(auth, request) {
899 if (auth.tenantId && !request.tenantId) {
900 return Object.assign(Object.assign({}, request), { tenantId: auth.tenantId });
901 }
902 return request;
903}
904async function _performApiRequest(auth, method, path, request, customErrorMap = {}) {
905 return _performFetchWithErrorHandling(auth, customErrorMap, async () => {
906 let body = {};
907 let params = {};
908 if (request) {
909 if (method === "GET" /* GET */) {
910 params = request;
911 }
912 else {
913 body = {
914 body: JSON.stringify(request)
915 };
916 }
917 }
918 const query = querystring(Object.assign({ key: auth.config.apiKey }, params)).slice(1);
919 const headers = await auth._getAdditionalHeaders();
920 headers["Content-Type" /* CONTENT_TYPE */] = 'application/json';
921 if (auth.languageCode) {
922 headers["X-Firebase-Locale" /* X_FIREBASE_LOCALE */] = auth.languageCode;
923 }
924 return FetchProvider.fetch()(_getFinalTarget(auth, auth.config.apiHost, path, query), Object.assign({ method,
925 headers, referrerPolicy: 'no-referrer' }, body));
926 });
927}
928async function _performFetchWithErrorHandling(auth, customErrorMap, fetchFn) {
929 auth._canInitEmulator = false;
930 const errorMap = Object.assign(Object.assign({}, SERVER_ERROR_MAP), customErrorMap);
931 try {
932 const networkTimeout = new NetworkTimeout(auth);
933 const response = await Promise.race([
934 fetchFn(),
935 networkTimeout.promise
936 ]);
937 // If we've reached this point, the fetch succeeded and the networkTimeout
938 // didn't throw; clear the network timeout delay so that Node won't hang
939 networkTimeout.clearNetworkTimeout();
940 const json = await response.json();
941 if ('needConfirmation' in json) {
942 throw _makeTaggedError(auth, "account-exists-with-different-credential" /* NEED_CONFIRMATION */, json);
943 }
944 if (response.ok && !('errorMessage' in json)) {
945 return json;
946 }
947 else {
948 const errorMessage = response.ok ? json.errorMessage : json.error.message;
949 const [serverErrorCode, serverErrorMessage] = errorMessage.split(' : ');
950 if (serverErrorCode === "FEDERATED_USER_ID_ALREADY_LINKED" /* FEDERATED_USER_ID_ALREADY_LINKED */) {
951 throw _makeTaggedError(auth, "credential-already-in-use" /* CREDENTIAL_ALREADY_IN_USE */, json);
952 }
953 else if (serverErrorCode === "EMAIL_EXISTS" /* EMAIL_EXISTS */) {
954 throw _makeTaggedError(auth, "email-already-in-use" /* EMAIL_EXISTS */, json);
955 }
956 else if (serverErrorCode === "USER_DISABLED" /* USER_DISABLED */) {
957 throw _makeTaggedError(auth, "user-disabled" /* USER_DISABLED */, json);
958 }
959 const authError = errorMap[serverErrorCode] ||
960 serverErrorCode
961 .toLowerCase()
962 .replace(/[_\s]+/g, '-');
963 if (serverErrorMessage) {
964 throw _errorWithCustomMessage(auth, authError, serverErrorMessage);
965 }
966 else {
967 _fail(auth, authError);
968 }
969 }
970 }
971 catch (e) {
972 if (e instanceof FirebaseError) {
973 throw e;
974 }
975 _fail(auth, "network-request-failed" /* NETWORK_REQUEST_FAILED */);
976 }
977}
978async function _performSignInRequest(auth, method, path, request, customErrorMap = {}) {
979 const serverResponse = (await _performApiRequest(auth, method, path, request, customErrorMap));
980 if ('mfaPendingCredential' in serverResponse) {
981 _fail(auth, "multi-factor-auth-required" /* MFA_REQUIRED */, {
982 _serverResponse: serverResponse
983 });
984 }
985 return serverResponse;
986}
987function _getFinalTarget(auth, host, path, query) {
988 const base = `${host}${path}?${query}`;
989 if (!auth.config.emulator) {
990 return `${auth.config.apiScheme}://${base}`;
991 }
992 return _emulatorUrl(auth.config, base);
993}
994class NetworkTimeout {
995 constructor(auth) {
996 this.auth = auth;
997 // Node timers and browser timers are fundamentally incompatible, but we
998 // don't care about the value here
999 // eslint-disable-next-line @typescript-eslint/no-explicit-any
1000 this.timer = null;
1001 this.promise = new Promise((_, reject) => {
1002 this.timer = setTimeout(() => {
1003 return reject(_createError(this.auth, "network-request-failed" /* NETWORK_REQUEST_FAILED */));
1004 }, DEFAULT_API_TIMEOUT_MS.get());
1005 });
1006 }
1007 clearNetworkTimeout() {
1008 clearTimeout(this.timer);
1009 }
1010}
1011function _makeTaggedError(auth, code, response) {
1012 const errorParams = {
1013 appName: auth.name
1014 };
1015 if (response.email) {
1016 errorParams.email = response.email;
1017 }
1018 if (response.phoneNumber) {
1019 errorParams.phoneNumber = response.phoneNumber;
1020 }
1021 const error = _createError(auth, code, errorParams);
1022 // We know customData is defined on error because errorParams is defined
1023 error.customData._tokenResponse = response;
1024 return error;
1025}
1026
1027/**
1028 * @license
1029 * Copyright 2020 Google LLC
1030 *
1031 * Licensed under the Apache License, Version 2.0 (the "License");
1032 * you may not use this file except in compliance with the License.
1033 * You may obtain a copy of the License at
1034 *
1035 * http://www.apache.org/licenses/LICENSE-2.0
1036 *
1037 * Unless required by applicable law or agreed to in writing, software
1038 * distributed under the License is distributed on an "AS IS" BASIS,
1039 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1040 * See the License for the specific language governing permissions and
1041 * limitations under the License.
1042 */
1043async function deleteAccount(auth, request) {
1044 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:delete" /* DELETE_ACCOUNT */, request);
1045}
1046async function deleteLinkedAccounts(auth, request) {
1047 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:update" /* SET_ACCOUNT_INFO */, request);
1048}
1049async function getAccountInfo(auth, request) {
1050 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:lookup" /* GET_ACCOUNT_INFO */, request);
1051}
1052
1053/**
1054 * @license
1055 * Copyright 2020 Google LLC
1056 *
1057 * Licensed under the Apache License, Version 2.0 (the "License");
1058 * you may not use this file except in compliance with the License.
1059 * You may obtain a copy of the License at
1060 *
1061 * http://www.apache.org/licenses/LICENSE-2.0
1062 *
1063 * Unless required by applicable law or agreed to in writing, software
1064 * distributed under the License is distributed on an "AS IS" BASIS,
1065 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1066 * See the License for the specific language governing permissions and
1067 * limitations under the License.
1068 */
1069function utcTimestampToDateString(utcTimestamp) {
1070 if (!utcTimestamp) {
1071 return undefined;
1072 }
1073 try {
1074 // Convert to date object.
1075 const date = new Date(Number(utcTimestamp));
1076 // Test date is valid.
1077 if (!isNaN(date.getTime())) {
1078 // Convert to UTC date string.
1079 return date.toUTCString();
1080 }
1081 }
1082 catch (e) {
1083 // Do nothing. undefined will be returned.
1084 }
1085 return undefined;
1086}
1087
1088/**
1089 * @license
1090 * Copyright 2020 Google LLC
1091 *
1092 * Licensed under the Apache License, Version 2.0 (the "License");
1093 * you may not use this file except in compliance with the License.
1094 * You may obtain a copy of the License at
1095 *
1096 * http://www.apache.org/licenses/LICENSE-2.0
1097 *
1098 * Unless required by applicable law or agreed to in writing, software
1099 * distributed under the License is distributed on an "AS IS" BASIS,
1100 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1101 * See the License for the specific language governing permissions and
1102 * limitations under the License.
1103 */
1104/**
1105 * Returns a JSON Web Token (JWT) used to identify the user to a Firebase service.
1106 *
1107 * @remarks
1108 * Returns the current token if it has not expired or if it will not expire in the next five
1109 * minutes. Otherwise, this will refresh the token and return a new one.
1110 *
1111 * @param user - The user.
1112 * @param forceRefresh - Force refresh regardless of token expiration.
1113 *
1114 * @public
1115 */
1116function getIdToken(user, forceRefresh = false) {
1117 return getModularInstance(user).getIdToken(forceRefresh);
1118}
1119/**
1120 * Returns a deserialized JSON Web Token (JWT) used to identitfy the user to a Firebase service.
1121 *
1122 * @remarks
1123 * Returns the current token if it has not expired or if it will not expire in the next five
1124 * minutes. Otherwise, this will refresh the token and return a new one.
1125 *
1126 * @param user - The user.
1127 * @param forceRefresh - Force refresh regardless of token expiration.
1128 *
1129 * @public
1130 */
1131async function getIdTokenResult(user, forceRefresh = false) {
1132 const userInternal = getModularInstance(user);
1133 const token = await userInternal.getIdToken(forceRefresh);
1134 const claims = _parseToken(token);
1135 _assert(claims && claims.exp && claims.auth_time && claims.iat, userInternal.auth, "internal-error" /* INTERNAL_ERROR */);
1136 const firebase = typeof claims.firebase === 'object' ? claims.firebase : undefined;
1137 const signInProvider = firebase === null || firebase === void 0 ? void 0 : firebase['sign_in_provider'];
1138 return {
1139 claims,
1140 token,
1141 authTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.auth_time)),
1142 issuedAtTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.iat)),
1143 expirationTime: utcTimestampToDateString(secondsStringToMilliseconds(claims.exp)),
1144 signInProvider: signInProvider || null,
1145 signInSecondFactor: (firebase === null || firebase === void 0 ? void 0 : firebase['sign_in_second_factor']) || null
1146 };
1147}
1148function secondsStringToMilliseconds(seconds) {
1149 return Number(seconds) * 1000;
1150}
1151function _parseToken(token) {
1152 var _a;
1153 const [algorithm, payload, signature] = token.split('.');
1154 if (algorithm === undefined ||
1155 payload === undefined ||
1156 signature === undefined) {
1157 _logError('JWT malformed, contained fewer than 3 sections');
1158 return null;
1159 }
1160 try {
1161 const decoded = base64Decode(payload);
1162 if (!decoded) {
1163 _logError('Failed to decode base64 JWT payload');
1164 return null;
1165 }
1166 return JSON.parse(decoded);
1167 }
1168 catch (e) {
1169 _logError('Caught error parsing JWT payload as JSON', (_a = e) === null || _a === void 0 ? void 0 : _a.toString());
1170 return null;
1171 }
1172}
1173/**
1174 * Extract expiresIn TTL from a token by subtracting the expiration from the issuance.
1175 */
1176function _tokenExpiresIn(token) {
1177 const parsedToken = _parseToken(token);
1178 _assert(parsedToken, "internal-error" /* INTERNAL_ERROR */);
1179 _assert(typeof parsedToken.exp !== 'undefined', "internal-error" /* INTERNAL_ERROR */);
1180 _assert(typeof parsedToken.iat !== 'undefined', "internal-error" /* INTERNAL_ERROR */);
1181 return Number(parsedToken.exp) - Number(parsedToken.iat);
1182}
1183
1184/**
1185 * @license
1186 * Copyright 2020 Google LLC
1187 *
1188 * Licensed under the Apache License, Version 2.0 (the "License");
1189 * you may not use this file except in compliance with the License.
1190 * You may obtain a copy of the License at
1191 *
1192 * http://www.apache.org/licenses/LICENSE-2.0
1193 *
1194 * Unless required by applicable law or agreed to in writing, software
1195 * distributed under the License is distributed on an "AS IS" BASIS,
1196 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1197 * See the License for the specific language governing permissions and
1198 * limitations under the License.
1199 */
1200async function _logoutIfInvalidated(user, promise, bypassAuthState = false) {
1201 if (bypassAuthState) {
1202 return promise;
1203 }
1204 try {
1205 return await promise;
1206 }
1207 catch (e) {
1208 if (e instanceof FirebaseError && isUserInvalidated(e)) {
1209 if (user.auth.currentUser === user) {
1210 await user.auth.signOut();
1211 }
1212 }
1213 throw e;
1214 }
1215}
1216function isUserInvalidated({ code }) {
1217 return (code === `auth/${"user-disabled" /* USER_DISABLED */}` ||
1218 code === `auth/${"user-token-expired" /* TOKEN_EXPIRED */}`);
1219}
1220
1221/**
1222 * @license
1223 * Copyright 2020 Google LLC
1224 *
1225 * Licensed under the Apache License, Version 2.0 (the "License");
1226 * you may not use this file except in compliance with the License.
1227 * You may obtain a copy of the License at
1228 *
1229 * http://www.apache.org/licenses/LICENSE-2.0
1230 *
1231 * Unless required by applicable law or agreed to in writing, software
1232 * distributed under the License is distributed on an "AS IS" BASIS,
1233 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1234 * See the License for the specific language governing permissions and
1235 * limitations under the License.
1236 */
1237class ProactiveRefresh {
1238 constructor(user) {
1239 this.user = user;
1240 this.isRunning = false;
1241 // Node timers and browser timers return fundamentally different types.
1242 // We don't actually care what the value is but TS won't accept unknown and
1243 // we can't cast properly in both environments.
1244 // eslint-disable-next-line @typescript-eslint/no-explicit-any
1245 this.timerId = null;
1246 this.errorBackoff = 30000 /* RETRY_BACKOFF_MIN */;
1247 }
1248 _start() {
1249 if (this.isRunning) {
1250 return;
1251 }
1252 this.isRunning = true;
1253 this.schedule();
1254 }
1255 _stop() {
1256 if (!this.isRunning) {
1257 return;
1258 }
1259 this.isRunning = false;
1260 if (this.timerId !== null) {
1261 clearTimeout(this.timerId);
1262 }
1263 }
1264 getInterval(wasError) {
1265 var _a;
1266 if (wasError) {
1267 const interval = this.errorBackoff;
1268 this.errorBackoff = Math.min(this.errorBackoff * 2, 960000 /* RETRY_BACKOFF_MAX */);
1269 return interval;
1270 }
1271 else {
1272 // Reset the error backoff
1273 this.errorBackoff = 30000 /* RETRY_BACKOFF_MIN */;
1274 const expTime = (_a = this.user.stsTokenManager.expirationTime) !== null && _a !== void 0 ? _a : 0;
1275 const interval = expTime - Date.now() - 300000 /* OFFSET */;
1276 return Math.max(0, interval);
1277 }
1278 }
1279 schedule(wasError = false) {
1280 if (!this.isRunning) {
1281 // Just in case...
1282 return;
1283 }
1284 const interval = this.getInterval(wasError);
1285 this.timerId = setTimeout(async () => {
1286 await this.iteration();
1287 }, interval);
1288 }
1289 async iteration() {
1290 var _a;
1291 try {
1292 await this.user.getIdToken(true);
1293 }
1294 catch (e) {
1295 // Only retry on network errors
1296 if (((_a = e) === null || _a === void 0 ? void 0 : _a.code) === `auth/${"network-request-failed" /* NETWORK_REQUEST_FAILED */}`) {
1297 this.schedule(/* wasError */ true);
1298 }
1299 return;
1300 }
1301 this.schedule();
1302 }
1303}
1304
1305/**
1306 * @license
1307 * Copyright 2020 Google LLC
1308 *
1309 * Licensed under the Apache License, Version 2.0 (the "License");
1310 * you may not use this file except in compliance with the License.
1311 * You may obtain a copy of the License at
1312 *
1313 * http://www.apache.org/licenses/LICENSE-2.0
1314 *
1315 * Unless required by applicable law or agreed to in writing, software
1316 * distributed under the License is distributed on an "AS IS" BASIS,
1317 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1318 * See the License for the specific language governing permissions and
1319 * limitations under the License.
1320 */
1321class UserMetadata {
1322 constructor(createdAt, lastLoginAt) {
1323 this.createdAt = createdAt;
1324 this.lastLoginAt = lastLoginAt;
1325 this._initializeTime();
1326 }
1327 _initializeTime() {
1328 this.lastSignInTime = utcTimestampToDateString(this.lastLoginAt);
1329 this.creationTime = utcTimestampToDateString(this.createdAt);
1330 }
1331 _copy(metadata) {
1332 this.createdAt = metadata.createdAt;
1333 this.lastLoginAt = metadata.lastLoginAt;
1334 this._initializeTime();
1335 }
1336 toJSON() {
1337 return {
1338 createdAt: this.createdAt,
1339 lastLoginAt: this.lastLoginAt
1340 };
1341 }
1342}
1343
1344/**
1345 * @license
1346 * Copyright 2019 Google LLC
1347 *
1348 * Licensed under the Apache License, Version 2.0 (the "License");
1349 * you may not use this file except in compliance with the License.
1350 * You may obtain a copy of the License at
1351 *
1352 * http://www.apache.org/licenses/LICENSE-2.0
1353 *
1354 * Unless required by applicable law or agreed to in writing, software
1355 * distributed under the License is distributed on an "AS IS" BASIS,
1356 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1357 * See the License for the specific language governing permissions and
1358 * limitations under the License.
1359 */
1360async function _reloadWithoutSaving(user) {
1361 var _a;
1362 const auth = user.auth;
1363 const idToken = await user.getIdToken();
1364 const response = await _logoutIfInvalidated(user, getAccountInfo(auth, { idToken }));
1365 _assert(response === null || response === void 0 ? void 0 : response.users.length, auth, "internal-error" /* INTERNAL_ERROR */);
1366 const coreAccount = response.users[0];
1367 user._notifyReloadListener(coreAccount);
1368 const newProviderData = ((_a = coreAccount.providerUserInfo) === null || _a === void 0 ? void 0 : _a.length)
1369 ? extractProviderData(coreAccount.providerUserInfo)
1370 : [];
1371 const providerData = mergeProviderData(user.providerData, newProviderData);
1372 // Preserves the non-nonymous status of the stored user, even if no more
1373 // credentials (federated or email/password) are linked to the user. If
1374 // the user was previously anonymous, then use provider data to update.
1375 // On the other hand, if it was not anonymous before, it should never be
1376 // considered anonymous now.
1377 const oldIsAnonymous = user.isAnonymous;
1378 const newIsAnonymous = !(user.email && coreAccount.passwordHash) && !(providerData === null || providerData === void 0 ? void 0 : providerData.length);
1379 const isAnonymous = !oldIsAnonymous ? false : newIsAnonymous;
1380 const updates = {
1381 uid: coreAccount.localId,
1382 displayName: coreAccount.displayName || null,
1383 photoURL: coreAccount.photoUrl || null,
1384 email: coreAccount.email || null,
1385 emailVerified: coreAccount.emailVerified || false,
1386 phoneNumber: coreAccount.phoneNumber || null,
1387 tenantId: coreAccount.tenantId || null,
1388 providerData,
1389 metadata: new UserMetadata(coreAccount.createdAt, coreAccount.lastLoginAt),
1390 isAnonymous
1391 };
1392 Object.assign(user, updates);
1393}
1394/**
1395 * Reloads user account data, if signed in.
1396 *
1397 * @param user - The user.
1398 *
1399 * @public
1400 */
1401async function reload(user) {
1402 const userInternal = getModularInstance(user);
1403 await _reloadWithoutSaving(userInternal);
1404 // Even though the current user hasn't changed, update
1405 // current user will trigger a persistence update w/ the
1406 // new info.
1407 await userInternal.auth._persistUserIfCurrent(userInternal);
1408 userInternal.auth._notifyListenersIfCurrent(userInternal);
1409}
1410function mergeProviderData(original, newData) {
1411 const deduped = original.filter(o => !newData.some(n => n.providerId === o.providerId));
1412 return [...deduped, ...newData];
1413}
1414function extractProviderData(providers) {
1415 return providers.map((_a) => {
1416 var { providerId } = _a, provider = __rest(_a, ["providerId"]);
1417 return {
1418 providerId,
1419 uid: provider.rawId || '',
1420 displayName: provider.displayName || null,
1421 email: provider.email || null,
1422 phoneNumber: provider.phoneNumber || null,
1423 photoURL: provider.photoUrl || null
1424 };
1425 });
1426}
1427
1428/**
1429 * @license
1430 * Copyright 2020 Google LLC
1431 *
1432 * Licensed under the Apache License, Version 2.0 (the "License");
1433 * you may not use this file except in compliance with the License.
1434 * You may obtain a copy of the License at
1435 *
1436 * http://www.apache.org/licenses/LICENSE-2.0
1437 *
1438 * Unless required by applicable law or agreed to in writing, software
1439 * distributed under the License is distributed on an "AS IS" BASIS,
1440 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1441 * See the License for the specific language governing permissions and
1442 * limitations under the License.
1443 */
1444async function requestStsToken(auth, refreshToken) {
1445 const response = await _performFetchWithErrorHandling(auth, {}, async () => {
1446 const body = querystring({
1447 'grant_type': 'refresh_token',
1448 'refresh_token': refreshToken
1449 }).slice(1);
1450 const { tokenApiHost, apiKey } = auth.config;
1451 const url = _getFinalTarget(auth, tokenApiHost, "/v1/token" /* TOKEN */, `key=${apiKey}`);
1452 const headers = await auth._getAdditionalHeaders();
1453 headers["Content-Type" /* CONTENT_TYPE */] = 'application/x-www-form-urlencoded';
1454 return FetchProvider.fetch()(url, {
1455 method: "POST" /* POST */,
1456 headers,
1457 body
1458 });
1459 });
1460 // The response comes back in snake_case. Convert to camel:
1461 return {
1462 accessToken: response.access_token,
1463 expiresIn: response.expires_in,
1464 refreshToken: response.refresh_token
1465 };
1466}
1467
1468/**
1469 * @license
1470 * Copyright 2020 Google LLC
1471 *
1472 * Licensed under the Apache License, Version 2.0 (the "License");
1473 * you may not use this file except in compliance with the License.
1474 * You may obtain a copy of the License at
1475 *
1476 * http://www.apache.org/licenses/LICENSE-2.0
1477 *
1478 * Unless required by applicable law or agreed to in writing, software
1479 * distributed under the License is distributed on an "AS IS" BASIS,
1480 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1481 * See the License for the specific language governing permissions and
1482 * limitations under the License.
1483 */
1484/**
1485 * We need to mark this class as internal explicitly to exclude it in the public typings, because
1486 * it references AuthInternal which has a circular dependency with UserInternal.
1487 *
1488 * @internal
1489 */
1490class StsTokenManager {
1491 constructor() {
1492 this.refreshToken = null;
1493 this.accessToken = null;
1494 this.expirationTime = null;
1495 }
1496 get isExpired() {
1497 return (!this.expirationTime ||
1498 Date.now() > this.expirationTime - 30000 /* TOKEN_REFRESH */);
1499 }
1500 updateFromServerResponse(response) {
1501 _assert(response.idToken, "internal-error" /* INTERNAL_ERROR */);
1502 _assert(typeof response.idToken !== 'undefined', "internal-error" /* INTERNAL_ERROR */);
1503 _assert(typeof response.refreshToken !== 'undefined', "internal-error" /* INTERNAL_ERROR */);
1504 const expiresIn = 'expiresIn' in response && typeof response.expiresIn !== 'undefined'
1505 ? Number(response.expiresIn)
1506 : _tokenExpiresIn(response.idToken);
1507 this.updateTokensAndExpiration(response.idToken, response.refreshToken, expiresIn);
1508 }
1509 async getToken(auth, forceRefresh = false) {
1510 _assert(!this.accessToken || this.refreshToken, auth, "user-token-expired" /* TOKEN_EXPIRED */);
1511 if (!forceRefresh && this.accessToken && !this.isExpired) {
1512 return this.accessToken;
1513 }
1514 if (this.refreshToken) {
1515 await this.refresh(auth, this.refreshToken);
1516 return this.accessToken;
1517 }
1518 return null;
1519 }
1520 clearRefreshToken() {
1521 this.refreshToken = null;
1522 }
1523 async refresh(auth, oldToken) {
1524 const { accessToken, refreshToken, expiresIn } = await requestStsToken(auth, oldToken);
1525 this.updateTokensAndExpiration(accessToken, refreshToken, Number(expiresIn));
1526 }
1527 updateTokensAndExpiration(accessToken, refreshToken, expiresInSec) {
1528 this.refreshToken = refreshToken || null;
1529 this.accessToken = accessToken || null;
1530 this.expirationTime = Date.now() + expiresInSec * 1000;
1531 }
1532 static fromJSON(appName, object) {
1533 const { refreshToken, accessToken, expirationTime } = object;
1534 const manager = new StsTokenManager();
1535 if (refreshToken) {
1536 _assert(typeof refreshToken === 'string', "internal-error" /* INTERNAL_ERROR */, {
1537 appName
1538 });
1539 manager.refreshToken = refreshToken;
1540 }
1541 if (accessToken) {
1542 _assert(typeof accessToken === 'string', "internal-error" /* INTERNAL_ERROR */, {
1543 appName
1544 });
1545 manager.accessToken = accessToken;
1546 }
1547 if (expirationTime) {
1548 _assert(typeof expirationTime === 'number', "internal-error" /* INTERNAL_ERROR */, {
1549 appName
1550 });
1551 manager.expirationTime = expirationTime;
1552 }
1553 return manager;
1554 }
1555 toJSON() {
1556 return {
1557 refreshToken: this.refreshToken,
1558 accessToken: this.accessToken,
1559 expirationTime: this.expirationTime
1560 };
1561 }
1562 _assign(stsTokenManager) {
1563 this.accessToken = stsTokenManager.accessToken;
1564 this.refreshToken = stsTokenManager.refreshToken;
1565 this.expirationTime = stsTokenManager.expirationTime;
1566 }
1567 _clone() {
1568 return Object.assign(new StsTokenManager(), this.toJSON());
1569 }
1570 _performRefresh() {
1571 return debugFail('not implemented');
1572 }
1573}
1574
1575/**
1576 * @license
1577 * Copyright 2020 Google LLC
1578 *
1579 * Licensed under the Apache License, Version 2.0 (the "License");
1580 * you may not use this file except in compliance with the License.
1581 * You may obtain a copy of the License at
1582 *
1583 * http://www.apache.org/licenses/LICENSE-2.0
1584 *
1585 * Unless required by applicable law or agreed to in writing, software
1586 * distributed under the License is distributed on an "AS IS" BASIS,
1587 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1588 * See the License for the specific language governing permissions and
1589 * limitations under the License.
1590 */
1591function assertStringOrUndefined(assertion, appName) {
1592 _assert(typeof assertion === 'string' || typeof assertion === 'undefined', "internal-error" /* INTERNAL_ERROR */, { appName });
1593}
1594class UserImpl {
1595 constructor(_a) {
1596 var { uid, auth, stsTokenManager } = _a, opt = __rest(_a, ["uid", "auth", "stsTokenManager"]);
1597 // For the user object, provider is always Firebase.
1598 this.providerId = "firebase" /* FIREBASE */;
1599 this.proactiveRefresh = new ProactiveRefresh(this);
1600 this.reloadUserInfo = null;
1601 this.reloadListener = null;
1602 this.uid = uid;
1603 this.auth = auth;
1604 this.stsTokenManager = stsTokenManager;
1605 this.accessToken = stsTokenManager.accessToken;
1606 this.displayName = opt.displayName || null;
1607 this.email = opt.email || null;
1608 this.emailVerified = opt.emailVerified || false;
1609 this.phoneNumber = opt.phoneNumber || null;
1610 this.photoURL = opt.photoURL || null;
1611 this.isAnonymous = opt.isAnonymous || false;
1612 this.tenantId = opt.tenantId || null;
1613 this.providerData = opt.providerData ? [...opt.providerData] : [];
1614 this.metadata = new UserMetadata(opt.createdAt || undefined, opt.lastLoginAt || undefined);
1615 }
1616 async getIdToken(forceRefresh) {
1617 const accessToken = await _logoutIfInvalidated(this, this.stsTokenManager.getToken(this.auth, forceRefresh));
1618 _assert(accessToken, this.auth, "internal-error" /* INTERNAL_ERROR */);
1619 if (this.accessToken !== accessToken) {
1620 this.accessToken = accessToken;
1621 await this.auth._persistUserIfCurrent(this);
1622 this.auth._notifyListenersIfCurrent(this);
1623 }
1624 return accessToken;
1625 }
1626 getIdTokenResult(forceRefresh) {
1627 return getIdTokenResult(this, forceRefresh);
1628 }
1629 reload() {
1630 return reload(this);
1631 }
1632 _assign(user) {
1633 if (this === user) {
1634 return;
1635 }
1636 _assert(this.uid === user.uid, this.auth, "internal-error" /* INTERNAL_ERROR */);
1637 this.displayName = user.displayName;
1638 this.photoURL = user.photoURL;
1639 this.email = user.email;
1640 this.emailVerified = user.emailVerified;
1641 this.phoneNumber = user.phoneNumber;
1642 this.isAnonymous = user.isAnonymous;
1643 this.tenantId = user.tenantId;
1644 this.providerData = user.providerData.map(userInfo => (Object.assign({}, userInfo)));
1645 this.metadata._copy(user.metadata);
1646 this.stsTokenManager._assign(user.stsTokenManager);
1647 }
1648 _clone(auth) {
1649 return new UserImpl(Object.assign(Object.assign({}, this), { auth, stsTokenManager: this.stsTokenManager._clone() }));
1650 }
1651 _onReload(callback) {
1652 // There should only ever be one listener, and that is a single instance of MultiFactorUser
1653 _assert(!this.reloadListener, this.auth, "internal-error" /* INTERNAL_ERROR */);
1654 this.reloadListener = callback;
1655 if (this.reloadUserInfo) {
1656 this._notifyReloadListener(this.reloadUserInfo);
1657 this.reloadUserInfo = null;
1658 }
1659 }
1660 _notifyReloadListener(userInfo) {
1661 if (this.reloadListener) {
1662 this.reloadListener(userInfo);
1663 }
1664 else {
1665 // If no listener is subscribed yet, save the result so it's available when they do subscribe
1666 this.reloadUserInfo = userInfo;
1667 }
1668 }
1669 _startProactiveRefresh() {
1670 this.proactiveRefresh._start();
1671 }
1672 _stopProactiveRefresh() {
1673 this.proactiveRefresh._stop();
1674 }
1675 async _updateTokensIfNecessary(response, reload = false) {
1676 let tokensRefreshed = false;
1677 if (response.idToken &&
1678 response.idToken !== this.stsTokenManager.accessToken) {
1679 this.stsTokenManager.updateFromServerResponse(response);
1680 tokensRefreshed = true;
1681 }
1682 if (reload) {
1683 await _reloadWithoutSaving(this);
1684 }
1685 await this.auth._persistUserIfCurrent(this);
1686 if (tokensRefreshed) {
1687 this.auth._notifyListenersIfCurrent(this);
1688 }
1689 }
1690 async delete() {
1691 const idToken = await this.getIdToken();
1692 await _logoutIfInvalidated(this, deleteAccount(this.auth, { idToken }));
1693 this.stsTokenManager.clearRefreshToken();
1694 // TODO: Determine if cancellable-promises are necessary to use in this class so that delete()
1695 // cancels pending actions...
1696 return this.auth.signOut();
1697 }
1698 toJSON() {
1699 return Object.assign(Object.assign({ uid: this.uid, email: this.email || undefined, emailVerified: this.emailVerified, displayName: this.displayName || undefined, isAnonymous: this.isAnonymous, photoURL: this.photoURL || undefined, phoneNumber: this.phoneNumber || undefined, tenantId: this.tenantId || undefined, providerData: this.providerData.map(userInfo => (Object.assign({}, userInfo))), stsTokenManager: this.stsTokenManager.toJSON(),
1700 // Redirect event ID must be maintained in case there is a pending
1701 // redirect event.
1702 _redirectEventId: this._redirectEventId }, this.metadata.toJSON()), {
1703 // Required for compatibility with the legacy SDK (go/firebase-auth-sdk-persistence-parsing):
1704 apiKey: this.auth.config.apiKey, appName: this.auth.name });
1705 }
1706 get refreshToken() {
1707 return this.stsTokenManager.refreshToken || '';
1708 }
1709 static _fromJSON(auth, object) {
1710 var _a, _b, _c, _d, _e, _f, _g, _h;
1711 const displayName = (_a = object.displayName) !== null && _a !== void 0 ? _a : undefined;
1712 const email = (_b = object.email) !== null && _b !== void 0 ? _b : undefined;
1713 const phoneNumber = (_c = object.phoneNumber) !== null && _c !== void 0 ? _c : undefined;
1714 const photoURL = (_d = object.photoURL) !== null && _d !== void 0 ? _d : undefined;
1715 const tenantId = (_e = object.tenantId) !== null && _e !== void 0 ? _e : undefined;
1716 const _redirectEventId = (_f = object._redirectEventId) !== null && _f !== void 0 ? _f : undefined;
1717 const createdAt = (_g = object.createdAt) !== null && _g !== void 0 ? _g : undefined;
1718 const lastLoginAt = (_h = object.lastLoginAt) !== null && _h !== void 0 ? _h : undefined;
1719 const { uid, emailVerified, isAnonymous, providerData, stsTokenManager: plainObjectTokenManager } = object;
1720 _assert(uid && plainObjectTokenManager, auth, "internal-error" /* INTERNAL_ERROR */);
1721 const stsTokenManager = StsTokenManager.fromJSON(this.name, plainObjectTokenManager);
1722 _assert(typeof uid === 'string', auth, "internal-error" /* INTERNAL_ERROR */);
1723 assertStringOrUndefined(displayName, auth.name);
1724 assertStringOrUndefined(email, auth.name);
1725 _assert(typeof emailVerified === 'boolean', auth, "internal-error" /* INTERNAL_ERROR */);
1726 _assert(typeof isAnonymous === 'boolean', auth, "internal-error" /* INTERNAL_ERROR */);
1727 assertStringOrUndefined(phoneNumber, auth.name);
1728 assertStringOrUndefined(photoURL, auth.name);
1729 assertStringOrUndefined(tenantId, auth.name);
1730 assertStringOrUndefined(_redirectEventId, auth.name);
1731 assertStringOrUndefined(createdAt, auth.name);
1732 assertStringOrUndefined(lastLoginAt, auth.name);
1733 const user = new UserImpl({
1734 uid,
1735 auth,
1736 email,
1737 emailVerified,
1738 displayName,
1739 isAnonymous,
1740 photoURL,
1741 phoneNumber,
1742 tenantId,
1743 stsTokenManager,
1744 createdAt,
1745 lastLoginAt
1746 });
1747 if (providerData && Array.isArray(providerData)) {
1748 user.providerData = providerData.map(userInfo => (Object.assign({}, userInfo)));
1749 }
1750 if (_redirectEventId) {
1751 user._redirectEventId = _redirectEventId;
1752 }
1753 return user;
1754 }
1755 /**
1756 * Initialize a User from an idToken server response
1757 * @param auth
1758 * @param idTokenResponse
1759 */
1760 static async _fromIdTokenResponse(auth, idTokenResponse, isAnonymous = false) {
1761 const stsTokenManager = new StsTokenManager();
1762 stsTokenManager.updateFromServerResponse(idTokenResponse);
1763 // Initialize the Firebase Auth user.
1764 const user = new UserImpl({
1765 uid: idTokenResponse.localId,
1766 auth,
1767 stsTokenManager,
1768 isAnonymous
1769 });
1770 // Updates the user info and data and resolves with a user instance.
1771 await _reloadWithoutSaving(user);
1772 return user;
1773 }
1774}
1775
1776/**
1777 * @license
1778 * Copyright 2019 Google LLC
1779 *
1780 * Licensed under the Apache License, Version 2.0 (the "License");
1781 * you may not use this file except in compliance with the License.
1782 * You may obtain a copy of the License at
1783 *
1784 * http://www.apache.org/licenses/LICENSE-2.0
1785 *
1786 * Unless required by applicable law or agreed to in writing, software
1787 * distributed under the License is distributed on an "AS IS" BASIS,
1788 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1789 * See the License for the specific language governing permissions and
1790 * limitations under the License.
1791 */
1792class InMemoryPersistence {
1793 constructor() {
1794 this.type = "NONE" /* NONE */;
1795 this.storage = {};
1796 }
1797 async _isAvailable() {
1798 return true;
1799 }
1800 async _set(key, value) {
1801 this.storage[key] = value;
1802 }
1803 async _get(key) {
1804 const value = this.storage[key];
1805 return value === undefined ? null : value;
1806 }
1807 async _remove(key) {
1808 delete this.storage[key];
1809 }
1810 _addListener(_key, _listener) {
1811 // Listeners are not supported for in-memory storage since it cannot be shared across windows/workers
1812 return;
1813 }
1814 _removeListener(_key, _listener) {
1815 // Listeners are not supported for in-memory storage since it cannot be shared across windows/workers
1816 return;
1817 }
1818}
1819InMemoryPersistence.type = 'NONE';
1820/**
1821 * An implementation of {@link Persistence} of type 'NONE'.
1822 *
1823 * @public
1824 */
1825const inMemoryPersistence = InMemoryPersistence;
1826
1827/**
1828 * @license
1829 * Copyright 2019 Google LLC
1830 *
1831 * Licensed under the Apache License, Version 2.0 (the "License");
1832 * you may not use this file except in compliance with the License.
1833 * You may obtain a copy of the License at
1834 *
1835 * http://www.apache.org/licenses/LICENSE-2.0
1836 *
1837 * Unless required by applicable law or agreed to in writing, software
1838 * distributed under the License is distributed on an "AS IS" BASIS,
1839 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1840 * See the License for the specific language governing permissions and
1841 * limitations under the License.
1842 */
1843function _persistenceKeyName(key, apiKey, appName) {
1844 return `${"firebase" /* PERSISTENCE */}:${key}:${apiKey}:${appName}`;
1845}
1846class PersistenceUserManager {
1847 constructor(persistence, auth, userKey) {
1848 this.persistence = persistence;
1849 this.auth = auth;
1850 this.userKey = userKey;
1851 const { config, name } = this.auth;
1852 this.fullUserKey = _persistenceKeyName(this.userKey, config.apiKey, name);
1853 this.fullPersistenceKey = _persistenceKeyName("persistence" /* PERSISTENCE_USER */, config.apiKey, name);
1854 this.boundEventHandler = auth._onStorageEvent.bind(auth);
1855 this.persistence._addListener(this.fullUserKey, this.boundEventHandler);
1856 }
1857 setCurrentUser(user) {
1858 return this.persistence._set(this.fullUserKey, user.toJSON());
1859 }
1860 async getCurrentUser() {
1861 const blob = await this.persistence._get(this.fullUserKey);
1862 return blob ? UserImpl._fromJSON(this.auth, blob) : null;
1863 }
1864 removeCurrentUser() {
1865 return this.persistence._remove(this.fullUserKey);
1866 }
1867 savePersistenceForRedirect() {
1868 return this.persistence._set(this.fullPersistenceKey, this.persistence.type);
1869 }
1870 async setPersistence(newPersistence) {
1871 if (this.persistence === newPersistence) {
1872 return;
1873 }
1874 const currentUser = await this.getCurrentUser();
1875 await this.removeCurrentUser();
1876 this.persistence = newPersistence;
1877 if (currentUser) {
1878 return this.setCurrentUser(currentUser);
1879 }
1880 }
1881 delete() {
1882 this.persistence._removeListener(this.fullUserKey, this.boundEventHandler);
1883 }
1884 static async create(auth, persistenceHierarchy, userKey = "authUser" /* AUTH_USER */) {
1885 if (!persistenceHierarchy.length) {
1886 return new PersistenceUserManager(_getInstance(inMemoryPersistence), auth, userKey);
1887 }
1888 // Eliminate any persistences that are not available
1889 const availablePersistences = (await Promise.all(persistenceHierarchy.map(async (persistence) => {
1890 if (await persistence._isAvailable()) {
1891 return persistence;
1892 }
1893 return undefined;
1894 }))).filter(persistence => persistence);
1895 // Fall back to the first persistence listed, or in memory if none available
1896 let selectedPersistence = availablePersistences[0] ||
1897 _getInstance(inMemoryPersistence);
1898 const key = _persistenceKeyName(userKey, auth.config.apiKey, auth.name);
1899 // Pull out the existing user, setting the chosen persistence to that
1900 // persistence if the user exists.
1901 let userToMigrate = null;
1902 // Note, here we check for a user in _all_ persistences, not just the
1903 // ones deemed available. If we can migrate a user out of a broken
1904 // persistence, we will (but only if that persistence supports migration).
1905 for (const persistence of persistenceHierarchy) {
1906 try {
1907 const blob = await persistence._get(key);
1908 if (blob) {
1909 const user = UserImpl._fromJSON(auth, blob); // throws for unparsable blob (wrong format)
1910 if (persistence !== selectedPersistence) {
1911 userToMigrate = user;
1912 }
1913 selectedPersistence = persistence;
1914 break;
1915 }
1916 }
1917 catch (_a) { }
1918 }
1919 // If we find the user in a persistence that does support migration, use
1920 // that migration path (of only persistences that support migration)
1921 const migrationHierarchy = availablePersistences.filter(p => p._shouldAllowMigration);
1922 // If the persistence does _not_ allow migration, just finish off here
1923 if (!selectedPersistence._shouldAllowMigration ||
1924 !migrationHierarchy.length) {
1925 return new PersistenceUserManager(selectedPersistence, auth, userKey);
1926 }
1927 selectedPersistence = migrationHierarchy[0];
1928 if (userToMigrate) {
1929 // This normally shouldn't throw since chosenPersistence.isAvailable() is true, but if it does
1930 // we'll just let it bubble to surface the error.
1931 await selectedPersistence._set(key, userToMigrate.toJSON());
1932 }
1933 // Attempt to clear the key in other persistences but ignore errors. This helps prevent issues
1934 // such as users getting stuck with a previous account after signing out and refreshing the tab.
1935 await Promise.all(persistenceHierarchy.map(async (persistence) => {
1936 if (persistence !== selectedPersistence) {
1937 try {
1938 await persistence._remove(key);
1939 }
1940 catch (_a) { }
1941 }
1942 }));
1943 return new PersistenceUserManager(selectedPersistence, auth, userKey);
1944 }
1945}
1946
1947/**
1948 * @license
1949 * Copyright 2020 Google LLC
1950 *
1951 * Licensed under the Apache License, Version 2.0 (the "License");
1952 * you may not use this file except in compliance with the License.
1953 * You may obtain a copy of the License at
1954 *
1955 * http://www.apache.org/licenses/LICENSE-2.0
1956 *
1957 * Unless required by applicable law or agreed to in writing, software
1958 * distributed under the License is distributed on an "AS IS" BASIS,
1959 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1960 * See the License for the specific language governing permissions and
1961 * limitations under the License.
1962 */
1963/**
1964 * Determine the browser for the purposes of reporting usage to the API
1965 */
1966function _getBrowserName(userAgent) {
1967 const ua = userAgent.toLowerCase();
1968 if (ua.includes('opera/') || ua.includes('opr/') || ua.includes('opios/')) {
1969 return "Opera" /* OPERA */;
1970 }
1971 else if (_isIEMobile(ua)) {
1972 // Windows phone IEMobile browser.
1973 return "IEMobile" /* IEMOBILE */;
1974 }
1975 else if (ua.includes('msie') || ua.includes('trident/')) {
1976 return "IE" /* IE */;
1977 }
1978 else if (ua.includes('edge/')) {
1979 return "Edge" /* EDGE */;
1980 }
1981 else if (_isFirefox(ua)) {
1982 return "Firefox" /* FIREFOX */;
1983 }
1984 else if (ua.includes('silk/')) {
1985 return "Silk" /* SILK */;
1986 }
1987 else if (_isBlackBerry(ua)) {
1988 // Blackberry browser.
1989 return "Blackberry" /* BLACKBERRY */;
1990 }
1991 else if (_isWebOS(ua)) {
1992 // WebOS default browser.
1993 return "Webos" /* WEBOS */;
1994 }
1995 else if (_isSafari(ua)) {
1996 return "Safari" /* SAFARI */;
1997 }
1998 else if ((ua.includes('chrome/') || _isChromeIOS(ua)) &&
1999 !ua.includes('edge/')) {
2000 return "Chrome" /* CHROME */;
2001 }
2002 else if (_isAndroid(ua)) {
2003 // Android stock browser.
2004 return "Android" /* ANDROID */;
2005 }
2006 else {
2007 // Most modern browsers have name/version at end of user agent string.
2008 const re = /([a-zA-Z\d\.]+)\/[a-zA-Z\d\.]*$/;
2009 const matches = userAgent.match(re);
2010 if ((matches === null || matches === void 0 ? void 0 : matches.length) === 2) {
2011 return matches[1];
2012 }
2013 }
2014 return "Other" /* OTHER */;
2015}
2016function _isFirefox(ua = getUA()) {
2017 return /firefox\//i.test(ua);
2018}
2019function _isSafari(userAgent = getUA()) {
2020 const ua = userAgent.toLowerCase();
2021 return (ua.includes('safari/') &&
2022 !ua.includes('chrome/') &&
2023 !ua.includes('crios/') &&
2024 !ua.includes('android'));
2025}
2026function _isChromeIOS(ua = getUA()) {
2027 return /crios\//i.test(ua);
2028}
2029function _isIEMobile(ua = getUA()) {
2030 return /iemobile/i.test(ua);
2031}
2032function _isAndroid(ua = getUA()) {
2033 return /android/i.test(ua);
2034}
2035function _isBlackBerry(ua = getUA()) {
2036 return /blackberry/i.test(ua);
2037}
2038function _isWebOS(ua = getUA()) {
2039 return /webos/i.test(ua);
2040}
2041function _isIOS(ua = getUA()) {
2042 return /iphone|ipad|ipod/i.test(ua) ||
2043 (/macintosh/i.test(ua) && /mobile/i.test(ua));
2044}
2045function _isIOS7Or8(ua = getUA()) {
2046 return (/(iPad|iPhone|iPod).*OS 7_\d/i.test(ua) ||
2047 /(iPad|iPhone|iPod).*OS 8_\d/i.test(ua));
2048}
2049function _isIE10() {
2050 return isIE() && document.documentMode === 10;
2051}
2052function _isMobileBrowser(ua = getUA()) {
2053 // TODO: implement getBrowserName equivalent for OS.
2054 return (_isIOS(ua) ||
2055 _isAndroid(ua) ||
2056 _isWebOS(ua) ||
2057 _isBlackBerry(ua) ||
2058 /windows phone/i.test(ua) ||
2059 _isIEMobile(ua));
2060}
2061function _isIframe() {
2062 try {
2063 // Check that the current window is not the top window.
2064 // If so, return true.
2065 return !!(window && window !== window.top);
2066 }
2067 catch (e) {
2068 return false;
2069 }
2070}
2071
2072/**
2073 * @license
2074 * Copyright 2020 Google LLC
2075 *
2076 * Licensed under the Apache License, Version 2.0 (the "License");
2077 * you may not use this file except in compliance with the License.
2078 * You may obtain a copy of the License at
2079 *
2080 * http://www.apache.org/licenses/LICENSE-2.0
2081 *
2082 * Unless required by applicable law or agreed to in writing, software
2083 * distributed under the License is distributed on an "AS IS" BASIS,
2084 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2085 * See the License for the specific language governing permissions and
2086 * limitations under the License.
2087 */
2088/*
2089 * Determine the SDK version string
2090 */
2091function _getClientVersion(clientPlatform, frameworks = []) {
2092 let reportedPlatform;
2093 switch (clientPlatform) {
2094 case "Browser" /* BROWSER */:
2095 // In a browser environment, report the browser name.
2096 reportedPlatform = _getBrowserName(getUA());
2097 break;
2098 case "Worker" /* WORKER */:
2099 // Technically a worker runs from a browser but we need to differentiate a
2100 // worker from a browser.
2101 // For example: Chrome-Worker/JsCore/4.9.1/FirebaseCore-web.
2102 reportedPlatform = `${_getBrowserName(getUA())}-${clientPlatform}`;
2103 break;
2104 default:
2105 reportedPlatform = clientPlatform;
2106 }
2107 const reportedFrameworks = frameworks.length
2108 ? frameworks.join(',')
2109 : 'FirebaseCore-web'; /* default value if no other framework is used */
2110 return `${reportedPlatform}/${"JsCore" /* CORE */}/${SDK_VERSION}/${reportedFrameworks}`;
2111}
2112
2113/**
2114 * @license
2115 * Copyright 2022 Google LLC
2116 *
2117 * Licensed under the Apache License, Version 2.0 (the "License");
2118 * you may not use this file except in compliance with the License.
2119 * You may obtain a copy of the License at
2120 *
2121 * http://www.apache.org/licenses/LICENSE-2.0
2122 *
2123 * Unless required by applicable law or agreed to in writing, software
2124 * distributed under the License is distributed on an "AS IS" BASIS,
2125 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2126 * See the License for the specific language governing permissions and
2127 * limitations under the License.
2128 */
2129class AuthMiddlewareQueue {
2130 constructor(auth) {
2131 this.auth = auth;
2132 this.queue = [];
2133 }
2134 pushCallback(callback, onAbort) {
2135 // The callback could be sync or async. Wrap it into a
2136 // function that is always async.
2137 const wrappedCallback = (user) => new Promise((resolve, reject) => {
2138 try {
2139 const result = callback(user);
2140 // Either resolve with existing promise or wrap a non-promise
2141 // return value into a promise.
2142 resolve(result);
2143 }
2144 catch (e) {
2145 // Sync callback throws.
2146 reject(e);
2147 }
2148 });
2149 // Attach the onAbort if present
2150 wrappedCallback.onAbort = onAbort;
2151 this.queue.push(wrappedCallback);
2152 const index = this.queue.length - 1;
2153 return () => {
2154 // Unsubscribe. Replace with no-op. Do not remove from array, or it will disturb
2155 // indexing of other elements.
2156 this.queue[index] = () => Promise.resolve();
2157 };
2158 }
2159 async runMiddleware(nextUser) {
2160 var _a;
2161 if (this.auth.currentUser === nextUser) {
2162 return;
2163 }
2164 // While running the middleware, build a temporary stack of onAbort
2165 // callbacks to call if one middleware callback rejects.
2166 const onAbortStack = [];
2167 try {
2168 for (const beforeStateCallback of this.queue) {
2169 await beforeStateCallback(nextUser);
2170 // Only push the onAbort if the callback succeeds
2171 if (beforeStateCallback.onAbort) {
2172 onAbortStack.push(beforeStateCallback.onAbort);
2173 }
2174 }
2175 }
2176 catch (e) {
2177 // Run all onAbort, with separate try/catch to ignore any errors and
2178 // continue
2179 onAbortStack.reverse();
2180 for (const onAbort of onAbortStack) {
2181 try {
2182 onAbort();
2183 }
2184 catch (_) { /* swallow error */ }
2185 }
2186 throw this.auth._errorFactory.create("login-blocked" /* LOGIN_BLOCKED */, { originalMessage: (_a = e) === null || _a === void 0 ? void 0 : _a.message });
2187 }
2188 }
2189}
2190
2191/**
2192 * @license
2193 * Copyright 2020 Google LLC
2194 *
2195 * Licensed under the Apache License, Version 2.0 (the "License");
2196 * you may not use this file except in compliance with the License.
2197 * You may obtain a copy of the License at
2198 *
2199 * http://www.apache.org/licenses/LICENSE-2.0
2200 *
2201 * Unless required by applicable law or agreed to in writing, software
2202 * distributed under the License is distributed on an "AS IS" BASIS,
2203 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2204 * See the License for the specific language governing permissions and
2205 * limitations under the License.
2206 */
2207class AuthImpl {
2208 constructor(app, heartbeatServiceProvider, config) {
2209 this.app = app;
2210 this.heartbeatServiceProvider = heartbeatServiceProvider;
2211 this.config = config;
2212 this.currentUser = null;
2213 this.emulatorConfig = null;
2214 this.operations = Promise.resolve();
2215 this.authStateSubscription = new Subscription(this);
2216 this.idTokenSubscription = new Subscription(this);
2217 this.beforeStateQueue = new AuthMiddlewareQueue(this);
2218 this.redirectUser = null;
2219 this.isProactiveRefreshEnabled = false;
2220 // Any network calls will set this to true and prevent subsequent emulator
2221 // initialization
2222 this._canInitEmulator = true;
2223 this._isInitialized = false;
2224 this._deleted = false;
2225 this._initializationPromise = null;
2226 this._popupRedirectResolver = null;
2227 this._errorFactory = _DEFAULT_AUTH_ERROR_FACTORY;
2228 // Tracks the last notified UID for state change listeners to prevent
2229 // repeated calls to the callbacks. Undefined means it's never been
2230 // called, whereas null means it's been called with a signed out user
2231 this.lastNotifiedUid = undefined;
2232 this.languageCode = null;
2233 this.tenantId = null;
2234 this.settings = { appVerificationDisabledForTesting: false };
2235 this.frameworks = [];
2236 this.name = app.name;
2237 this.clientVersion = config.sdkClientVersion;
2238 }
2239 _initializeWithPersistence(persistenceHierarchy, popupRedirectResolver) {
2240 if (popupRedirectResolver) {
2241 this._popupRedirectResolver = _getInstance(popupRedirectResolver);
2242 }
2243 // Have to check for app deletion throughout initialization (after each
2244 // promise resolution)
2245 this._initializationPromise = this.queue(async () => {
2246 var _a, _b;
2247 if (this._deleted) {
2248 return;
2249 }
2250 this.persistenceManager = await PersistenceUserManager.create(this, persistenceHierarchy);
2251 if (this._deleted) {
2252 return;
2253 }
2254 // Initialize the resolver early if necessary (only applicable to web:
2255 // this will cause the iframe to load immediately in certain cases)
2256 if ((_a = this._popupRedirectResolver) === null || _a === void 0 ? void 0 : _a._shouldInitProactively) {
2257 // If this fails, don't halt auth loading
2258 try {
2259 await this._popupRedirectResolver._initialize(this);
2260 }
2261 catch (e) { /* Ignore the error */ }
2262 }
2263 await this.initializeCurrentUser(popupRedirectResolver);
2264 this.lastNotifiedUid = ((_b = this.currentUser) === null || _b === void 0 ? void 0 : _b.uid) || null;
2265 if (this._deleted) {
2266 return;
2267 }
2268 this._isInitialized = true;
2269 });
2270 return this._initializationPromise;
2271 }
2272 /**
2273 * If the persistence is changed in another window, the user manager will let us know
2274 */
2275 async _onStorageEvent() {
2276 if (this._deleted) {
2277 return;
2278 }
2279 const user = await this.assertedPersistence.getCurrentUser();
2280 if (!this.currentUser && !user) {
2281 // No change, do nothing (was signed out and remained signed out).
2282 return;
2283 }
2284 // If the same user is to be synchronized.
2285 if (this.currentUser && user && this.currentUser.uid === user.uid) {
2286 // Data update, simply copy data changes.
2287 this._currentUser._assign(user);
2288 // If tokens changed from previous user tokens, this will trigger
2289 // notifyAuthListeners_.
2290 await this.currentUser.getIdToken();
2291 return;
2292 }
2293 // Update current Auth state. Either a new login or logout.
2294 // Skip blocking callbacks, they should not apply to a change in another tab.
2295 await this._updateCurrentUser(user, /* skipBeforeStateCallbacks */ true);
2296 }
2297 async initializeCurrentUser(popupRedirectResolver) {
2298 var _a;
2299 // First check to see if we have a pending redirect event.
2300 const previouslyStoredUser = (await this.assertedPersistence.getCurrentUser());
2301 let futureCurrentUser = previouslyStoredUser;
2302 let needsTocheckMiddleware = false;
2303 if (popupRedirectResolver && this.config.authDomain) {
2304 await this.getOrInitRedirectPersistenceManager();
2305 const redirectUserEventId = (_a = this.redirectUser) === null || _a === void 0 ? void 0 : _a._redirectEventId;
2306 const storedUserEventId = futureCurrentUser === null || futureCurrentUser === void 0 ? void 0 : futureCurrentUser._redirectEventId;
2307 const result = await this.tryRedirectSignIn(popupRedirectResolver);
2308 // If the stored user (i.e. the old "currentUser") has a redirectId that
2309 // matches the redirect user, then we want to initially sign in with the
2310 // new user object from result.
2311 // TODO(samgho): More thoroughly test all of this
2312 if ((!redirectUserEventId || redirectUserEventId === storedUserEventId) &&
2313 (result === null || result === void 0 ? void 0 : result.user)) {
2314 futureCurrentUser = result.user;
2315 needsTocheckMiddleware = true;
2316 }
2317 }
2318 // If no user in persistence, there is no current user. Set to null.
2319 if (!futureCurrentUser) {
2320 return this.directlySetCurrentUser(null);
2321 }
2322 if (!futureCurrentUser._redirectEventId) {
2323 // This isn't a redirect link operation, we can reload and bail.
2324 // First though, ensure that we check the middleware is happy.
2325 if (needsTocheckMiddleware) {
2326 try {
2327 await this.beforeStateQueue.runMiddleware(futureCurrentUser);
2328 }
2329 catch (e) {
2330 futureCurrentUser = previouslyStoredUser;
2331 // We know this is available since the bit is only set when the
2332 // resolver is available
2333 this._popupRedirectResolver._overrideRedirectResult(this, () => Promise.reject(e));
2334 }
2335 }
2336 if (futureCurrentUser) {
2337 return this.reloadAndSetCurrentUserOrClear(futureCurrentUser);
2338 }
2339 else {
2340 return this.directlySetCurrentUser(null);
2341 }
2342 }
2343 _assert(this._popupRedirectResolver, this, "argument-error" /* ARGUMENT_ERROR */);
2344 await this.getOrInitRedirectPersistenceManager();
2345 // If the redirect user's event ID matches the current user's event ID,
2346 // DO NOT reload the current user, otherwise they'll be cleared from storage.
2347 // This is important for the reauthenticateWithRedirect() flow.
2348 if (this.redirectUser &&
2349 this.redirectUser._redirectEventId === futureCurrentUser._redirectEventId) {
2350 return this.directlySetCurrentUser(futureCurrentUser);
2351 }
2352 return this.reloadAndSetCurrentUserOrClear(futureCurrentUser);
2353 }
2354 async tryRedirectSignIn(redirectResolver) {
2355 // The redirect user needs to be checked (and signed in if available)
2356 // during auth initialization. All of the normal sign in and link/reauth
2357 // flows call back into auth and push things onto the promise queue. We
2358 // need to await the result of the redirect sign in *inside the promise
2359 // queue*. This presents a problem: we run into deadlock. See:
2360 // ┌> [Initialization] ─────┐
2361 // ┌> [<other queue tasks>] │
2362 // └─ [getRedirectResult] <─┘
2363 // where [] are tasks on the queue and arrows denote awaits
2364 // Initialization will never complete because it's waiting on something
2365 // that's waiting for initialization to complete!
2366 //
2367 // Instead, this method calls getRedirectResult() (stored in
2368 // _completeRedirectFn) with an optional parameter that instructs all of
2369 // the underlying auth operations to skip anything that mutates auth state.
2370 let result = null;
2371 try {
2372 // We know this._popupRedirectResolver is set since redirectResolver
2373 // is passed in. The _completeRedirectFn expects the unwrapped extern.
2374 result = await this._popupRedirectResolver._completeRedirectFn(this, redirectResolver, true);
2375 }
2376 catch (e) {
2377 // Swallow any errors here; the code can retrieve them in
2378 // getRedirectResult().
2379 await this._setRedirectUser(null);
2380 }
2381 return result;
2382 }
2383 async reloadAndSetCurrentUserOrClear(user) {
2384 var _a;
2385 try {
2386 await _reloadWithoutSaving(user);
2387 }
2388 catch (e) {
2389 if (((_a = e) === null || _a === void 0 ? void 0 : _a.code) !== `auth/${"network-request-failed" /* NETWORK_REQUEST_FAILED */}`) {
2390 // Something's wrong with the user's token. Log them out and remove
2391 // them from storage
2392 return this.directlySetCurrentUser(null);
2393 }
2394 }
2395 return this.directlySetCurrentUser(user);
2396 }
2397 useDeviceLanguage() {
2398 this.languageCode = _getUserLanguage();
2399 }
2400 async _delete() {
2401 this._deleted = true;
2402 }
2403 async updateCurrentUser(userExtern) {
2404 // The public updateCurrentUser method needs to make a copy of the user,
2405 // and also check that the project matches
2406 const user = userExtern
2407 ? getModularInstance(userExtern)
2408 : null;
2409 if (user) {
2410 _assert(user.auth.config.apiKey === this.config.apiKey, this, "invalid-user-token" /* INVALID_AUTH */);
2411 }
2412 return this._updateCurrentUser(user && user._clone(this));
2413 }
2414 async _updateCurrentUser(user, skipBeforeStateCallbacks = false) {
2415 if (this._deleted) {
2416 return;
2417 }
2418 if (user) {
2419 _assert(this.tenantId === user.tenantId, this, "tenant-id-mismatch" /* TENANT_ID_MISMATCH */);
2420 }
2421 if (!skipBeforeStateCallbacks) {
2422 await this.beforeStateQueue.runMiddleware(user);
2423 }
2424 return this.queue(async () => {
2425 await this.directlySetCurrentUser(user);
2426 this.notifyAuthListeners();
2427 });
2428 }
2429 async signOut() {
2430 // Run first, to block _setRedirectUser() if any callbacks fail.
2431 await this.beforeStateQueue.runMiddleware(null);
2432 // Clear the redirect user when signOut is called
2433 if (this.redirectPersistenceManager || this._popupRedirectResolver) {
2434 await this._setRedirectUser(null);
2435 }
2436 // Prevent callbacks from being called again in _updateCurrentUser, as
2437 // they were already called in the first line.
2438 return this._updateCurrentUser(null, /* skipBeforeStateCallbacks */ true);
2439 }
2440 setPersistence(persistence) {
2441 return this.queue(async () => {
2442 await this.assertedPersistence.setPersistence(_getInstance(persistence));
2443 });
2444 }
2445 _getPersistence() {
2446 return this.assertedPersistence.persistence.type;
2447 }
2448 _updateErrorMap(errorMap) {
2449 this._errorFactory = new ErrorFactory('auth', 'Firebase', errorMap());
2450 }
2451 onAuthStateChanged(nextOrObserver, error, completed) {
2452 return this.registerStateListener(this.authStateSubscription, nextOrObserver, error, completed);
2453 }
2454 beforeAuthStateChanged(callback, onAbort) {
2455 return this.beforeStateQueue.pushCallback(callback, onAbort);
2456 }
2457 onIdTokenChanged(nextOrObserver, error, completed) {
2458 return this.registerStateListener(this.idTokenSubscription, nextOrObserver, error, completed);
2459 }
2460 toJSON() {
2461 var _a;
2462 return {
2463 apiKey: this.config.apiKey,
2464 authDomain: this.config.authDomain,
2465 appName: this.name,
2466 currentUser: (_a = this._currentUser) === null || _a === void 0 ? void 0 : _a.toJSON()
2467 };
2468 }
2469 async _setRedirectUser(user, popupRedirectResolver) {
2470 const redirectManager = await this.getOrInitRedirectPersistenceManager(popupRedirectResolver);
2471 return user === null
2472 ? redirectManager.removeCurrentUser()
2473 : redirectManager.setCurrentUser(user);
2474 }
2475 async getOrInitRedirectPersistenceManager(popupRedirectResolver) {
2476 if (!this.redirectPersistenceManager) {
2477 const resolver = (popupRedirectResolver && _getInstance(popupRedirectResolver)) ||
2478 this._popupRedirectResolver;
2479 _assert(resolver, this, "argument-error" /* ARGUMENT_ERROR */);
2480 this.redirectPersistenceManager = await PersistenceUserManager.create(this, [_getInstance(resolver._redirectPersistence)], "redirectUser" /* REDIRECT_USER */);
2481 this.redirectUser =
2482 await this.redirectPersistenceManager.getCurrentUser();
2483 }
2484 return this.redirectPersistenceManager;
2485 }
2486 async _redirectUserForId(id) {
2487 var _a, _b;
2488 // Make sure we've cleared any pending persistence actions if we're not in
2489 // the initializer
2490 if (this._isInitialized) {
2491 await this.queue(async () => { });
2492 }
2493 if (((_a = this._currentUser) === null || _a === void 0 ? void 0 : _a._redirectEventId) === id) {
2494 return this._currentUser;
2495 }
2496 if (((_b = this.redirectUser) === null || _b === void 0 ? void 0 : _b._redirectEventId) === id) {
2497 return this.redirectUser;
2498 }
2499 return null;
2500 }
2501 async _persistUserIfCurrent(user) {
2502 if (user === this.currentUser) {
2503 return this.queue(async () => this.directlySetCurrentUser(user));
2504 }
2505 }
2506 /** Notifies listeners only if the user is current */
2507 _notifyListenersIfCurrent(user) {
2508 if (user === this.currentUser) {
2509 this.notifyAuthListeners();
2510 }
2511 }
2512 _key() {
2513 return `${this.config.authDomain}:${this.config.apiKey}:${this.name}`;
2514 }
2515 _startProactiveRefresh() {
2516 this.isProactiveRefreshEnabled = true;
2517 if (this.currentUser) {
2518 this._currentUser._startProactiveRefresh();
2519 }
2520 }
2521 _stopProactiveRefresh() {
2522 this.isProactiveRefreshEnabled = false;
2523 if (this.currentUser) {
2524 this._currentUser._stopProactiveRefresh();
2525 }
2526 }
2527 /** Returns the current user cast as the internal type */
2528 get _currentUser() {
2529 return this.currentUser;
2530 }
2531 notifyAuthListeners() {
2532 var _a, _b;
2533 if (!this._isInitialized) {
2534 return;
2535 }
2536 this.idTokenSubscription.next(this.currentUser);
2537 const currentUid = (_b = (_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.uid) !== null && _b !== void 0 ? _b : null;
2538 if (this.lastNotifiedUid !== currentUid) {
2539 this.lastNotifiedUid = currentUid;
2540 this.authStateSubscription.next(this.currentUser);
2541 }
2542 }
2543 registerStateListener(subscription, nextOrObserver, error, completed) {
2544 if (this._deleted) {
2545 return () => { };
2546 }
2547 const cb = typeof nextOrObserver === 'function'
2548 ? nextOrObserver
2549 : nextOrObserver.next.bind(nextOrObserver);
2550 const promise = this._isInitialized
2551 ? Promise.resolve()
2552 : this._initializationPromise;
2553 _assert(promise, this, "internal-error" /* INTERNAL_ERROR */);
2554 // The callback needs to be called asynchronously per the spec.
2555 // eslint-disable-next-line @typescript-eslint/no-floating-promises
2556 promise.then(() => cb(this.currentUser));
2557 if (typeof nextOrObserver === 'function') {
2558 return subscription.addObserver(nextOrObserver, error, completed);
2559 }
2560 else {
2561 return subscription.addObserver(nextOrObserver);
2562 }
2563 }
2564 /**
2565 * Unprotected (from race conditions) method to set the current user. This
2566 * should only be called from within a queued callback. This is necessary
2567 * because the queue shouldn't rely on another queued callback.
2568 */
2569 async directlySetCurrentUser(user) {
2570 if (this.currentUser && this.currentUser !== user) {
2571 this._currentUser._stopProactiveRefresh();
2572 if (user && this.isProactiveRefreshEnabled) {
2573 user._startProactiveRefresh();
2574 }
2575 }
2576 this.currentUser = user;
2577 if (user) {
2578 await this.assertedPersistence.setCurrentUser(user);
2579 }
2580 else {
2581 await this.assertedPersistence.removeCurrentUser();
2582 }
2583 }
2584 queue(action) {
2585 // In case something errors, the callback still should be called in order
2586 // to keep the promise chain alive
2587 this.operations = this.operations.then(action, action);
2588 return this.operations;
2589 }
2590 get assertedPersistence() {
2591 _assert(this.persistenceManager, this, "internal-error" /* INTERNAL_ERROR */);
2592 return this.persistenceManager;
2593 }
2594 _logFramework(framework) {
2595 if (!framework || this.frameworks.includes(framework)) {
2596 return;
2597 }
2598 this.frameworks.push(framework);
2599 // Sort alphabetically so that "FirebaseCore-web,FirebaseUI-web" and
2600 // "FirebaseUI-web,FirebaseCore-web" aren't viewed as different.
2601 this.frameworks.sort();
2602 this.clientVersion = _getClientVersion(this.config.clientPlatform, this._getFrameworks());
2603 }
2604 _getFrameworks() {
2605 return this.frameworks;
2606 }
2607 async _getAdditionalHeaders() {
2608 var _a;
2609 // Additional headers on every request
2610 const headers = {
2611 ["X-Client-Version" /* X_CLIENT_VERSION */]: this.clientVersion,
2612 };
2613 if (this.app.options.appId) {
2614 headers["X-Firebase-gmpid" /* X_FIREBASE_GMPID */] = this.app.options.appId;
2615 }
2616 // If the heartbeat service exists, add the heartbeat string
2617 const heartbeatsHeader = await ((_a = this.heartbeatServiceProvider.getImmediate({
2618 optional: true,
2619 })) === null || _a === void 0 ? void 0 : _a.getHeartbeatsHeader());
2620 if (heartbeatsHeader) {
2621 headers["X-Firebase-Client" /* X_FIREBASE_CLIENT */] = heartbeatsHeader;
2622 }
2623 return headers;
2624 }
2625}
2626/**
2627 * Method to be used to cast down to our private implmentation of Auth.
2628 * It will also handle unwrapping from the compat type if necessary
2629 *
2630 * @param auth Auth object passed in from developer
2631 */
2632function _castAuth(auth) {
2633 return getModularInstance(auth);
2634}
2635/** Helper class to wrap subscriber logic */
2636class Subscription {
2637 constructor(auth) {
2638 this.auth = auth;
2639 this.observer = null;
2640 this.addObserver = createSubscribe(observer => (this.observer = observer));
2641 }
2642 get next() {
2643 _assert(this.observer, this.auth, "internal-error" /* INTERNAL_ERROR */);
2644 return this.observer.next.bind(this.observer);
2645 }
2646}
2647
2648/**
2649 * Changes the {@link Auth} instance to communicate with the Firebase Auth Emulator, instead of production
2650 * Firebase Auth services.
2651 *
2652 * @remarks
2653 * This must be called synchronously immediately following the first call to
2654 * {@link initializeAuth}. Do not use with production credentials as emulator
2655 * traffic is not encrypted.
2656 *
2657 *
2658 * @example
2659 * ```javascript
2660 * connectAuthEmulator(auth, 'http://127.0.0.1:9099', { disableWarnings: true });
2661 * ```
2662 *
2663 * @param auth - The {@link Auth} instance.
2664 * @param url - The URL at which the emulator is running (eg, 'http://localhost:9099').
2665 * @param options - Optional. `options.disableWarnings` defaults to `false`. Set it to
2666 * `true` to disable the warning banner attached to the DOM.
2667 *
2668 * @public
2669 */
2670function connectAuthEmulator(auth, url, options) {
2671 const authInternal = _castAuth(auth);
2672 _assert(authInternal._canInitEmulator, authInternal, "emulator-config-failed" /* EMULATOR_CONFIG_FAILED */);
2673 _assert(/^https?:\/\//.test(url), authInternal, "invalid-emulator-scheme" /* INVALID_EMULATOR_SCHEME */);
2674 const disableWarnings = !!(options === null || options === void 0 ? void 0 : options.disableWarnings);
2675 const protocol = extractProtocol(url);
2676 const { host, port } = extractHostAndPort(url);
2677 const portStr = port === null ? '' : `:${port}`;
2678 // Always replace path with "/" (even if input url had no path at all, or had a different one).
2679 authInternal.config.emulator = { url: `${protocol}//${host}${portStr}/` };
2680 authInternal.settings.appVerificationDisabledForTesting = true;
2681 authInternal.emulatorConfig = Object.freeze({
2682 host,
2683 port,
2684 protocol: protocol.replace(':', ''),
2685 options: Object.freeze({ disableWarnings })
2686 });
2687 if (!disableWarnings) {
2688 emitEmulatorWarning();
2689 }
2690}
2691function extractProtocol(url) {
2692 const protocolEnd = url.indexOf(':');
2693 return protocolEnd < 0 ? '' : url.substr(0, protocolEnd + 1);
2694}
2695function extractHostAndPort(url) {
2696 const protocol = extractProtocol(url);
2697 const authority = /(\/\/)?([^?#/]+)/.exec(url.substr(protocol.length)); // Between // and /, ? or #.
2698 if (!authority) {
2699 return { host: '', port: null };
2700 }
2701 const hostAndPort = authority[2].split('@').pop() || ''; // Strip out "username:password@".
2702 const bracketedIPv6 = /^(\[[^\]]+\])(:|$)/.exec(hostAndPort);
2703 if (bracketedIPv6) {
2704 const host = bracketedIPv6[1];
2705 return { host, port: parsePort(hostAndPort.substr(host.length + 1)) };
2706 }
2707 else {
2708 const [host, port] = hostAndPort.split(':');
2709 return { host, port: parsePort(port) };
2710 }
2711}
2712function parsePort(portStr) {
2713 if (!portStr) {
2714 return null;
2715 }
2716 const port = Number(portStr);
2717 if (isNaN(port)) {
2718 return null;
2719 }
2720 return port;
2721}
2722function emitEmulatorWarning() {
2723 function attachBanner() {
2724 const el = document.createElement('p');
2725 const sty = el.style;
2726 el.innerText =
2727 'Running in emulator mode. Do not use with production credentials.';
2728 sty.position = 'fixed';
2729 sty.width = '100%';
2730 sty.backgroundColor = '#ffffff';
2731 sty.border = '.1em solid #000000';
2732 sty.color = '#b50000';
2733 sty.bottom = '0px';
2734 sty.left = '0px';
2735 sty.margin = '0px';
2736 sty.zIndex = '10000';
2737 sty.textAlign = 'center';
2738 el.classList.add('firebase-emulator-warning');
2739 document.body.appendChild(el);
2740 }
2741 if (typeof console !== 'undefined' && typeof console.info === 'function') {
2742 console.info('WARNING: You are using the Auth Emulator,' +
2743 ' which is intended for local testing only. Do not use with' +
2744 ' production credentials.');
2745 }
2746 if (typeof window !== 'undefined' &&
2747 typeof document !== 'undefined') {
2748 if (document.readyState === 'loading') {
2749 window.addEventListener('DOMContentLoaded', attachBanner);
2750 }
2751 else {
2752 attachBanner();
2753 }
2754 }
2755}
2756
2757/**
2758 * @license
2759 * Copyright 2020 Google LLC
2760 *
2761 * Licensed under the Apache License, Version 2.0 (the "License");
2762 * you may not use this file except in compliance with the License.
2763 * You may obtain a copy of the License at
2764 *
2765 * http://www.apache.org/licenses/LICENSE-2.0
2766 *
2767 * Unless required by applicable law or agreed to in writing, software
2768 * distributed under the License is distributed on an "AS IS" BASIS,
2769 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2770 * See the License for the specific language governing permissions and
2771 * limitations under the License.
2772 */
2773/**
2774 * Interface that represents the credentials returned by an {@link AuthProvider}.
2775 *
2776 * @remarks
2777 * Implementations specify the details about each auth provider's credential requirements.
2778 *
2779 * @public
2780 */
2781class AuthCredential {
2782 /** @internal */
2783 constructor(
2784 /**
2785 * The authentication provider ID for the credential.
2786 *
2787 * @remarks
2788 * For example, 'facebook.com', or 'google.com'.
2789 */
2790 providerId,
2791 /**
2792 * The authentication sign in method for the credential.
2793 *
2794 * @remarks
2795 * For example, {@link SignInMethod}.EMAIL_PASSWORD, or
2796 * {@link SignInMethod}.EMAIL_LINK. This corresponds to the sign-in method
2797 * identifier as returned in {@link fetchSignInMethodsForEmail}.
2798 */
2799 signInMethod) {
2800 this.providerId = providerId;
2801 this.signInMethod = signInMethod;
2802 }
2803 /**
2804 * Returns a JSON-serializable representation of this object.
2805 *
2806 * @returns a JSON-serializable representation of this object.
2807 */
2808 toJSON() {
2809 return debugFail('not implemented');
2810 }
2811 /** @internal */
2812 _getIdTokenResponse(_auth) {
2813 return debugFail('not implemented');
2814 }
2815 /** @internal */
2816 _linkToIdToken(_auth, _idToken) {
2817 return debugFail('not implemented');
2818 }
2819 /** @internal */
2820 _getReauthenticationResolver(_auth) {
2821 return debugFail('not implemented');
2822 }
2823}
2824
2825/**
2826 * @license
2827 * Copyright 2020 Google LLC
2828 *
2829 * Licensed under the Apache License, Version 2.0 (the "License");
2830 * you may not use this file except in compliance with the License.
2831 * You may obtain a copy of the License at
2832 *
2833 * http://www.apache.org/licenses/LICENSE-2.0
2834 *
2835 * Unless required by applicable law or agreed to in writing, software
2836 * distributed under the License is distributed on an "AS IS" BASIS,
2837 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2838 * See the License for the specific language governing permissions and
2839 * limitations under the License.
2840 */
2841async function resetPassword(auth, request) {
2842 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:resetPassword" /* RESET_PASSWORD */, _addTidIfNecessary(auth, request));
2843}
2844async function updateEmailPassword(auth, request) {
2845 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:update" /* SET_ACCOUNT_INFO */, request);
2846}
2847async function applyActionCode$1(auth, request) {
2848 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:update" /* SET_ACCOUNT_INFO */, _addTidIfNecessary(auth, request));
2849}
2850
2851/**
2852 * @license
2853 * Copyright 2020 Google LLC
2854 *
2855 * Licensed under the Apache License, Version 2.0 (the "License");
2856 * you may not use this file except in compliance with the License.
2857 * You may obtain a copy of the License at
2858 *
2859 * http://www.apache.org/licenses/LICENSE-2.0
2860 *
2861 * Unless required by applicable law or agreed to in writing, software
2862 * distributed under the License is distributed on an "AS IS" BASIS,
2863 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2864 * See the License for the specific language governing permissions and
2865 * limitations under the License.
2866 */
2867async function signInWithPassword(auth, request) {
2868 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithPassword" /* SIGN_IN_WITH_PASSWORD */, _addTidIfNecessary(auth, request));
2869}
2870async function sendOobCode(auth, request) {
2871 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:sendOobCode" /* SEND_OOB_CODE */, _addTidIfNecessary(auth, request));
2872}
2873async function sendEmailVerification$1(auth, request) {
2874 return sendOobCode(auth, request);
2875}
2876async function sendPasswordResetEmail$1(auth, request) {
2877 return sendOobCode(auth, request);
2878}
2879async function sendSignInLinkToEmail$1(auth, request) {
2880 return sendOobCode(auth, request);
2881}
2882async function verifyAndChangeEmail(auth, request) {
2883 return sendOobCode(auth, request);
2884}
2885
2886/**
2887 * @license
2888 * Copyright 2020 Google LLC
2889 *
2890 * Licensed under the Apache License, Version 2.0 (the "License");
2891 * you may not use this file except in compliance with the License.
2892 * You may obtain a copy of the License at
2893 *
2894 * http://www.apache.org/licenses/LICENSE-2.0
2895 *
2896 * Unless required by applicable law or agreed to in writing, software
2897 * distributed under the License is distributed on an "AS IS" BASIS,
2898 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2899 * See the License for the specific language governing permissions and
2900 * limitations under the License.
2901 */
2902async function signInWithEmailLink$1(auth, request) {
2903 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithEmailLink" /* SIGN_IN_WITH_EMAIL_LINK */, _addTidIfNecessary(auth, request));
2904}
2905async function signInWithEmailLinkForLinking(auth, request) {
2906 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithEmailLink" /* SIGN_IN_WITH_EMAIL_LINK */, _addTidIfNecessary(auth, request));
2907}
2908
2909/**
2910 * @license
2911 * Copyright 2020 Google LLC
2912 *
2913 * Licensed under the Apache License, Version 2.0 (the "License");
2914 * you may not use this file except in compliance with the License.
2915 * You may obtain a copy of the License at
2916 *
2917 * http://www.apache.org/licenses/LICENSE-2.0
2918 *
2919 * Unless required by applicable law or agreed to in writing, software
2920 * distributed under the License is distributed on an "AS IS" BASIS,
2921 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2922 * See the License for the specific language governing permissions and
2923 * limitations under the License.
2924 */
2925/**
2926 * Interface that represents the credentials returned by {@link EmailAuthProvider} for
2927 * {@link ProviderId}.PASSWORD
2928 *
2929 * @remarks
2930 * Covers both {@link SignInMethod}.EMAIL_PASSWORD and
2931 * {@link SignInMethod}.EMAIL_LINK.
2932 *
2933 * @public
2934 */
2935class EmailAuthCredential extends AuthCredential {
2936 /** @internal */
2937 constructor(
2938 /** @internal */
2939 _email,
2940 /** @internal */
2941 _password, signInMethod,
2942 /** @internal */
2943 _tenantId = null) {
2944 super("password" /* PASSWORD */, signInMethod);
2945 this._email = _email;
2946 this._password = _password;
2947 this._tenantId = _tenantId;
2948 }
2949 /** @internal */
2950 static _fromEmailAndPassword(email, password) {
2951 return new EmailAuthCredential(email, password, "password" /* EMAIL_PASSWORD */);
2952 }
2953 /** @internal */
2954 static _fromEmailAndCode(email, oobCode, tenantId = null) {
2955 return new EmailAuthCredential(email, oobCode, "emailLink" /* EMAIL_LINK */, tenantId);
2956 }
2957 /** {@inheritdoc AuthCredential.toJSON} */
2958 toJSON() {
2959 return {
2960 email: this._email,
2961 password: this._password,
2962 signInMethod: this.signInMethod,
2963 tenantId: this._tenantId
2964 };
2965 }
2966 /**
2967 * Static method to deserialize a JSON representation of an object into an {@link AuthCredential}.
2968 *
2969 * @param json - Either `object` or the stringified representation of the object. When string is
2970 * provided, `JSON.parse` would be called first.
2971 *
2972 * @returns If the JSON input does not represent an {@link AuthCredential}, null is returned.
2973 */
2974 static fromJSON(json) {
2975 const obj = typeof json === 'string' ? JSON.parse(json) : json;
2976 if ((obj === null || obj === void 0 ? void 0 : obj.email) && (obj === null || obj === void 0 ? void 0 : obj.password)) {
2977 if (obj.signInMethod === "password" /* EMAIL_PASSWORD */) {
2978 return this._fromEmailAndPassword(obj.email, obj.password);
2979 }
2980 else if (obj.signInMethod === "emailLink" /* EMAIL_LINK */) {
2981 return this._fromEmailAndCode(obj.email, obj.password, obj.tenantId);
2982 }
2983 }
2984 return null;
2985 }
2986 /** @internal */
2987 async _getIdTokenResponse(auth) {
2988 switch (this.signInMethod) {
2989 case "password" /* EMAIL_PASSWORD */:
2990 return signInWithPassword(auth, {
2991 returnSecureToken: true,
2992 email: this._email,
2993 password: this._password
2994 });
2995 case "emailLink" /* EMAIL_LINK */:
2996 return signInWithEmailLink$1(auth, {
2997 email: this._email,
2998 oobCode: this._password
2999 });
3000 default:
3001 _fail(auth, "internal-error" /* INTERNAL_ERROR */);
3002 }
3003 }
3004 /** @internal */
3005 async _linkToIdToken(auth, idToken) {
3006 switch (this.signInMethod) {
3007 case "password" /* EMAIL_PASSWORD */:
3008 return updateEmailPassword(auth, {
3009 idToken,
3010 returnSecureToken: true,
3011 email: this._email,
3012 password: this._password
3013 });
3014 case "emailLink" /* EMAIL_LINK */:
3015 return signInWithEmailLinkForLinking(auth, {
3016 idToken,
3017 email: this._email,
3018 oobCode: this._password
3019 });
3020 default:
3021 _fail(auth, "internal-error" /* INTERNAL_ERROR */);
3022 }
3023 }
3024 /** @internal */
3025 _getReauthenticationResolver(auth) {
3026 return this._getIdTokenResponse(auth);
3027 }
3028}
3029
3030/**
3031 * @license
3032 * Copyright 2020 Google LLC
3033 *
3034 * Licensed under the Apache License, Version 2.0 (the "License");
3035 * you may not use this file except in compliance with the License.
3036 * You may obtain a copy of the License at
3037 *
3038 * http://www.apache.org/licenses/LICENSE-2.0
3039 *
3040 * Unless required by applicable law or agreed to in writing, software
3041 * distributed under the License is distributed on an "AS IS" BASIS,
3042 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3043 * See the License for the specific language governing permissions and
3044 * limitations under the License.
3045 */
3046async function signInWithIdp(auth, request) {
3047 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithIdp" /* SIGN_IN_WITH_IDP */, _addTidIfNecessary(auth, request));
3048}
3049
3050/**
3051 * @license
3052 * Copyright 2020 Google LLC
3053 *
3054 * Licensed under the Apache License, Version 2.0 (the "License");
3055 * you may not use this file except in compliance with the License.
3056 * You may obtain a copy of the License at
3057 *
3058 * http://www.apache.org/licenses/LICENSE-2.0
3059 *
3060 * Unless required by applicable law or agreed to in writing, software
3061 * distributed under the License is distributed on an "AS IS" BASIS,
3062 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3063 * See the License for the specific language governing permissions and
3064 * limitations under the License.
3065 */
3066const IDP_REQUEST_URI$1 = 'http://localhost';
3067/**
3068 * Represents the OAuth credentials returned by an {@link OAuthProvider}.
3069 *
3070 * @remarks
3071 * Implementations specify the details about each auth provider's credential requirements.
3072 *
3073 * @public
3074 */
3075class OAuthCredential extends AuthCredential {
3076 constructor() {
3077 super(...arguments);
3078 this.pendingToken = null;
3079 }
3080 /** @internal */
3081 static _fromParams(params) {
3082 const cred = new OAuthCredential(params.providerId, params.signInMethod);
3083 if (params.idToken || params.accessToken) {
3084 // OAuth 2 and either ID token or access token.
3085 if (params.idToken) {
3086 cred.idToken = params.idToken;
3087 }
3088 if (params.accessToken) {
3089 cred.accessToken = params.accessToken;
3090 }
3091 // Add nonce if available and no pendingToken is present.
3092 if (params.nonce && !params.pendingToken) {
3093 cred.nonce = params.nonce;
3094 }
3095 if (params.pendingToken) {
3096 cred.pendingToken = params.pendingToken;
3097 }
3098 }
3099 else if (params.oauthToken && params.oauthTokenSecret) {
3100 // OAuth 1 and OAuth token with token secret
3101 cred.accessToken = params.oauthToken;
3102 cred.secret = params.oauthTokenSecret;
3103 }
3104 else {
3105 _fail("argument-error" /* ARGUMENT_ERROR */);
3106 }
3107 return cred;
3108 }
3109 /** {@inheritdoc AuthCredential.toJSON} */
3110 toJSON() {
3111 return {
3112 idToken: this.idToken,
3113 accessToken: this.accessToken,
3114 secret: this.secret,
3115 nonce: this.nonce,
3116 pendingToken: this.pendingToken,
3117 providerId: this.providerId,
3118 signInMethod: this.signInMethod
3119 };
3120 }
3121 /**
3122 * Static method to deserialize a JSON representation of an object into an
3123 * {@link AuthCredential}.
3124 *
3125 * @param json - Input can be either Object or the stringified representation of the object.
3126 * When string is provided, JSON.parse would be called first.
3127 *
3128 * @returns If the JSON input does not represent an {@link AuthCredential}, null is returned.
3129 */
3130 static fromJSON(json) {
3131 const obj = typeof json === 'string' ? JSON.parse(json) : json;
3132 const { providerId, signInMethod } = obj, rest = __rest(obj, ["providerId", "signInMethod"]);
3133 if (!providerId || !signInMethod) {
3134 return null;
3135 }
3136 const cred = new OAuthCredential(providerId, signInMethod);
3137 cred.idToken = rest.idToken || undefined;
3138 cred.accessToken = rest.accessToken || undefined;
3139 cred.secret = rest.secret;
3140 cred.nonce = rest.nonce;
3141 cred.pendingToken = rest.pendingToken || null;
3142 return cred;
3143 }
3144 /** @internal */
3145 _getIdTokenResponse(auth) {
3146 const request = this.buildRequest();
3147 return signInWithIdp(auth, request);
3148 }
3149 /** @internal */
3150 _linkToIdToken(auth, idToken) {
3151 const request = this.buildRequest();
3152 request.idToken = idToken;
3153 return signInWithIdp(auth, request);
3154 }
3155 /** @internal */
3156 _getReauthenticationResolver(auth) {
3157 const request = this.buildRequest();
3158 request.autoCreate = false;
3159 return signInWithIdp(auth, request);
3160 }
3161 buildRequest() {
3162 const request = {
3163 requestUri: IDP_REQUEST_URI$1,
3164 returnSecureToken: true
3165 };
3166 if (this.pendingToken) {
3167 request.pendingToken = this.pendingToken;
3168 }
3169 else {
3170 const postBody = {};
3171 if (this.idToken) {
3172 postBody['id_token'] = this.idToken;
3173 }
3174 if (this.accessToken) {
3175 postBody['access_token'] = this.accessToken;
3176 }
3177 if (this.secret) {
3178 postBody['oauth_token_secret'] = this.secret;
3179 }
3180 postBody['providerId'] = this.providerId;
3181 if (this.nonce && !this.pendingToken) {
3182 postBody['nonce'] = this.nonce;
3183 }
3184 request.postBody = querystring(postBody);
3185 }
3186 return request;
3187 }
3188}
3189
3190/**
3191 * @license
3192 * Copyright 2020 Google LLC
3193 *
3194 * Licensed under the Apache License, Version 2.0 (the "License");
3195 * you may not use this file except in compliance with the License.
3196 * You may obtain a copy of the License at
3197 *
3198 * http://www.apache.org/licenses/LICENSE-2.0
3199 *
3200 * Unless required by applicable law or agreed to in writing, software
3201 * distributed under the License is distributed on an "AS IS" BASIS,
3202 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3203 * See the License for the specific language governing permissions and
3204 * limitations under the License.
3205 */
3206async function signInWithPhoneNumber$1(auth, request) {
3207 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithPhoneNumber" /* SIGN_IN_WITH_PHONE_NUMBER */, _addTidIfNecessary(auth, request));
3208}
3209async function linkWithPhoneNumber$1(auth, request) {
3210 const response = await _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithPhoneNumber" /* SIGN_IN_WITH_PHONE_NUMBER */, _addTidIfNecessary(auth, request));
3211 if (response.temporaryProof) {
3212 throw _makeTaggedError(auth, "account-exists-with-different-credential" /* NEED_CONFIRMATION */, response);
3213 }
3214 return response;
3215}
3216const VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_ = {
3217 ["USER_NOT_FOUND" /* USER_NOT_FOUND */]: "user-not-found" /* USER_DELETED */
3218};
3219async function verifyPhoneNumberForExisting(auth, request) {
3220 const apiRequest = Object.assign(Object.assign({}, request), { operation: 'REAUTH' });
3221 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithPhoneNumber" /* SIGN_IN_WITH_PHONE_NUMBER */, _addTidIfNecessary(auth, apiRequest), VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_);
3222}
3223
3224/**
3225 * @license
3226 * Copyright 2020 Google LLC
3227 *
3228 * Licensed under the Apache License, Version 2.0 (the "License");
3229 * you may not use this file except in compliance with the License.
3230 * You may obtain a copy of the License at
3231 *
3232 * http://www.apache.org/licenses/LICENSE-2.0
3233 *
3234 * Unless required by applicable law or agreed to in writing, software
3235 * distributed under the License is distributed on an "AS IS" BASIS,
3236 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3237 * See the License for the specific language governing permissions and
3238 * limitations under the License.
3239 */
3240/**
3241 * Represents the credentials returned by {@link PhoneAuthProvider}.
3242 *
3243 * @public
3244 */
3245class PhoneAuthCredential extends AuthCredential {
3246 constructor(params) {
3247 super("phone" /* PHONE */, "phone" /* PHONE */);
3248 this.params = params;
3249 }
3250 /** @internal */
3251 static _fromVerification(verificationId, verificationCode) {
3252 return new PhoneAuthCredential({ verificationId, verificationCode });
3253 }
3254 /** @internal */
3255 static _fromTokenResponse(phoneNumber, temporaryProof) {
3256 return new PhoneAuthCredential({ phoneNumber, temporaryProof });
3257 }
3258 /** @internal */
3259 _getIdTokenResponse(auth) {
3260 return signInWithPhoneNumber$1(auth, this._makeVerificationRequest());
3261 }
3262 /** @internal */
3263 _linkToIdToken(auth, idToken) {
3264 return linkWithPhoneNumber$1(auth, Object.assign({ idToken }, this._makeVerificationRequest()));
3265 }
3266 /** @internal */
3267 _getReauthenticationResolver(auth) {
3268 return verifyPhoneNumberForExisting(auth, this._makeVerificationRequest());
3269 }
3270 /** @internal */
3271 _makeVerificationRequest() {
3272 const { temporaryProof, phoneNumber, verificationId, verificationCode } = this.params;
3273 if (temporaryProof && phoneNumber) {
3274 return { temporaryProof, phoneNumber };
3275 }
3276 return {
3277 sessionInfo: verificationId,
3278 code: verificationCode
3279 };
3280 }
3281 /** {@inheritdoc AuthCredential.toJSON} */
3282 toJSON() {
3283 const obj = {
3284 providerId: this.providerId
3285 };
3286 if (this.params.phoneNumber) {
3287 obj.phoneNumber = this.params.phoneNumber;
3288 }
3289 if (this.params.temporaryProof) {
3290 obj.temporaryProof = this.params.temporaryProof;
3291 }
3292 if (this.params.verificationCode) {
3293 obj.verificationCode = this.params.verificationCode;
3294 }
3295 if (this.params.verificationId) {
3296 obj.verificationId = this.params.verificationId;
3297 }
3298 return obj;
3299 }
3300 /** Generates a phone credential based on a plain object or a JSON string. */
3301 static fromJSON(json) {
3302 if (typeof json === 'string') {
3303 json = JSON.parse(json);
3304 }
3305 const { verificationId, verificationCode, phoneNumber, temporaryProof } = json;
3306 if (!verificationCode &&
3307 !verificationId &&
3308 !phoneNumber &&
3309 !temporaryProof) {
3310 return null;
3311 }
3312 return new PhoneAuthCredential({
3313 verificationId,
3314 verificationCode,
3315 phoneNumber,
3316 temporaryProof
3317 });
3318 }
3319}
3320
3321/**
3322 * @license
3323 * Copyright 2020 Google LLC
3324 *
3325 * Licensed under the Apache License, Version 2.0 (the "License");
3326 * you may not use this file except in compliance with the License.
3327 * You may obtain a copy of the License at
3328 *
3329 * http://www.apache.org/licenses/LICENSE-2.0
3330 *
3331 * Unless required by applicable law or agreed to in writing, software
3332 * distributed under the License is distributed on an "AS IS" BASIS,
3333 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3334 * See the License for the specific language governing permissions and
3335 * limitations under the License.
3336 */
3337/**
3338 * Maps the mode string in action code URL to Action Code Info operation.
3339 *
3340 * @param mode
3341 */
3342function parseMode(mode) {
3343 switch (mode) {
3344 case 'recoverEmail':
3345 return "RECOVER_EMAIL" /* RECOVER_EMAIL */;
3346 case 'resetPassword':
3347 return "PASSWORD_RESET" /* PASSWORD_RESET */;
3348 case 'signIn':
3349 return "EMAIL_SIGNIN" /* EMAIL_SIGNIN */;
3350 case 'verifyEmail':
3351 return "VERIFY_EMAIL" /* VERIFY_EMAIL */;
3352 case 'verifyAndChangeEmail':
3353 return "VERIFY_AND_CHANGE_EMAIL" /* VERIFY_AND_CHANGE_EMAIL */;
3354 case 'revertSecondFactorAddition':
3355 return "REVERT_SECOND_FACTOR_ADDITION" /* REVERT_SECOND_FACTOR_ADDITION */;
3356 default:
3357 return null;
3358 }
3359}
3360/**
3361 * Helper to parse FDL links
3362 *
3363 * @param url
3364 */
3365function parseDeepLink(url) {
3366 const link = querystringDecode(extractQuerystring(url))['link'];
3367 // Double link case (automatic redirect).
3368 const doubleDeepLink = link
3369 ? querystringDecode(extractQuerystring(link))['deep_link_id']
3370 : null;
3371 // iOS custom scheme links.
3372 const iOSDeepLink = querystringDecode(extractQuerystring(url))['deep_link_id'];
3373 const iOSDoubleDeepLink = iOSDeepLink
3374 ? querystringDecode(extractQuerystring(iOSDeepLink))['link']
3375 : null;
3376 return iOSDoubleDeepLink || iOSDeepLink || doubleDeepLink || link || url;
3377}
3378/**
3379 * A utility class to parse email action URLs such as password reset, email verification,
3380 * email link sign in, etc.
3381 *
3382 * @public
3383 */
3384class ActionCodeURL {
3385 /**
3386 * @param actionLink - The link from which to extract the URL.
3387 * @returns The {@link ActionCodeURL} object, or null if the link is invalid.
3388 *
3389 * @internal
3390 */
3391 constructor(actionLink) {
3392 var _a, _b, _c, _d, _e, _f;
3393 const searchParams = querystringDecode(extractQuerystring(actionLink));
3394 const apiKey = (_a = searchParams["apiKey" /* API_KEY */]) !== null && _a !== void 0 ? _a : null;
3395 const code = (_b = searchParams["oobCode" /* CODE */]) !== null && _b !== void 0 ? _b : null;
3396 const operation = parseMode((_c = searchParams["mode" /* MODE */]) !== null && _c !== void 0 ? _c : null);
3397 // Validate API key, code and mode.
3398 _assert(apiKey && code && operation, "argument-error" /* ARGUMENT_ERROR */);
3399 this.apiKey = apiKey;
3400 this.operation = operation;
3401 this.code = code;
3402 this.continueUrl = (_d = searchParams["continueUrl" /* CONTINUE_URL */]) !== null && _d !== void 0 ? _d : null;
3403 this.languageCode = (_e = searchParams["languageCode" /* LANGUAGE_CODE */]) !== null && _e !== void 0 ? _e : null;
3404 this.tenantId = (_f = searchParams["tenantId" /* TENANT_ID */]) !== null && _f !== void 0 ? _f : null;
3405 }
3406 /**
3407 * Parses the email action link string and returns an {@link ActionCodeURL} if the link is valid,
3408 * otherwise returns null.
3409 *
3410 * @param link - The email action link string.
3411 * @returns The {@link ActionCodeURL} object, or null if the link is invalid.
3412 *
3413 * @public
3414 */
3415 static parseLink(link) {
3416 const actionLink = parseDeepLink(link);
3417 try {
3418 return new ActionCodeURL(actionLink);
3419 }
3420 catch (_a) {
3421 return null;
3422 }
3423 }
3424}
3425/**
3426 * Parses the email action link string and returns an {@link ActionCodeURL} if
3427 * the link is valid, otherwise returns null.
3428 *
3429 * @public
3430 */
3431function parseActionCodeURL(link) {
3432 return ActionCodeURL.parseLink(link);
3433}
3434
3435/**
3436 * @license
3437 * Copyright 2020 Google LLC
3438 *
3439 * Licensed under the Apache License, Version 2.0 (the "License");
3440 * you may not use this file except in compliance with the License.
3441 * You may obtain a copy of the License at
3442 *
3443 * http://www.apache.org/licenses/LICENSE-2.0
3444 *
3445 * Unless required by applicable law or agreed to in writing, software
3446 * distributed under the License is distributed on an "AS IS" BASIS,
3447 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3448 * See the License for the specific language governing permissions and
3449 * limitations under the License.
3450 */
3451/**
3452 * Provider for generating {@link EmailAuthCredential}.
3453 *
3454 * @public
3455 */
3456class EmailAuthProvider {
3457 constructor() {
3458 /**
3459 * Always set to {@link ProviderId}.PASSWORD, even for email link.
3460 */
3461 this.providerId = EmailAuthProvider.PROVIDER_ID;
3462 }
3463 /**
3464 * Initialize an {@link AuthCredential} using an email and password.
3465 *
3466 * @example
3467 * ```javascript
3468 * const authCredential = EmailAuthProvider.credential(email, password);
3469 * const userCredential = await signInWithCredential(auth, authCredential);
3470 * ```
3471 *
3472 * @example
3473 * ```javascript
3474 * const userCredential = await signInWithEmailAndPassword(auth, email, password);
3475 * ```
3476 *
3477 * @param email - Email address.
3478 * @param password - User account password.
3479 * @returns The auth provider credential.
3480 */
3481 static credential(email, password) {
3482 return EmailAuthCredential._fromEmailAndPassword(email, password);
3483 }
3484 /**
3485 * Initialize an {@link AuthCredential} using an email and an email link after a sign in with
3486 * email link operation.
3487 *
3488 * @example
3489 * ```javascript
3490 * const authCredential = EmailAuthProvider.credentialWithLink(auth, email, emailLink);
3491 * const userCredential = await signInWithCredential(auth, authCredential);
3492 * ```
3493 *
3494 * @example
3495 * ```javascript
3496 * await sendSignInLinkToEmail(auth, email);
3497 * // Obtain emailLink from user.
3498 * const userCredential = await signInWithEmailLink(auth, email, emailLink);
3499 * ```
3500 *
3501 * @param auth - The {@link Auth} instance used to verify the link.
3502 * @param email - Email address.
3503 * @param emailLink - Sign-in email link.
3504 * @returns - The auth provider credential.
3505 */
3506 static credentialWithLink(email, emailLink) {
3507 const actionCodeUrl = ActionCodeURL.parseLink(emailLink);
3508 _assert(actionCodeUrl, "argument-error" /* ARGUMENT_ERROR */);
3509 return EmailAuthCredential._fromEmailAndCode(email, actionCodeUrl.code, actionCodeUrl.tenantId);
3510 }
3511}
3512/**
3513 * Always set to {@link ProviderId}.PASSWORD, even for email link.
3514 */
3515EmailAuthProvider.PROVIDER_ID = "password" /* PASSWORD */;
3516/**
3517 * Always set to {@link SignInMethod}.EMAIL_PASSWORD.
3518 */
3519EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD = "password" /* EMAIL_PASSWORD */;
3520/**
3521 * Always set to {@link SignInMethod}.EMAIL_LINK.
3522 */
3523EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD = "emailLink" /* EMAIL_LINK */;
3524
3525/**
3526 * @license
3527 * Copyright 2020 Google LLC
3528 *
3529 * Licensed under the Apache License, Version 2.0 (the "License");
3530 * you may not use this file except in compliance with the License.
3531 * You may obtain a copy of the License at
3532 *
3533 * http://www.apache.org/licenses/LICENSE-2.0
3534 *
3535 * Unless required by applicable law or agreed to in writing, software
3536 * distributed under the License is distributed on an "AS IS" BASIS,
3537 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3538 * See the License for the specific language governing permissions and
3539 * limitations under the License.
3540 */
3541/**
3542 * The base class for all Federated providers (OAuth (including OIDC), SAML).
3543 *
3544 * This class is not meant to be instantiated directly.
3545 *
3546 * @public
3547 */
3548class FederatedAuthProvider {
3549 /**
3550 * Constructor for generic OAuth providers.
3551 *
3552 * @param providerId - Provider for which credentials should be generated.
3553 */
3554 constructor(providerId) {
3555 this.providerId = providerId;
3556 /** @internal */
3557 this.defaultLanguageCode = null;
3558 /** @internal */
3559 this.customParameters = {};
3560 }
3561 /**
3562 * Set the language gode.
3563 *
3564 * @param languageCode - language code
3565 */
3566 setDefaultLanguage(languageCode) {
3567 this.defaultLanguageCode = languageCode;
3568 }
3569 /**
3570 * Sets the OAuth custom parameters to pass in an OAuth request for popup and redirect sign-in
3571 * operations.
3572 *
3573 * @remarks
3574 * For a detailed list, check the reserved required OAuth 2.0 parameters such as `client_id`,
3575 * `redirect_uri`, `scope`, `response_type`, and `state` are not allowed and will be ignored.
3576 *
3577 * @param customOAuthParameters - The custom OAuth parameters to pass in the OAuth request.
3578 */
3579 setCustomParameters(customOAuthParameters) {
3580 this.customParameters = customOAuthParameters;
3581 return this;
3582 }
3583 /**
3584 * Retrieve the current list of {@link CustomParameters}.
3585 */
3586 getCustomParameters() {
3587 return this.customParameters;
3588 }
3589}
3590
3591/**
3592 * @license
3593 * Copyright 2019 Google LLC
3594 *
3595 * Licensed under the Apache License, Version 2.0 (the "License");
3596 * you may not use this file except in compliance with the License.
3597 * You may obtain a copy of the License at
3598 *
3599 * http://www.apache.org/licenses/LICENSE-2.0
3600 *
3601 * Unless required by applicable law or agreed to in writing, software
3602 * distributed under the License is distributed on an "AS IS" BASIS,
3603 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3604 * See the License for the specific language governing permissions and
3605 * limitations under the License.
3606 */
3607/**
3608 * Common code to all OAuth providers. This is separate from the
3609 * {@link OAuthProvider} so that child providers (like
3610 * {@link GoogleAuthProvider}) don't inherit the `credential` instance method.
3611 * Instead, they rely on a static `credential` method.
3612 */
3613class BaseOAuthProvider extends FederatedAuthProvider {
3614 constructor() {
3615 super(...arguments);
3616 /** @internal */
3617 this.scopes = [];
3618 }
3619 /**
3620 * Add an OAuth scope to the credential.
3621 *
3622 * @param scope - Provider OAuth scope to add.
3623 */
3624 addScope(scope) {
3625 // If not already added, add scope to list.
3626 if (!this.scopes.includes(scope)) {
3627 this.scopes.push(scope);
3628 }
3629 return this;
3630 }
3631 /**
3632 * Retrieve the current list of OAuth scopes.
3633 */
3634 getScopes() {
3635 return [...this.scopes];
3636 }
3637}
3638/**
3639 * Provider for generating generic {@link OAuthCredential}.
3640 *
3641 * @example
3642 * ```javascript
3643 * // Sign in using a redirect.
3644 * const provider = new OAuthProvider('google.com');
3645 * // Start a sign in process for an unauthenticated user.
3646 * provider.addScope('profile');
3647 * provider.addScope('email');
3648 * await signInWithRedirect(auth, provider);
3649 * // This will trigger a full page redirect away from your app
3650 *
3651 * // After returning from the redirect when your app initializes you can obtain the result
3652 * const result = await getRedirectResult(auth);
3653 * if (result) {
3654 * // This is the signed-in user
3655 * const user = result.user;
3656 * // This gives you a OAuth Access Token for the provider.
3657 * const credential = provider.credentialFromResult(auth, result);
3658 * const token = credential.accessToken;
3659 * }
3660 * ```
3661 *
3662 * @example
3663 * ```javascript
3664 * // Sign in using a popup.
3665 * const provider = new OAuthProvider('google.com');
3666 * provider.addScope('profile');
3667 * provider.addScope('email');
3668 * const result = await signInWithPopup(auth, provider);
3669 *
3670 * // The signed-in user info.
3671 * const user = result.user;
3672 * // This gives you a OAuth Access Token for the provider.
3673 * const credential = provider.credentialFromResult(auth, result);
3674 * const token = credential.accessToken;
3675 * ```
3676 * @public
3677 */
3678class OAuthProvider extends BaseOAuthProvider {
3679 /**
3680 * Creates an {@link OAuthCredential} from a JSON string or a plain object.
3681 * @param json - A plain object or a JSON string
3682 */
3683 static credentialFromJSON(json) {
3684 const obj = typeof json === 'string' ? JSON.parse(json) : json;
3685 _assert('providerId' in obj && 'signInMethod' in obj, "argument-error" /* ARGUMENT_ERROR */);
3686 return OAuthCredential._fromParams(obj);
3687 }
3688 /**
3689 * Creates a {@link OAuthCredential} from a generic OAuth provider's access token or ID token.
3690 *
3691 * @remarks
3692 * The raw nonce is required when an ID token with a nonce field is provided. The SHA-256 hash of
3693 * the raw nonce must match the nonce field in the ID token.
3694 *
3695 * @example
3696 * ```javascript
3697 * // `googleUser` from the onsuccess Google Sign In callback.
3698 * // Initialize a generate OAuth provider with a `google.com` providerId.
3699 * const provider = new OAuthProvider('google.com');
3700 * const credential = provider.credential({
3701 * idToken: googleUser.getAuthResponse().id_token,
3702 * });
3703 * const result = await signInWithCredential(credential);
3704 * ```
3705 *
3706 * @param params - Either the options object containing the ID token, access token and raw nonce
3707 * or the ID token string.
3708 */
3709 credential(params) {
3710 return this._credential(Object.assign(Object.assign({}, params), { nonce: params.rawNonce }));
3711 }
3712 /** An internal credential method that accepts more permissive options */
3713 _credential(params) {
3714 _assert(params.idToken || params.accessToken, "argument-error" /* ARGUMENT_ERROR */);
3715 // For OAuthCredential, sign in method is same as providerId.
3716 return OAuthCredential._fromParams(Object.assign(Object.assign({}, params), { providerId: this.providerId, signInMethod: this.providerId }));
3717 }
3718 /**
3719 * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
3720 *
3721 * @param userCredential - The user credential.
3722 */
3723 static credentialFromResult(userCredential) {
3724 return OAuthProvider.oauthCredentialFromTaggedObject(userCredential);
3725 }
3726 /**
3727 * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
3728 * thrown during a sign-in, link, or reauthenticate operation.
3729 *
3730 * @param userCredential - The user credential.
3731 */
3732 static credentialFromError(error) {
3733 return OAuthProvider.oauthCredentialFromTaggedObject((error.customData || {}));
3734 }
3735 static oauthCredentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
3736 if (!tokenResponse) {
3737 return null;
3738 }
3739 const { oauthIdToken, oauthAccessToken, oauthTokenSecret, pendingToken, nonce, providerId } = tokenResponse;
3740 if (!oauthAccessToken &&
3741 !oauthTokenSecret &&
3742 !oauthIdToken &&
3743 !pendingToken) {
3744 return null;
3745 }
3746 if (!providerId) {
3747 return null;
3748 }
3749 try {
3750 return new OAuthProvider(providerId)._credential({
3751 idToken: oauthIdToken,
3752 accessToken: oauthAccessToken,
3753 nonce,
3754 pendingToken
3755 });
3756 }
3757 catch (e) {
3758 return null;
3759 }
3760 }
3761}
3762
3763/**
3764 * @license
3765 * Copyright 2020 Google LLC
3766 *
3767 * Licensed under the Apache License, Version 2.0 (the "License");
3768 * you may not use this file except in compliance with the License.
3769 * You may obtain a copy of the License at
3770 *
3771 * http://www.apache.org/licenses/LICENSE-2.0
3772 *
3773 * Unless required by applicable law or agreed to in writing, software
3774 * distributed under the License is distributed on an "AS IS" BASIS,
3775 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3776 * See the License for the specific language governing permissions and
3777 * limitations under the License.
3778 */
3779/**
3780 * Provider for generating an {@link OAuthCredential} for {@link ProviderId}.FACEBOOK.
3781 *
3782 * @example
3783 * ```javascript
3784 * // Sign in using a redirect.
3785 * const provider = new FacebookAuthProvider();
3786 * // Start a sign in process for an unauthenticated user.
3787 * provider.addScope('user_birthday');
3788 * await signInWithRedirect(auth, provider);
3789 * // This will trigger a full page redirect away from your app
3790 *
3791 * // After returning from the redirect when your app initializes you can obtain the result
3792 * const result = await getRedirectResult(auth);
3793 * if (result) {
3794 * // This is the signed-in user
3795 * const user = result.user;
3796 * // This gives you a Facebook Access Token.
3797 * const credential = FacebookAuthProvider.credentialFromResult(result);
3798 * const token = credential.accessToken;
3799 * }
3800 * ```
3801 *
3802 * @example
3803 * ```javascript
3804 * // Sign in using a popup.
3805 * const provider = new FacebookAuthProvider();
3806 * provider.addScope('user_birthday');
3807 * const result = await signInWithPopup(auth, provider);
3808 *
3809 * // The signed-in user info.
3810 * const user = result.user;
3811 * // This gives you a Facebook Access Token.
3812 * const credential = FacebookAuthProvider.credentialFromResult(result);
3813 * const token = credential.accessToken;
3814 * ```
3815 *
3816 * @public
3817 */
3818class FacebookAuthProvider extends BaseOAuthProvider {
3819 constructor() {
3820 super("facebook.com" /* FACEBOOK */);
3821 }
3822 /**
3823 * Creates a credential for Facebook.
3824 *
3825 * @example
3826 * ```javascript
3827 * // `event` from the Facebook auth.authResponseChange callback.
3828 * const credential = FacebookAuthProvider.credential(event.authResponse.accessToken);
3829 * const result = await signInWithCredential(credential);
3830 * ```
3831 *
3832 * @param accessToken - Facebook access token.
3833 */
3834 static credential(accessToken) {
3835 return OAuthCredential._fromParams({
3836 providerId: FacebookAuthProvider.PROVIDER_ID,
3837 signInMethod: FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD,
3838 accessToken
3839 });
3840 }
3841 /**
3842 * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
3843 *
3844 * @param userCredential - The user credential.
3845 */
3846 static credentialFromResult(userCredential) {
3847 return FacebookAuthProvider.credentialFromTaggedObject(userCredential);
3848 }
3849 /**
3850 * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
3851 * thrown during a sign-in, link, or reauthenticate operation.
3852 *
3853 * @param userCredential - The user credential.
3854 */
3855 static credentialFromError(error) {
3856 return FacebookAuthProvider.credentialFromTaggedObject((error.customData || {}));
3857 }
3858 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
3859 if (!tokenResponse || !('oauthAccessToken' in tokenResponse)) {
3860 return null;
3861 }
3862 if (!tokenResponse.oauthAccessToken) {
3863 return null;
3864 }
3865 try {
3866 return FacebookAuthProvider.credential(tokenResponse.oauthAccessToken);
3867 }
3868 catch (_a) {
3869 return null;
3870 }
3871 }
3872}
3873/** Always set to {@link SignInMethod}.FACEBOOK. */
3874FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD = "facebook.com" /* FACEBOOK */;
3875/** Always set to {@link ProviderId}.FACEBOOK. */
3876FacebookAuthProvider.PROVIDER_ID = "facebook.com" /* FACEBOOK */;
3877
3878/**
3879 * @license
3880 * Copyright 2020 Google LLC
3881 *
3882 * Licensed under the Apache License, Version 2.0 (the "License");
3883 * you may not use this file except in compliance with the License.
3884 * You may obtain a copy of the License at
3885 *
3886 * http://www.apache.org/licenses/LICENSE-2.0
3887 *
3888 * Unless required by applicable law or agreed to in writing, software
3889 * distributed under the License is distributed on an "AS IS" BASIS,
3890 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3891 * See the License for the specific language governing permissions and
3892 * limitations under the License.
3893 */
3894/**
3895 * Provider for generating an an {@link OAuthCredential} for {@link ProviderId}.GOOGLE.
3896 *
3897 * @example
3898 * ```javascript
3899 * // Sign in using a redirect.
3900 * const provider = new GoogleAuthProvider();
3901 * // Start a sign in process for an unauthenticated user.
3902 * provider.addScope('profile');
3903 * provider.addScope('email');
3904 * await signInWithRedirect(auth, provider);
3905 * // This will trigger a full page redirect away from your app
3906 *
3907 * // After returning from the redirect when your app initializes you can obtain the result
3908 * const result = await getRedirectResult(auth);
3909 * if (result) {
3910 * // This is the signed-in user
3911 * const user = result.user;
3912 * // This gives you a Google Access Token.
3913 * const credential = GoogleAuthProvider.credentialFromResult(result);
3914 * const token = credential.accessToken;
3915 * }
3916 * ```
3917 *
3918 * @example
3919 * ```javascript
3920 * // Sign in using a popup.
3921 * const provider = new GoogleAuthProvider();
3922 * provider.addScope('profile');
3923 * provider.addScope('email');
3924 * const result = await signInWithPopup(auth, provider);
3925 *
3926 * // The signed-in user info.
3927 * const user = result.user;
3928 * // This gives you a Google Access Token.
3929 * const credential = GoogleAuthProvider.credentialFromResult(result);
3930 * const token = credential.accessToken;
3931 * ```
3932 *
3933 * @public
3934 */
3935class GoogleAuthProvider extends BaseOAuthProvider {
3936 constructor() {
3937 super("google.com" /* GOOGLE */);
3938 this.addScope('profile');
3939 }
3940 /**
3941 * Creates a credential for Google. At least one of ID token and access token is required.
3942 *
3943 * @example
3944 * ```javascript
3945 * // \`googleUser\` from the onsuccess Google Sign In callback.
3946 * const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
3947 * const result = await signInWithCredential(credential);
3948 * ```
3949 *
3950 * @param idToken - Google ID token.
3951 * @param accessToken - Google access token.
3952 */
3953 static credential(idToken, accessToken) {
3954 return OAuthCredential._fromParams({
3955 providerId: GoogleAuthProvider.PROVIDER_ID,
3956 signInMethod: GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD,
3957 idToken,
3958 accessToken
3959 });
3960 }
3961 /**
3962 * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
3963 *
3964 * @param userCredential - The user credential.
3965 */
3966 static credentialFromResult(userCredential) {
3967 return GoogleAuthProvider.credentialFromTaggedObject(userCredential);
3968 }
3969 /**
3970 * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
3971 * thrown during a sign-in, link, or reauthenticate operation.
3972 *
3973 * @param userCredential - The user credential.
3974 */
3975 static credentialFromError(error) {
3976 return GoogleAuthProvider.credentialFromTaggedObject((error.customData || {}));
3977 }
3978 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
3979 if (!tokenResponse) {
3980 return null;
3981 }
3982 const { oauthIdToken, oauthAccessToken } = tokenResponse;
3983 if (!oauthIdToken && !oauthAccessToken) {
3984 // This could be an oauth 1 credential or a phone credential
3985 return null;
3986 }
3987 try {
3988 return GoogleAuthProvider.credential(oauthIdToken, oauthAccessToken);
3989 }
3990 catch (_a) {
3991 return null;
3992 }
3993 }
3994}
3995/** Always set to {@link SignInMethod}.GOOGLE. */
3996GoogleAuthProvider.GOOGLE_SIGN_IN_METHOD = "google.com" /* GOOGLE */;
3997/** Always set to {@link ProviderId}.GOOGLE. */
3998GoogleAuthProvider.PROVIDER_ID = "google.com" /* GOOGLE */;
3999
4000/**
4001 * @license
4002 * Copyright 2020 Google LLC
4003 *
4004 * Licensed under the Apache License, Version 2.0 (the "License");
4005 * you may not use this file except in compliance with the License.
4006 * You may obtain a copy of the License at
4007 *
4008 * http://www.apache.org/licenses/LICENSE-2.0
4009 *
4010 * Unless required by applicable law or agreed to in writing, software
4011 * distributed under the License is distributed on an "AS IS" BASIS,
4012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4013 * See the License for the specific language governing permissions and
4014 * limitations under the License.
4015 */
4016/**
4017 * Provider for generating an {@link OAuthCredential} for {@link ProviderId}.GITHUB.
4018 *
4019 * @remarks
4020 * GitHub requires an OAuth 2.0 redirect, so you can either handle the redirect directly, or use
4021 * the {@link signInWithPopup} handler:
4022 *
4023 * @example
4024 * ```javascript
4025 * // Sign in using a redirect.
4026 * const provider = new GithubAuthProvider();
4027 * // Start a sign in process for an unauthenticated user.
4028 * provider.addScope('repo');
4029 * await signInWithRedirect(auth, provider);
4030 * // This will trigger a full page redirect away from your app
4031 *
4032 * // After returning from the redirect when your app initializes you can obtain the result
4033 * const result = await getRedirectResult(auth);
4034 * if (result) {
4035 * // This is the signed-in user
4036 * const user = result.user;
4037 * // This gives you a Github Access Token.
4038 * const credential = GithubAuthProvider.credentialFromResult(result);
4039 * const token = credential.accessToken;
4040 * }
4041 * ```
4042 *
4043 * @example
4044 * ```javascript
4045 * // Sign in using a popup.
4046 * const provider = new GithubAuthProvider();
4047 * provider.addScope('repo');
4048 * const result = await signInWithPopup(auth, provider);
4049 *
4050 * // The signed-in user info.
4051 * const user = result.user;
4052 * // This gives you a Github Access Token.
4053 * const credential = GithubAuthProvider.credentialFromResult(result);
4054 * const token = credential.accessToken;
4055 * ```
4056 * @public
4057 */
4058class GithubAuthProvider extends BaseOAuthProvider {
4059 constructor() {
4060 super("github.com" /* GITHUB */);
4061 }
4062 /**
4063 * Creates a credential for Github.
4064 *
4065 * @param accessToken - Github access token.
4066 */
4067 static credential(accessToken) {
4068 return OAuthCredential._fromParams({
4069 providerId: GithubAuthProvider.PROVIDER_ID,
4070 signInMethod: GithubAuthProvider.GITHUB_SIGN_IN_METHOD,
4071 accessToken
4072 });
4073 }
4074 /**
4075 * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
4076 *
4077 * @param userCredential - The user credential.
4078 */
4079 static credentialFromResult(userCredential) {
4080 return GithubAuthProvider.credentialFromTaggedObject(userCredential);
4081 }
4082 /**
4083 * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
4084 * thrown during a sign-in, link, or reauthenticate operation.
4085 *
4086 * @param userCredential - The user credential.
4087 */
4088 static credentialFromError(error) {
4089 return GithubAuthProvider.credentialFromTaggedObject((error.customData || {}));
4090 }
4091 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
4092 if (!tokenResponse || !('oauthAccessToken' in tokenResponse)) {
4093 return null;
4094 }
4095 if (!tokenResponse.oauthAccessToken) {
4096 return null;
4097 }
4098 try {
4099 return GithubAuthProvider.credential(tokenResponse.oauthAccessToken);
4100 }
4101 catch (_a) {
4102 return null;
4103 }
4104 }
4105}
4106/** Always set to {@link SignInMethod}.GITHUB. */
4107GithubAuthProvider.GITHUB_SIGN_IN_METHOD = "github.com" /* GITHUB */;
4108/** Always set to {@link ProviderId}.GITHUB. */
4109GithubAuthProvider.PROVIDER_ID = "github.com" /* GITHUB */;
4110
4111/**
4112 * @license
4113 * Copyright 2020 Google LLC
4114 *
4115 * Licensed under the Apache License, Version 2.0 (the "License");
4116 * you may not use this file except in compliance with the License.
4117 * You may obtain a copy of the License at
4118 *
4119 * http://www.apache.org/licenses/LICENSE-2.0
4120 *
4121 * Unless required by applicable law or agreed to in writing, software
4122 * distributed under the License is distributed on an "AS IS" BASIS,
4123 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4124 * See the License for the specific language governing permissions and
4125 * limitations under the License.
4126 */
4127const IDP_REQUEST_URI = 'http://localhost';
4128/**
4129 * @public
4130 */
4131class SAMLAuthCredential extends AuthCredential {
4132 /** @internal */
4133 constructor(providerId, pendingToken) {
4134 super(providerId, providerId);
4135 this.pendingToken = pendingToken;
4136 }
4137 /** @internal */
4138 _getIdTokenResponse(auth) {
4139 const request = this.buildRequest();
4140 return signInWithIdp(auth, request);
4141 }
4142 /** @internal */
4143 _linkToIdToken(auth, idToken) {
4144 const request = this.buildRequest();
4145 request.idToken = idToken;
4146 return signInWithIdp(auth, request);
4147 }
4148 /** @internal */
4149 _getReauthenticationResolver(auth) {
4150 const request = this.buildRequest();
4151 request.autoCreate = false;
4152 return signInWithIdp(auth, request);
4153 }
4154 /** {@inheritdoc AuthCredential.toJSON} */
4155 toJSON() {
4156 return {
4157 signInMethod: this.signInMethod,
4158 providerId: this.providerId,
4159 pendingToken: this.pendingToken
4160 };
4161 }
4162 /**
4163 * Static method to deserialize a JSON representation of an object into an
4164 * {@link AuthCredential}.
4165 *
4166 * @param json - Input can be either Object or the stringified representation of the object.
4167 * When string is provided, JSON.parse would be called first.
4168 *
4169 * @returns If the JSON input does not represent an {@link AuthCredential}, null is returned.
4170 */
4171 static fromJSON(json) {
4172 const obj = typeof json === 'string' ? JSON.parse(json) : json;
4173 const { providerId, signInMethod, pendingToken } = obj;
4174 if (!providerId ||
4175 !signInMethod ||
4176 !pendingToken ||
4177 providerId !== signInMethod) {
4178 return null;
4179 }
4180 return new SAMLAuthCredential(providerId, pendingToken);
4181 }
4182 /**
4183 * Helper static method to avoid exposing the constructor to end users.
4184 *
4185 * @internal
4186 */
4187 static _create(providerId, pendingToken) {
4188 return new SAMLAuthCredential(providerId, pendingToken);
4189 }
4190 buildRequest() {
4191 return {
4192 requestUri: IDP_REQUEST_URI,
4193 returnSecureToken: true,
4194 pendingToken: this.pendingToken
4195 };
4196 }
4197}
4198
4199/**
4200 * @license
4201 * Copyright 2020 Google LLC
4202 *
4203 * Licensed under the Apache License, Version 2.0 (the "License");
4204 * you may not use this file except in compliance with the License.
4205 * You may obtain a copy of the License at
4206 *
4207 * http://www.apache.org/licenses/LICENSE-2.0
4208 *
4209 * Unless required by applicable law or agreed to in writing, software
4210 * distributed under the License is distributed on an "AS IS" BASIS,
4211 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4212 * See the License for the specific language governing permissions and
4213 * limitations under the License.
4214 */
4215const SAML_PROVIDER_PREFIX = 'saml.';
4216/**
4217 * An {@link AuthProvider} for SAML.
4218 *
4219 * @public
4220 */
4221class SAMLAuthProvider extends FederatedAuthProvider {
4222 /**
4223 * Constructor. The providerId must start with "saml."
4224 * @param providerId - SAML provider ID.
4225 */
4226 constructor(providerId) {
4227 _assert(providerId.startsWith(SAML_PROVIDER_PREFIX), "argument-error" /* ARGUMENT_ERROR */);
4228 super(providerId);
4229 }
4230 /**
4231 * Generates an {@link AuthCredential} from a {@link UserCredential} after a
4232 * successful SAML flow completes.
4233 *
4234 * @remarks
4235 *
4236 * For example, to get an {@link AuthCredential}, you could write the
4237 * following code:
4238 *
4239 * ```js
4240 * const userCredential = await signInWithPopup(auth, samlProvider);
4241 * const credential = SAMLAuthProvider.credentialFromResult(userCredential);
4242 * ```
4243 *
4244 * @param userCredential - The user credential.
4245 */
4246 static credentialFromResult(userCredential) {
4247 return SAMLAuthProvider.samlCredentialFromTaggedObject(userCredential);
4248 }
4249 /**
4250 * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
4251 * thrown during a sign-in, link, or reauthenticate operation.
4252 *
4253 * @param userCredential - The user credential.
4254 */
4255 static credentialFromError(error) {
4256 return SAMLAuthProvider.samlCredentialFromTaggedObject((error.customData || {}));
4257 }
4258 /**
4259 * Creates an {@link AuthCredential} from a JSON string or a plain object.
4260 * @param json - A plain object or a JSON string
4261 */
4262 static credentialFromJSON(json) {
4263 const credential = SAMLAuthCredential.fromJSON(json);
4264 _assert(credential, "argument-error" /* ARGUMENT_ERROR */);
4265 return credential;
4266 }
4267 static samlCredentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
4268 if (!tokenResponse) {
4269 return null;
4270 }
4271 const { pendingToken, providerId } = tokenResponse;
4272 if (!pendingToken || !providerId) {
4273 return null;
4274 }
4275 try {
4276 return SAMLAuthCredential._create(providerId, pendingToken);
4277 }
4278 catch (e) {
4279 return null;
4280 }
4281 }
4282}
4283
4284/**
4285 * @license
4286 * Copyright 2020 Google LLC
4287 *
4288 * Licensed under the Apache License, Version 2.0 (the "License");
4289 * you may not use this file except in compliance with the License.
4290 * You may obtain a copy of the License at
4291 *
4292 * http://www.apache.org/licenses/LICENSE-2.0
4293 *
4294 * Unless required by applicable law or agreed to in writing, software
4295 * distributed under the License is distributed on an "AS IS" BASIS,
4296 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4297 * See the License for the specific language governing permissions and
4298 * limitations under the License.
4299 */
4300/**
4301 * Provider for generating an {@link OAuthCredential} for {@link ProviderId}.TWITTER.
4302 *
4303 * @example
4304 * ```javascript
4305 * // Sign in using a redirect.
4306 * const provider = new TwitterAuthProvider();
4307 * // Start a sign in process for an unauthenticated user.
4308 * await signInWithRedirect(auth, provider);
4309 * // This will trigger a full page redirect away from your app
4310 *
4311 * // After returning from the redirect when your app initializes you can obtain the result
4312 * const result = await getRedirectResult(auth);
4313 * if (result) {
4314 * // This is the signed-in user
4315 * const user = result.user;
4316 * // This gives you a Twitter Access Token and Secret.
4317 * const credential = TwitterAuthProvider.credentialFromResult(result);
4318 * const token = credential.accessToken;
4319 * const secret = credential.secret;
4320 * }
4321 * ```
4322 *
4323 * @example
4324 * ```javascript
4325 * // Sign in using a popup.
4326 * const provider = new TwitterAuthProvider();
4327 * const result = await signInWithPopup(auth, provider);
4328 *
4329 * // The signed-in user info.
4330 * const user = result.user;
4331 * // This gives you a Twitter Access Token and Secret.
4332 * const credential = TwitterAuthProvider.credentialFromResult(result);
4333 * const token = credential.accessToken;
4334 * const secret = credential.secret;
4335 * ```
4336 *
4337 * @public
4338 */
4339class TwitterAuthProvider extends BaseOAuthProvider {
4340 constructor() {
4341 super("twitter.com" /* TWITTER */);
4342 }
4343 /**
4344 * Creates a credential for Twitter.
4345 *
4346 * @param token - Twitter access token.
4347 * @param secret - Twitter secret.
4348 */
4349 static credential(token, secret) {
4350 return OAuthCredential._fromParams({
4351 providerId: TwitterAuthProvider.PROVIDER_ID,
4352 signInMethod: TwitterAuthProvider.TWITTER_SIGN_IN_METHOD,
4353 oauthToken: token,
4354 oauthTokenSecret: secret
4355 });
4356 }
4357 /**
4358 * Used to extract the underlying {@link OAuthCredential} from a {@link UserCredential}.
4359 *
4360 * @param userCredential - The user credential.
4361 */
4362 static credentialFromResult(userCredential) {
4363 return TwitterAuthProvider.credentialFromTaggedObject(userCredential);
4364 }
4365 /**
4366 * Used to extract the underlying {@link OAuthCredential} from a {@link AuthError} which was
4367 * thrown during a sign-in, link, or reauthenticate operation.
4368 *
4369 * @param userCredential - The user credential.
4370 */
4371 static credentialFromError(error) {
4372 return TwitterAuthProvider.credentialFromTaggedObject((error.customData || {}));
4373 }
4374 static credentialFromTaggedObject({ _tokenResponse: tokenResponse }) {
4375 if (!tokenResponse) {
4376 return null;
4377 }
4378 const { oauthAccessToken, oauthTokenSecret } = tokenResponse;
4379 if (!oauthAccessToken || !oauthTokenSecret) {
4380 return null;
4381 }
4382 try {
4383 return TwitterAuthProvider.credential(oauthAccessToken, oauthTokenSecret);
4384 }
4385 catch (_a) {
4386 return null;
4387 }
4388 }
4389}
4390/** Always set to {@link SignInMethod}.TWITTER. */
4391TwitterAuthProvider.TWITTER_SIGN_IN_METHOD = "twitter.com" /* TWITTER */;
4392/** Always set to {@link ProviderId}.TWITTER. */
4393TwitterAuthProvider.PROVIDER_ID = "twitter.com" /* TWITTER */;
4394
4395/**
4396 * @license
4397 * Copyright 2020 Google LLC
4398 *
4399 * Licensed under the Apache License, Version 2.0 (the "License");
4400 * you may not use this file except in compliance with the License.
4401 * You may obtain a copy of the License at
4402 *
4403 * http://www.apache.org/licenses/LICENSE-2.0
4404 *
4405 * Unless required by applicable law or agreed to in writing, software
4406 * distributed under the License is distributed on an "AS IS" BASIS,
4407 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4408 * See the License for the specific language governing permissions and
4409 * limitations under the License.
4410 */
4411async function signUp(auth, request) {
4412 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signUp" /* SIGN_UP */, _addTidIfNecessary(auth, request));
4413}
4414
4415/**
4416 * @license
4417 * Copyright 2020 Google LLC
4418 *
4419 * Licensed under the Apache License, Version 2.0 (the "License");
4420 * you may not use this file except in compliance with the License.
4421 * You may obtain a copy of the License at
4422 *
4423 * http://www.apache.org/licenses/LICENSE-2.0
4424 *
4425 * Unless required by applicable law or agreed to in writing, software
4426 * distributed under the License is distributed on an "AS IS" BASIS,
4427 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4428 * See the License for the specific language governing permissions and
4429 * limitations under the License.
4430 */
4431class UserCredentialImpl {
4432 constructor(params) {
4433 this.user = params.user;
4434 this.providerId = params.providerId;
4435 this._tokenResponse = params._tokenResponse;
4436 this.operationType = params.operationType;
4437 }
4438 static async _fromIdTokenResponse(auth, operationType, idTokenResponse, isAnonymous = false) {
4439 const user = await UserImpl._fromIdTokenResponse(auth, idTokenResponse, isAnonymous);
4440 const providerId = providerIdForResponse(idTokenResponse);
4441 const userCred = new UserCredentialImpl({
4442 user,
4443 providerId,
4444 _tokenResponse: idTokenResponse,
4445 operationType
4446 });
4447 return userCred;
4448 }
4449 static async _forOperation(user, operationType, response) {
4450 await user._updateTokensIfNecessary(response, /* reload */ true);
4451 const providerId = providerIdForResponse(response);
4452 return new UserCredentialImpl({
4453 user,
4454 providerId,
4455 _tokenResponse: response,
4456 operationType
4457 });
4458 }
4459}
4460function providerIdForResponse(response) {
4461 if (response.providerId) {
4462 return response.providerId;
4463 }
4464 if ('phoneNumber' in response) {
4465 return "phone" /* PHONE */;
4466 }
4467 return null;
4468}
4469
4470/**
4471 * @license
4472 * Copyright 2020 Google LLC
4473 *
4474 * Licensed under the Apache License, Version 2.0 (the "License");
4475 * you may not use this file except in compliance with the License.
4476 * You may obtain a copy of the License at
4477 *
4478 * http://www.apache.org/licenses/LICENSE-2.0
4479 *
4480 * Unless required by applicable law or agreed to in writing, software
4481 * distributed under the License is distributed on an "AS IS" BASIS,
4482 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4483 * See the License for the specific language governing permissions and
4484 * limitations under the License.
4485 */
4486/**
4487 * Asynchronously signs in as an anonymous user.
4488 *
4489 * @remarks
4490 * If there is already an anonymous user signed in, that user will be returned; otherwise, a
4491 * new anonymous user identity will be created and returned.
4492 *
4493 * @param auth - The {@link Auth} instance.
4494 *
4495 * @public
4496 */
4497async function signInAnonymously(auth) {
4498 var _a;
4499 const authInternal = _castAuth(auth);
4500 await authInternal._initializationPromise;
4501 if ((_a = authInternal.currentUser) === null || _a === void 0 ? void 0 : _a.isAnonymous) {
4502 // If an anonymous user is already signed in, no need to sign them in again.
4503 return new UserCredentialImpl({
4504 user: authInternal.currentUser,
4505 providerId: null,
4506 operationType: "signIn" /* SIGN_IN */
4507 });
4508 }
4509 const response = await signUp(authInternal, {
4510 returnSecureToken: true
4511 });
4512 const userCredential = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* SIGN_IN */, response, true);
4513 await authInternal._updateCurrentUser(userCredential.user);
4514 return userCredential;
4515}
4516
4517/**
4518 * @license
4519 * Copyright 2020 Google LLC
4520 *
4521 * Licensed under the Apache License, Version 2.0 (the "License");
4522 * you may not use this file except in compliance with the License.
4523 * You may obtain a copy of the License at
4524 *
4525 * http://www.apache.org/licenses/LICENSE-2.0
4526 *
4527 * Unless required by applicable law or agreed to in writing, software
4528 * distributed under the License is distributed on an "AS IS" BASIS,
4529 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4530 * See the License for the specific language governing permissions and
4531 * limitations under the License.
4532 */
4533class MultiFactorError extends FirebaseError {
4534 constructor(auth, error, operationType, user) {
4535 var _a;
4536 super(error.code, error.message);
4537 this.operationType = operationType;
4538 this.user = user;
4539 // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
4540 Object.setPrototypeOf(this, MultiFactorError.prototype);
4541 this.customData = {
4542 appName: auth.name,
4543 tenantId: (_a = auth.tenantId) !== null && _a !== void 0 ? _a : undefined,
4544 _serverResponse: error.customData._serverResponse,
4545 operationType,
4546 };
4547 }
4548 static _fromErrorAndOperation(auth, error, operationType, user) {
4549 return new MultiFactorError(auth, error, operationType, user);
4550 }
4551}
4552function _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential, user) {
4553 const idTokenProvider = operationType === "reauthenticate" /* REAUTHENTICATE */
4554 ? credential._getReauthenticationResolver(auth)
4555 : credential._getIdTokenResponse(auth);
4556 return idTokenProvider.catch(error => {
4557 if (error.code === `auth/${"multi-factor-auth-required" /* MFA_REQUIRED */}`) {
4558 throw MultiFactorError._fromErrorAndOperation(auth, error, operationType, user);
4559 }
4560 throw error;
4561 });
4562}
4563
4564/**
4565 * @license
4566 * Copyright 2020 Google LLC
4567 *
4568 * Licensed under the Apache License, Version 2.0 (the "License");
4569 * you may not use this file except in compliance with the License.
4570 * You may obtain a copy of the License at
4571 *
4572 * http://www.apache.org/licenses/LICENSE-2.0
4573 *
4574 * Unless required by applicable law or agreed to in writing, software
4575 * distributed under the License is distributed on an "AS IS" BASIS,
4576 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4577 * See the License for the specific language governing permissions and
4578 * limitations under the License.
4579 */
4580/**
4581 * Takes a set of UserInfo provider data and converts it to a set of names
4582 */
4583function providerDataAsNames(providerData) {
4584 return new Set(providerData
4585 .map(({ providerId }) => providerId)
4586 .filter(pid => !!pid));
4587}
4588
4589/**
4590 * @license
4591 * Copyright 2019 Google LLC
4592 *
4593 * Licensed under the Apache License, Version 2.0 (the "License");
4594 * you may not use this file except in compliance with the License.
4595 * You may obtain a copy of the License at
4596 *
4597 * http://www.apache.org/licenses/LICENSE-2.0
4598 *
4599 * Unless required by applicable law or agreed to in writing, software
4600 * distributed under the License is distributed on an "AS IS" BASIS,
4601 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4602 * See the License for the specific language governing permissions and
4603 * limitations under the License.
4604 */
4605/**
4606 * Unlinks a provider from a user account.
4607 *
4608 * @param user - The user.
4609 * @param providerId - The provider to unlink.
4610 *
4611 * @public
4612 */
4613async function unlink(user, providerId) {
4614 const userInternal = getModularInstance(user);
4615 await _assertLinkedStatus(true, userInternal, providerId);
4616 const { providerUserInfo } = await deleteLinkedAccounts(userInternal.auth, {
4617 idToken: await userInternal.getIdToken(),
4618 deleteProvider: [providerId]
4619 });
4620 const providersLeft = providerDataAsNames(providerUserInfo || []);
4621 userInternal.providerData = userInternal.providerData.filter(pd => providersLeft.has(pd.providerId));
4622 if (!providersLeft.has("phone" /* PHONE */)) {
4623 userInternal.phoneNumber = null;
4624 }
4625 await userInternal.auth._persistUserIfCurrent(userInternal);
4626 return userInternal;
4627}
4628async function _link(user, credential, bypassAuthState = false) {
4629 const response = await _logoutIfInvalidated(user, credential._linkToIdToken(user.auth, await user.getIdToken()), bypassAuthState);
4630 return UserCredentialImpl._forOperation(user, "link" /* LINK */, response);
4631}
4632async function _assertLinkedStatus(expected, user, provider) {
4633 await _reloadWithoutSaving(user);
4634 const providerIds = providerDataAsNames(user.providerData);
4635 const code = expected === false
4636 ? "provider-already-linked" /* PROVIDER_ALREADY_LINKED */
4637 : "no-such-provider" /* NO_SUCH_PROVIDER */;
4638 _assert(providerIds.has(provider) === expected, user.auth, code);
4639}
4640
4641/**
4642 * @license
4643 * Copyright 2019 Google LLC
4644 *
4645 * Licensed under the Apache License, Version 2.0 (the "License");
4646 * you may not use this file except in compliance with the License.
4647 * You may obtain a copy of the License at
4648 *
4649 * http://www.apache.org/licenses/LICENSE-2.0
4650 *
4651 * Unless required by applicable law or agreed to in writing, software
4652 * distributed under the License is distributed on an "AS IS" BASIS,
4653 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4654 * See the License for the specific language governing permissions and
4655 * limitations under the License.
4656 */
4657async function _reauthenticate(user, credential, bypassAuthState = false) {
4658 var _a;
4659 const { auth } = user;
4660 const operationType = "reauthenticate" /* REAUTHENTICATE */;
4661 try {
4662 const response = await _logoutIfInvalidated(user, _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential, user), bypassAuthState);
4663 _assert(response.idToken, auth, "internal-error" /* INTERNAL_ERROR */);
4664 const parsed = _parseToken(response.idToken);
4665 _assert(parsed, auth, "internal-error" /* INTERNAL_ERROR */);
4666 const { sub: localId } = parsed;
4667 _assert(user.uid === localId, auth, "user-mismatch" /* USER_MISMATCH */);
4668 return UserCredentialImpl._forOperation(user, operationType, response);
4669 }
4670 catch (e) {
4671 // Convert user deleted error into user mismatch
4672 if (((_a = e) === null || _a === void 0 ? void 0 : _a.code) === `auth/${"user-not-found" /* USER_DELETED */}`) {
4673 _fail(auth, "user-mismatch" /* USER_MISMATCH */);
4674 }
4675 throw e;
4676 }
4677}
4678
4679/**
4680 * @license
4681 * Copyright 2020 Google LLC
4682 *
4683 * Licensed under the Apache License, Version 2.0 (the "License");
4684 * you may not use this file except in compliance with the License.
4685 * You may obtain a copy of the License at
4686 *
4687 * http://www.apache.org/licenses/LICENSE-2.0
4688 *
4689 * Unless required by applicable law or agreed to in writing, software
4690 * distributed under the License is distributed on an "AS IS" BASIS,
4691 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4692 * See the License for the specific language governing permissions and
4693 * limitations under the License.
4694 */
4695async function _signInWithCredential(auth, credential, bypassAuthState = false) {
4696 const operationType = "signIn" /* SIGN_IN */;
4697 const response = await _processCredentialSavingMfaContextIfNecessary(auth, operationType, credential);
4698 const userCredential = await UserCredentialImpl._fromIdTokenResponse(auth, operationType, response);
4699 if (!bypassAuthState) {
4700 await auth._updateCurrentUser(userCredential.user);
4701 }
4702 return userCredential;
4703}
4704/**
4705 * Asynchronously signs in with the given credentials.
4706 *
4707 * @remarks
4708 * An {@link AuthProvider} can be used to generate the credential.
4709 *
4710 * @param auth - The {@link Auth} instance.
4711 * @param credential - The auth credential.
4712 *
4713 * @public
4714 */
4715async function signInWithCredential(auth, credential) {
4716 return _signInWithCredential(_castAuth(auth), credential);
4717}
4718/**
4719 * Links the user account with the given credentials.
4720 *
4721 * @remarks
4722 * An {@link AuthProvider} can be used to generate the credential.
4723 *
4724 * @param user - The user.
4725 * @param credential - The auth credential.
4726 *
4727 * @public
4728 */
4729async function linkWithCredential(user, credential) {
4730 const userInternal = getModularInstance(user);
4731 await _assertLinkedStatus(false, userInternal, credential.providerId);
4732 return _link(userInternal, credential);
4733}
4734/**
4735 * Re-authenticates a user using a fresh credential.
4736 *
4737 * @remarks
4738 * Use before operations such as {@link updatePassword} that require tokens from recent sign-in
4739 * attempts. This method can be used to recover from a `CREDENTIAL_TOO_OLD_LOGIN_AGAIN` error.
4740 *
4741 * @param user - The user.
4742 * @param credential - The auth credential.
4743 *
4744 * @public
4745 */
4746async function reauthenticateWithCredential(user, credential) {
4747 return _reauthenticate(getModularInstance(user), credential);
4748}
4749
4750/**
4751 * @license
4752 * Copyright 2020 Google LLC
4753 *
4754 * Licensed under the Apache License, Version 2.0 (the "License");
4755 * you may not use this file except in compliance with the License.
4756 * You may obtain a copy of the License at
4757 *
4758 * http://www.apache.org/licenses/LICENSE-2.0
4759 *
4760 * Unless required by applicable law or agreed to in writing, software
4761 * distributed under the License is distributed on an "AS IS" BASIS,
4762 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4763 * See the License for the specific language governing permissions and
4764 * limitations under the License.
4765 */
4766async function signInWithCustomToken$1(auth, request) {
4767 return _performSignInRequest(auth, "POST" /* POST */, "/v1/accounts:signInWithCustomToken" /* SIGN_IN_WITH_CUSTOM_TOKEN */, _addTidIfNecessary(auth, request));
4768}
4769
4770/**
4771 * @license
4772 * Copyright 2020 Google LLC
4773 *
4774 * Licensed under the Apache License, Version 2.0 (the "License");
4775 * you may not use this file except in compliance with the License.
4776 * You may obtain a copy of the License at
4777 *
4778 * http://www.apache.org/licenses/LICENSE-2.0
4779 *
4780 * Unless required by applicable law or agreed to in writing, software
4781 * distributed under the License is distributed on an "AS IS" BASIS,
4782 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4783 * See the License for the specific language governing permissions and
4784 * limitations under the License.
4785 */
4786/**
4787 * Asynchronously signs in using a custom token.
4788 *
4789 * @remarks
4790 * Custom tokens are used to integrate Firebase Auth with existing auth systems, and must
4791 * be generated by an auth backend using the
4792 * {@link https://firebase.google.com/docs/reference/admin/node/admin.auth.Auth#createcustomtoken | createCustomToken}
4793 * method in the {@link https://firebase.google.com/docs/auth/admin | Admin SDK} .
4794 *
4795 * Fails with an error if the token is invalid, expired, or not accepted by the Firebase Auth service.
4796 *
4797 * @param auth - The {@link Auth} instance.
4798 * @param customToken - The custom token to sign in with.
4799 *
4800 * @public
4801 */
4802async function signInWithCustomToken(auth, customToken) {
4803 const authInternal = _castAuth(auth);
4804 const response = await signInWithCustomToken$1(authInternal, {
4805 token: customToken,
4806 returnSecureToken: true
4807 });
4808 const cred = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* SIGN_IN */, response);
4809 await authInternal._updateCurrentUser(cred.user);
4810 return cred;
4811}
4812
4813/**
4814 * @license
4815 * Copyright 2020 Google LLC
4816 *
4817 * Licensed under the Apache License, Version 2.0 (the "License");
4818 * you may not use this file except in compliance with the License.
4819 * You may obtain a copy of the License at
4820 *
4821 * http://www.apache.org/licenses/LICENSE-2.0
4822 *
4823 * Unless required by applicable law or agreed to in writing, software
4824 * distributed under the License is distributed on an "AS IS" BASIS,
4825 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4826 * See the License for the specific language governing permissions and
4827 * limitations under the License.
4828 */
4829class MultiFactorInfoImpl {
4830 constructor(factorId, response) {
4831 this.factorId = factorId;
4832 this.uid = response.mfaEnrollmentId;
4833 this.enrollmentTime = new Date(response.enrolledAt).toUTCString();
4834 this.displayName = response.displayName;
4835 }
4836 static _fromServerResponse(auth, enrollment) {
4837 if ('phoneInfo' in enrollment) {
4838 return PhoneMultiFactorInfoImpl._fromServerResponse(auth, enrollment);
4839 }
4840 return _fail(auth, "internal-error" /* INTERNAL_ERROR */);
4841 }
4842}
4843class PhoneMultiFactorInfoImpl extends MultiFactorInfoImpl {
4844 constructor(response) {
4845 super("phone" /* PHONE */, response);
4846 this.phoneNumber = response.phoneInfo;
4847 }
4848 static _fromServerResponse(_auth, enrollment) {
4849 return new PhoneMultiFactorInfoImpl(enrollment);
4850 }
4851}
4852
4853/**
4854 * @license
4855 * Copyright 2020 Google LLC
4856 *
4857 * Licensed under the Apache License, Version 2.0 (the "License");
4858 * you may not use this file except in compliance with the License.
4859 * You may obtain a copy of the License at
4860 *
4861 * http://www.apache.org/licenses/LICENSE-2.0
4862 *
4863 * Unless required by applicable law or agreed to in writing, software
4864 * distributed under the License is distributed on an "AS IS" BASIS,
4865 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4866 * See the License for the specific language governing permissions and
4867 * limitations under the License.
4868 */
4869function _setActionCodeSettingsOnRequest(auth, request, actionCodeSettings) {
4870 var _a;
4871 _assert(((_a = actionCodeSettings.url) === null || _a === void 0 ? void 0 : _a.length) > 0, auth, "invalid-continue-uri" /* INVALID_CONTINUE_URI */);
4872 _assert(typeof actionCodeSettings.dynamicLinkDomain === 'undefined' ||
4873 actionCodeSettings.dynamicLinkDomain.length > 0, auth, "invalid-dynamic-link-domain" /* INVALID_DYNAMIC_LINK_DOMAIN */);
4874 request.continueUrl = actionCodeSettings.url;
4875 request.dynamicLinkDomain = actionCodeSettings.dynamicLinkDomain;
4876 request.canHandleCodeInApp = actionCodeSettings.handleCodeInApp;
4877 if (actionCodeSettings.iOS) {
4878 _assert(actionCodeSettings.iOS.bundleId.length > 0, auth, "missing-ios-bundle-id" /* MISSING_IOS_BUNDLE_ID */);
4879 request.iOSBundleId = actionCodeSettings.iOS.bundleId;
4880 }
4881 if (actionCodeSettings.android) {
4882 _assert(actionCodeSettings.android.packageName.length > 0, auth, "missing-android-pkg-name" /* MISSING_ANDROID_PACKAGE_NAME */);
4883 request.androidInstallApp = actionCodeSettings.android.installApp;
4884 request.androidMinimumVersionCode =
4885 actionCodeSettings.android.minimumVersion;
4886 request.androidPackageName = actionCodeSettings.android.packageName;
4887 }
4888}
4889
4890/**
4891 * @license
4892 * Copyright 2020 Google LLC
4893 *
4894 * Licensed under the Apache License, Version 2.0 (the "License");
4895 * you may not use this file except in compliance with the License.
4896 * You may obtain a copy of the License at
4897 *
4898 * http://www.apache.org/licenses/LICENSE-2.0
4899 *
4900 * Unless required by applicable law or agreed to in writing, software
4901 * distributed under the License is distributed on an "AS IS" BASIS,
4902 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4903 * See the License for the specific language governing permissions and
4904 * limitations under the License.
4905 */
4906/**
4907 * Sends a password reset email to the given email address.
4908 *
4909 * @remarks
4910 * To complete the password reset, call {@link confirmPasswordReset} with the code supplied in
4911 * the email sent to the user, along with the new password specified by the user.
4912 *
4913 * @example
4914 * ```javascript
4915 * const actionCodeSettings = {
4916 * url: 'https://www.example.com/?email=user@example.com',
4917 * iOS: {
4918 * bundleId: 'com.example.ios'
4919 * },
4920 * android: {
4921 * packageName: 'com.example.android',
4922 * installApp: true,
4923 * minimumVersion: '12'
4924 * },
4925 * handleCodeInApp: true
4926 * };
4927 * await sendPasswordResetEmail(auth, 'user@example.com', actionCodeSettings);
4928 * // Obtain code from user.
4929 * await confirmPasswordReset('user@example.com', code);
4930 * ```
4931 *
4932 * @param auth - The {@link Auth} instance.
4933 * @param email - The user's email address.
4934 * @param actionCodeSettings - The {@link ActionCodeSettings}.
4935 *
4936 * @public
4937 */
4938async function sendPasswordResetEmail(auth, email, actionCodeSettings) {
4939 const authModular = getModularInstance(auth);
4940 const request = {
4941 requestType: "PASSWORD_RESET" /* PASSWORD_RESET */,
4942 email
4943 };
4944 if (actionCodeSettings) {
4945 _setActionCodeSettingsOnRequest(authModular, request, actionCodeSettings);
4946 }
4947 await sendPasswordResetEmail$1(authModular, request);
4948}
4949/**
4950 * Completes the password reset process, given a confirmation code and new password.
4951 *
4952 * @param auth - The {@link Auth} instance.
4953 * @param oobCode - A confirmation code sent to the user.
4954 * @param newPassword - The new password.
4955 *
4956 * @public
4957 */
4958async function confirmPasswordReset(auth, oobCode, newPassword) {
4959 await resetPassword(getModularInstance(auth), {
4960 oobCode,
4961 newPassword
4962 });
4963 // Do not return the email.
4964}
4965/**
4966 * Applies a verification code sent to the user by email or other out-of-band mechanism.
4967 *
4968 * @param auth - The {@link Auth} instance.
4969 * @param oobCode - A verification code sent to the user.
4970 *
4971 * @public
4972 */
4973async function applyActionCode(auth, oobCode) {
4974 await applyActionCode$1(getModularInstance(auth), { oobCode });
4975}
4976/**
4977 * Checks a verification code sent to the user by email or other out-of-band mechanism.
4978 *
4979 * @returns metadata about the code.
4980 *
4981 * @param auth - The {@link Auth} instance.
4982 * @param oobCode - A verification code sent to the user.
4983 *
4984 * @public
4985 */
4986async function checkActionCode(auth, oobCode) {
4987 const authModular = getModularInstance(auth);
4988 const response = await resetPassword(authModular, { oobCode });
4989 // Email could be empty only if the request type is EMAIL_SIGNIN or
4990 // VERIFY_AND_CHANGE_EMAIL.
4991 // New email should not be empty if the request type is
4992 // VERIFY_AND_CHANGE_EMAIL.
4993 // Multi-factor info could not be empty if the request type is
4994 // REVERT_SECOND_FACTOR_ADDITION.
4995 const operation = response.requestType;
4996 _assert(operation, authModular, "internal-error" /* INTERNAL_ERROR */);
4997 switch (operation) {
4998 case "EMAIL_SIGNIN" /* EMAIL_SIGNIN */:
4999 break;
5000 case "VERIFY_AND_CHANGE_EMAIL" /* VERIFY_AND_CHANGE_EMAIL */:
5001 _assert(response.newEmail, authModular, "internal-error" /* INTERNAL_ERROR */);
5002 break;
5003 case "REVERT_SECOND_FACTOR_ADDITION" /* REVERT_SECOND_FACTOR_ADDITION */:
5004 _assert(response.mfaInfo, authModular, "internal-error" /* INTERNAL_ERROR */);
5005 // fall through
5006 default:
5007 _assert(response.email, authModular, "internal-error" /* INTERNAL_ERROR */);
5008 }
5009 // The multi-factor info for revert second factor addition
5010 let multiFactorInfo = null;
5011 if (response.mfaInfo) {
5012 multiFactorInfo = MultiFactorInfoImpl._fromServerResponse(_castAuth(authModular), response.mfaInfo);
5013 }
5014 return {
5015 data: {
5016 email: (response.requestType === "VERIFY_AND_CHANGE_EMAIL" /* VERIFY_AND_CHANGE_EMAIL */
5017 ? response.newEmail
5018 : response.email) || null,
5019 previousEmail: (response.requestType === "VERIFY_AND_CHANGE_EMAIL" /* VERIFY_AND_CHANGE_EMAIL */
5020 ? response.email
5021 : response.newEmail) || null,
5022 multiFactorInfo
5023 },
5024 operation
5025 };
5026}
5027/**
5028 * Checks a password reset code sent to the user by email or other out-of-band mechanism.
5029 *
5030 * @returns the user's email address if valid.
5031 *
5032 * @param auth - The {@link Auth} instance.
5033 * @param code - A verification code sent to the user.
5034 *
5035 * @public
5036 */
5037async function verifyPasswordResetCode(auth, code) {
5038 const { data } = await checkActionCode(getModularInstance(auth), code);
5039 // Email should always be present since a code was sent to it
5040 return data.email;
5041}
5042/**
5043 * Creates a new user account associated with the specified email address and password.
5044 *
5045 * @remarks
5046 * On successful creation of the user account, this user will also be signed in to your application.
5047 *
5048 * User account creation can fail if the account already exists or the password is invalid.
5049 *
5050 * Note: The email address acts as a unique identifier for the user and enables an email-based
5051 * password reset. This function will create a new user account and set the initial user password.
5052 *
5053 * @param auth - The {@link Auth} instance.
5054 * @param email - The user's email address.
5055 * @param password - The user's chosen password.
5056 *
5057 * @public
5058 */
5059async function createUserWithEmailAndPassword(auth, email, password) {
5060 const authInternal = _castAuth(auth);
5061 const response = await signUp(authInternal, {
5062 returnSecureToken: true,
5063 email,
5064 password
5065 });
5066 const userCredential = await UserCredentialImpl._fromIdTokenResponse(authInternal, "signIn" /* SIGN_IN */, response);
5067 await authInternal._updateCurrentUser(userCredential.user);
5068 return userCredential;
5069}
5070/**
5071 * Asynchronously signs in using an email and password.
5072 *
5073 * @remarks
5074 * Fails with an error if the email address and password do not match.
5075 *
5076 * Note: The user's password is NOT the password used to access the user's email account. The
5077 * email address serves as a unique identifier for the user, and the password is used to access
5078 * the user's account in your Firebase project. See also: {@link createUserWithEmailAndPassword}.
5079 *
5080 * @param auth - The {@link Auth} instance.
5081 * @param email - The users email address.
5082 * @param password - The users password.
5083 *
5084 * @public
5085 */
5086function signInWithEmailAndPassword(auth, email, password) {
5087 return signInWithCredential(getModularInstance(auth), EmailAuthProvider.credential(email, password));
5088}
5089
5090/**
5091 * @license
5092 * Copyright 2020 Google LLC
5093 *
5094 * Licensed under the Apache License, Version 2.0 (the "License");
5095 * you may not use this file except in compliance with the License.
5096 * You may obtain a copy of the License at
5097 *
5098 * http://www.apache.org/licenses/LICENSE-2.0
5099 *
5100 * Unless required by applicable law or agreed to in writing, software
5101 * distributed under the License is distributed on an "AS IS" BASIS,
5102 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5103 * See the License for the specific language governing permissions and
5104 * limitations under the License.
5105 */
5106/**
5107 * Sends a sign-in email link to the user with the specified email.
5108 *
5109 * @remarks
5110 * The sign-in operation has to always be completed in the app unlike other out of band email
5111 * actions (password reset and email verifications). This is because, at the end of the flow,
5112 * the user is expected to be signed in and their Auth state persisted within the app.
5113 *
5114 * To complete sign in with the email link, call {@link signInWithEmailLink} with the email
5115 * address and the email link supplied in the email sent to the user.
5116 *
5117 * @example
5118 * ```javascript
5119 * const actionCodeSettings = {
5120 * url: 'https://www.example.com/?email=user@example.com',
5121 * iOS: {
5122 * bundleId: 'com.example.ios'
5123 * },
5124 * android: {
5125 * packageName: 'com.example.android',
5126 * installApp: true,
5127 * minimumVersion: '12'
5128 * },
5129 * handleCodeInApp: true
5130 * };
5131 * await sendSignInLinkToEmail(auth, 'user@example.com', actionCodeSettings);
5132 * // Obtain emailLink from the user.
5133 * if(isSignInWithEmailLink(auth, emailLink)) {
5134 * await signInWithEmailLink(auth, 'user@example.com', emailLink);
5135 * }
5136 * ```
5137 *
5138 * @param authInternal - The {@link Auth} instance.
5139 * @param email - The user's email address.
5140 * @param actionCodeSettings - The {@link ActionCodeSettings}.
5141 *
5142 * @public
5143 */
5144async function sendSignInLinkToEmail(auth, email, actionCodeSettings) {
5145 const authModular = getModularInstance(auth);
5146 const request = {
5147 requestType: "EMAIL_SIGNIN" /* EMAIL_SIGNIN */,
5148 email
5149 };
5150 _assert(actionCodeSettings.handleCodeInApp, authModular, "argument-error" /* ARGUMENT_ERROR */);
5151 if (actionCodeSettings) {
5152 _setActionCodeSettingsOnRequest(authModular, request, actionCodeSettings);
5153 }
5154 await sendSignInLinkToEmail$1(authModular, request);
5155}
5156/**
5157 * Checks if an incoming link is a sign-in with email link suitable for {@link signInWithEmailLink}.
5158 *
5159 * @param auth - The {@link Auth} instance.
5160 * @param emailLink - The link sent to the user's email address.
5161 *
5162 * @public
5163 */
5164function isSignInWithEmailLink(auth, emailLink) {
5165 const actionCodeUrl = ActionCodeURL.parseLink(emailLink);
5166 return (actionCodeUrl === null || actionCodeUrl === void 0 ? void 0 : actionCodeUrl.operation) === "EMAIL_SIGNIN" /* EMAIL_SIGNIN */;
5167}
5168/**
5169 * Asynchronously signs in using an email and sign-in email link.
5170 *
5171 * @remarks
5172 * If no link is passed, the link is inferred from the current URL.
5173 *
5174 * Fails with an error if the email address is invalid or OTP in email link expires.
5175 *
5176 * Note: Confirm the link is a sign-in email link before calling this method firebase.auth.Auth.isSignInWithEmailLink.
5177 *
5178 * @example
5179 * ```javascript
5180 * const actionCodeSettings = {
5181 * url: 'https://www.example.com/?email=user@example.com',
5182 * iOS: {
5183 * bundleId: 'com.example.ios'
5184 * },
5185 * android: {
5186 * packageName: 'com.example.android',
5187 * installApp: true,
5188 * minimumVersion: '12'
5189 * },
5190 * handleCodeInApp: true
5191 * };
5192 * await sendSignInLinkToEmail(auth, 'user@example.com', actionCodeSettings);
5193 * // Obtain emailLink from the user.
5194 * if(isSignInWithEmailLink(auth, emailLink)) {
5195 * await signInWithEmailLink(auth, 'user@example.com', emailLink);
5196 * }
5197 * ```
5198 *
5199 * @param auth - The {@link Auth} instance.
5200 * @param email - The user's email address.
5201 * @param emailLink - The link sent to the user's email address.
5202 *
5203 * @public
5204 */
5205async function signInWithEmailLink(auth, email, emailLink) {
5206 const authModular = getModularInstance(auth);
5207 const credential = EmailAuthProvider.credentialWithLink(email, emailLink || _getCurrentUrl());
5208 // Check if the tenant ID in the email link matches the tenant ID on Auth
5209 // instance.
5210 _assert(credential._tenantId === (authModular.tenantId || null), authModular, "tenant-id-mismatch" /* TENANT_ID_MISMATCH */);
5211 return signInWithCredential(authModular, credential);
5212}
5213
5214/**
5215 * @license
5216 * Copyright 2020 Google LLC
5217 *
5218 * Licensed under the Apache License, Version 2.0 (the "License");
5219 * you may not use this file except in compliance with the License.
5220 * You may obtain a copy of the License at
5221 *
5222 * http://www.apache.org/licenses/LICENSE-2.0
5223 *
5224 * Unless required by applicable law or agreed to in writing, software
5225 * distributed under the License is distributed on an "AS IS" BASIS,
5226 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5227 * See the License for the specific language governing permissions and
5228 * limitations under the License.
5229 */
5230async function createAuthUri(auth, request) {
5231 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:createAuthUri" /* CREATE_AUTH_URI */, _addTidIfNecessary(auth, request));
5232}
5233
5234/**
5235 * @license
5236 * Copyright 2020 Google LLC
5237 *
5238 * Licensed under the Apache License, Version 2.0 (the "License");
5239 * you may not use this file except in compliance with the License.
5240 * You may obtain a copy of the License at
5241 *
5242 * http://www.apache.org/licenses/LICENSE-2.0
5243 *
5244 * Unless required by applicable law or agreed to in writing, software
5245 * distributed under the License is distributed on an "AS IS" BASIS,
5246 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5247 * See the License for the specific language governing permissions and
5248 * limitations under the License.
5249 */
5250/**
5251 * Gets the list of possible sign in methods for the given email address.
5252 *
5253 * @remarks
5254 * This is useful to differentiate methods of sign-in for the same provider, eg.
5255 * {@link EmailAuthProvider} which has 2 methods of sign-in,
5256 * {@link SignInMethod}.EMAIL_PASSWORD and
5257 * {@link SignInMethod}.EMAIL_LINK.
5258 *
5259 * @param auth - The {@link Auth} instance.
5260 * @param email - The user's email address.
5261 *
5262 * @public
5263 */
5264async function fetchSignInMethodsForEmail(auth, email) {
5265 // createAuthUri returns an error if continue URI is not http or https.
5266 // For environments like Cordova, Chrome extensions, native frameworks, file
5267 // systems, etc, use http://localhost as continue URL.
5268 const continueUri = _isHttpOrHttps() ? _getCurrentUrl() : 'http://localhost';
5269 const request = {
5270 identifier: email,
5271 continueUri
5272 };
5273 const { signinMethods } = await createAuthUri(getModularInstance(auth), request);
5274 return signinMethods || [];
5275}
5276/**
5277 * Sends a verification email to a user.
5278 *
5279 * @remarks
5280 * The verification process is completed by calling {@link applyActionCode}.
5281 *
5282 * @example
5283 * ```javascript
5284 * const actionCodeSettings = {
5285 * url: 'https://www.example.com/?email=user@example.com',
5286 * iOS: {
5287 * bundleId: 'com.example.ios'
5288 * },
5289 * android: {
5290 * packageName: 'com.example.android',
5291 * installApp: true,
5292 * minimumVersion: '12'
5293 * },
5294 * handleCodeInApp: true
5295 * };
5296 * await sendEmailVerification(user, actionCodeSettings);
5297 * // Obtain code from the user.
5298 * await applyActionCode(auth, code);
5299 * ```
5300 *
5301 * @param user - The user.
5302 * @param actionCodeSettings - The {@link ActionCodeSettings}.
5303 *
5304 * @public
5305 */
5306async function sendEmailVerification(user, actionCodeSettings) {
5307 const userInternal = getModularInstance(user);
5308 const idToken = await user.getIdToken();
5309 const request = {
5310 requestType: "VERIFY_EMAIL" /* VERIFY_EMAIL */,
5311 idToken
5312 };
5313 if (actionCodeSettings) {
5314 _setActionCodeSettingsOnRequest(userInternal.auth, request, actionCodeSettings);
5315 }
5316 const { email } = await sendEmailVerification$1(userInternal.auth, request);
5317 if (email !== user.email) {
5318 await user.reload();
5319 }
5320}
5321/**
5322 * Sends a verification email to a new email address.
5323 *
5324 * @remarks
5325 * The user's email will be updated to the new one after being verified.
5326 *
5327 * If you have a custom email action handler, you can complete the verification process by calling
5328 * {@link applyActionCode}.
5329 *
5330 * @example
5331 * ```javascript
5332 * const actionCodeSettings = {
5333 * url: 'https://www.example.com/?email=user@example.com',
5334 * iOS: {
5335 * bundleId: 'com.example.ios'
5336 * },
5337 * android: {
5338 * packageName: 'com.example.android',
5339 * installApp: true,
5340 * minimumVersion: '12'
5341 * },
5342 * handleCodeInApp: true
5343 * };
5344 * await verifyBeforeUpdateEmail(user, 'newemail@example.com', actionCodeSettings);
5345 * // Obtain code from the user.
5346 * await applyActionCode(auth, code);
5347 * ```
5348 *
5349 * @param user - The user.
5350 * @param newEmail - The new email address to be verified before update.
5351 * @param actionCodeSettings - The {@link ActionCodeSettings}.
5352 *
5353 * @public
5354 */
5355async function verifyBeforeUpdateEmail(user, newEmail, actionCodeSettings) {
5356 const userInternal = getModularInstance(user);
5357 const idToken = await user.getIdToken();
5358 const request = {
5359 requestType: "VERIFY_AND_CHANGE_EMAIL" /* VERIFY_AND_CHANGE_EMAIL */,
5360 idToken,
5361 newEmail
5362 };
5363 if (actionCodeSettings) {
5364 _setActionCodeSettingsOnRequest(userInternal.auth, request, actionCodeSettings);
5365 }
5366 const { email } = await verifyAndChangeEmail(userInternal.auth, request);
5367 if (email !== user.email) {
5368 // If the local copy of the email on user is outdated, reload the
5369 // user.
5370 await user.reload();
5371 }
5372}
5373
5374/**
5375 * @license
5376 * Copyright 2020 Google LLC
5377 *
5378 * Licensed under the Apache License, Version 2.0 (the "License");
5379 * you may not use this file except in compliance with the License.
5380 * You may obtain a copy of the License at
5381 *
5382 * http://www.apache.org/licenses/LICENSE-2.0
5383 *
5384 * Unless required by applicable law or agreed to in writing, software
5385 * distributed under the License is distributed on an "AS IS" BASIS,
5386 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5387 * See the License for the specific language governing permissions and
5388 * limitations under the License.
5389 */
5390async function updateProfile$1(auth, request) {
5391 return _performApiRequest(auth, "POST" /* POST */, "/v1/accounts:update" /* SET_ACCOUNT_INFO */, request);
5392}
5393
5394/**
5395 * @license
5396 * Copyright 2020 Google LLC
5397 *
5398 * Licensed under the Apache License, Version 2.0 (the "License");
5399 * you may not use this file except in compliance with the License.
5400 * You may obtain a copy of the License at
5401 *
5402 * http://www.apache.org/licenses/LICENSE-2.0
5403 *
5404 * Unless required by applicable law or agreed to in writing, software
5405 * distributed under the License is distributed on an "AS IS" BASIS,
5406 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5407 * See the License for the specific language governing permissions and
5408 * limitations under the License.
5409 */
5410/**
5411 * Updates a user's profile data.
5412 *
5413 * @param user - The user.
5414 * @param profile - The profile's `displayName` and `photoURL` to update.
5415 *
5416 * @public
5417 */
5418async function updateProfile(user, { displayName, photoURL: photoUrl }) {
5419 if (displayName === undefined && photoUrl === undefined) {
5420 return;
5421 }
5422 const userInternal = getModularInstance(user);
5423 const idToken = await userInternal.getIdToken();
5424 const profileRequest = {
5425 idToken,
5426 displayName,
5427 photoUrl,
5428 returnSecureToken: true
5429 };
5430 const response = await _logoutIfInvalidated(userInternal, updateProfile$1(userInternal.auth, profileRequest));
5431 userInternal.displayName = response.displayName || null;
5432 userInternal.photoURL = response.photoUrl || null;
5433 // Update the password provider as well
5434 const passwordProvider = userInternal.providerData.find(({ providerId }) => providerId === "password" /* PASSWORD */);
5435 if (passwordProvider) {
5436 passwordProvider.displayName = userInternal.displayName;
5437 passwordProvider.photoURL = userInternal.photoURL;
5438 }
5439 await userInternal._updateTokensIfNecessary(response);
5440}
5441/**
5442 * Updates the user's email address.
5443 *
5444 * @remarks
5445 * An email will be sent to the original email address (if it was set) that allows to revoke the
5446 * email address change, in order to protect them from account hijacking.
5447 *
5448 * Important: this is a security sensitive operation that requires the user to have recently signed
5449 * in. If this requirement isn't met, ask the user to authenticate again and then call
5450 * {@link reauthenticateWithCredential}.
5451 *
5452 * @param user - The user.
5453 * @param newEmail - The new email address.
5454 *
5455 * @public
5456 */
5457function updateEmail(user, newEmail) {
5458 return updateEmailOrPassword(getModularInstance(user), newEmail, null);
5459}
5460/**
5461 * Updates the user's password.
5462 *
5463 * @remarks
5464 * Important: this is a security sensitive operation that requires the user to have recently signed
5465 * in. If this requirement isn't met, ask the user to authenticate again and then call
5466 * {@link reauthenticateWithCredential}.
5467 *
5468 * @param user - The user.
5469 * @param newPassword - The new password.
5470 *
5471 * @public
5472 */
5473function updatePassword(user, newPassword) {
5474 return updateEmailOrPassword(getModularInstance(user), null, newPassword);
5475}
5476async function updateEmailOrPassword(user, email, password) {
5477 const { auth } = user;
5478 const idToken = await user.getIdToken();
5479 const request = {
5480 idToken,
5481 returnSecureToken: true
5482 };
5483 if (email) {
5484 request.email = email;
5485 }
5486 if (password) {
5487 request.password = password;
5488 }
5489 const response = await _logoutIfInvalidated(user, updateEmailPassword(auth, request));
5490 await user._updateTokensIfNecessary(response, /* reload */ true);
5491}
5492
5493/**
5494 * @license
5495 * Copyright 2019 Google LLC
5496 *
5497 * Licensed under the Apache License, Version 2.0 (the "License");
5498 * you may not use this file except in compliance with the License.
5499 * You may obtain a copy of the License at
5500 *
5501 * http://www.apache.org/licenses/LICENSE-2.0
5502 *
5503 * Unless required by applicable law or agreed to in writing, software
5504 * distributed under the License is distributed on an "AS IS" BASIS,
5505 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5506 * See the License for the specific language governing permissions and
5507 * limitations under the License.
5508 */
5509/**
5510 * Parse the `AdditionalUserInfo` from the ID token response.
5511 *
5512 */
5513function _fromIdTokenResponse(idTokenResponse) {
5514 var _a, _b;
5515 if (!idTokenResponse) {
5516 return null;
5517 }
5518 const { providerId } = idTokenResponse;
5519 const profile = idTokenResponse.rawUserInfo
5520 ? JSON.parse(idTokenResponse.rawUserInfo)
5521 : {};
5522 const isNewUser = idTokenResponse.isNewUser ||
5523 idTokenResponse.kind === "identitytoolkit#SignupNewUserResponse" /* SignupNewUser */;
5524 if (!providerId && (idTokenResponse === null || idTokenResponse === void 0 ? void 0 : idTokenResponse.idToken)) {
5525 const signInProvider = (_b = (_a = _parseToken(idTokenResponse.idToken)) === null || _a === void 0 ? void 0 : _a.firebase) === null || _b === void 0 ? void 0 : _b['sign_in_provider'];
5526 if (signInProvider) {
5527 const filteredProviderId = signInProvider !== "anonymous" /* ANONYMOUS */ &&
5528 signInProvider !== "custom" /* CUSTOM */
5529 ? signInProvider
5530 : null;
5531 // Uses generic class in accordance with the legacy SDK.
5532 return new GenericAdditionalUserInfo(isNewUser, filteredProviderId);
5533 }
5534 }
5535 if (!providerId) {
5536 return null;
5537 }
5538 switch (providerId) {
5539 case "facebook.com" /* FACEBOOK */:
5540 return new FacebookAdditionalUserInfo(isNewUser, profile);
5541 case "github.com" /* GITHUB */:
5542 return new GithubAdditionalUserInfo(isNewUser, profile);
5543 case "google.com" /* GOOGLE */:
5544 return new GoogleAdditionalUserInfo(isNewUser, profile);
5545 case "twitter.com" /* TWITTER */:
5546 return new TwitterAdditionalUserInfo(isNewUser, profile, idTokenResponse.screenName || null);
5547 case "custom" /* CUSTOM */:
5548 case "anonymous" /* ANONYMOUS */:
5549 return new GenericAdditionalUserInfo(isNewUser, null);
5550 default:
5551 return new GenericAdditionalUserInfo(isNewUser, providerId, profile);
5552 }
5553}
5554class GenericAdditionalUserInfo {
5555 constructor(isNewUser, providerId, profile = {}) {
5556 this.isNewUser = isNewUser;
5557 this.providerId = providerId;
5558 this.profile = profile;
5559 }
5560}
5561class FederatedAdditionalUserInfoWithUsername extends GenericAdditionalUserInfo {
5562 constructor(isNewUser, providerId, profile, username) {
5563 super(isNewUser, providerId, profile);
5564 this.username = username;
5565 }
5566}
5567class FacebookAdditionalUserInfo extends GenericAdditionalUserInfo {
5568 constructor(isNewUser, profile) {
5569 super(isNewUser, "facebook.com" /* FACEBOOK */, profile);
5570 }
5571}
5572class GithubAdditionalUserInfo extends FederatedAdditionalUserInfoWithUsername {
5573 constructor(isNewUser, profile) {
5574 super(isNewUser, "github.com" /* GITHUB */, profile, typeof (profile === null || profile === void 0 ? void 0 : profile.login) === 'string' ? profile === null || profile === void 0 ? void 0 : profile.login : null);
5575 }
5576}
5577class GoogleAdditionalUserInfo extends GenericAdditionalUserInfo {
5578 constructor(isNewUser, profile) {
5579 super(isNewUser, "google.com" /* GOOGLE */, profile);
5580 }
5581}
5582class TwitterAdditionalUserInfo extends FederatedAdditionalUserInfoWithUsername {
5583 constructor(isNewUser, profile, screenName) {
5584 super(isNewUser, "twitter.com" /* TWITTER */, profile, screenName);
5585 }
5586}
5587/**
5588 * Extracts provider specific {@link AdditionalUserInfo} for the given credential.
5589 *
5590 * @param userCredential - The user credential.
5591 *
5592 * @public
5593 */
5594function getAdditionalUserInfo(userCredential) {
5595 const { user, _tokenResponse } = userCredential;
5596 if (user.isAnonymous && !_tokenResponse) {
5597 // Handle the special case where signInAnonymously() gets called twice.
5598 // No network call is made so there's nothing to actually fill this in
5599 return {
5600 providerId: null,
5601 isNewUser: false,
5602 profile: null
5603 };
5604 }
5605 return _fromIdTokenResponse(_tokenResponse);
5606}
5607
5608/**
5609 * @license
5610 * Copyright 2020 Google LLC
5611 *
5612 * Licensed under the Apache License, Version 2.0 (the "License");
5613 * you may not use this file except in compliance with the License.
5614 * You may obtain a copy of the License at
5615 *
5616 * http://www.apache.org/licenses/LICENSE-2.0
5617 *
5618 * Unless required by applicable law or agreed to in writing, software
5619 * distributed under the License is distributed on an "AS IS" BASIS,
5620 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5621 * See the License for the specific language governing permissions and
5622 * limitations under the License.
5623 */
5624// Non-optional auth methods.
5625/**
5626 * Changes the type of persistence on the {@link Auth} instance for the currently saved
5627 * `Auth` session and applies this type of persistence for future sign-in requests, including
5628 * sign-in with redirect requests.
5629 *
5630 * @remarks
5631 * This makes it easy for a user signing in to specify whether their session should be
5632 * remembered or not. It also makes it easier to never persist the `Auth` state for applications
5633 * that are shared by other users or have sensitive data.
5634 *
5635 * @example
5636 * ```javascript
5637 * setPersistence(auth, browserSessionPersistence);
5638 * ```
5639 *
5640 * @param auth - The {@link Auth} instance.
5641 * @param persistence - The {@link Persistence} to use.
5642 * @returns A `Promise` that resolves once the persistence change has completed
5643 *
5644 * @public
5645 */
5646function setPersistence(auth, persistence) {
5647 return getModularInstance(auth).setPersistence(persistence);
5648}
5649/**
5650 * Adds an observer for changes to the signed-in user's ID token.
5651 *
5652 * @remarks
5653 * This includes sign-in, sign-out, and token refresh events.
5654 *
5655 * @param auth - The {@link Auth} instance.
5656 * @param nextOrObserver - callback triggered on change.
5657 * @param error - Deprecated. This callback is never triggered. Errors
5658 * on signing in/out can be caught in promises returned from
5659 * sign-in/sign-out functions.
5660 * @param completed - Deprecated. This callback is never triggered.
5661 *
5662 * @public
5663 */
5664function onIdTokenChanged(auth, nextOrObserver, error, completed) {
5665 return getModularInstance(auth).onIdTokenChanged(nextOrObserver, error, completed);
5666}
5667/**
5668 * Adds a blocking callback that runs before an auth state change
5669 * sets a new user.
5670 *
5671 * @param auth - The {@link Auth} instance.
5672 * @param callback - callback triggered before new user value is set.
5673 * If this throws, it blocks the user from being set.
5674 * @param onAbort - callback triggered if a later `beforeAuthStateChanged()`
5675 * callback throws, allowing you to undo any side effects.
5676 */
5677function beforeAuthStateChanged(auth, callback, onAbort) {
5678 return getModularInstance(auth).beforeAuthStateChanged(callback, onAbort);
5679}
5680/**
5681 * Adds an observer for changes to the user's sign-in state.
5682 *
5683 * @remarks
5684 * To keep the old behavior, see {@link onIdTokenChanged}.
5685 *
5686 * @param auth - The {@link Auth} instance.
5687 * @param nextOrObserver - callback triggered on change.
5688 * @param error - Deprecated. This callback is never triggered. Errors
5689 * on signing in/out can be caught in promises returned from
5690 * sign-in/sign-out functions.
5691 * @param completed - Deprecated. This callback is never triggered.
5692 *
5693 * @public
5694 */
5695function onAuthStateChanged(auth, nextOrObserver, error, completed) {
5696 return getModularInstance(auth).onAuthStateChanged(nextOrObserver, error, completed);
5697}
5698/**
5699 * Sets the current language to the default device/browser preference.
5700 *
5701 * @param auth - The {@link Auth} instance.
5702 *
5703 * @public
5704 */
5705function useDeviceLanguage(auth) {
5706 getModularInstance(auth).useDeviceLanguage();
5707}
5708/**
5709 * Asynchronously sets the provided user as {@link Auth.currentUser} on the
5710 * {@link Auth} instance.
5711 *
5712 * @remarks
5713 * A new instance copy of the user provided will be made and set as currentUser.
5714 *
5715 * This will trigger {@link onAuthStateChanged} and {@link onIdTokenChanged} listeners
5716 * like other sign in methods.
5717 *
5718 * The operation fails with an error if the user to be updated belongs to a different Firebase
5719 * project.
5720 *
5721 * @param auth - The {@link Auth} instance.
5722 * @param user - The new {@link User}.
5723 *
5724 * @public
5725 */
5726function updateCurrentUser(auth, user) {
5727 return getModularInstance(auth).updateCurrentUser(user);
5728}
5729/**
5730 * Signs out the current user.
5731 *
5732 * @param auth - The {@link Auth} instance.
5733 *
5734 * @public
5735 */
5736function signOut(auth) {
5737 return getModularInstance(auth).signOut();
5738}
5739/**
5740 * Deletes and signs out the user.
5741 *
5742 * @remarks
5743 * Important: this is a security-sensitive operation that requires the user to have recently
5744 * signed in. If this requirement isn't met, ask the user to authenticate again and then call
5745 * {@link reauthenticateWithCredential}.
5746 *
5747 * @param user - The user.
5748 *
5749 * @public
5750 */
5751async function deleteUser(user) {
5752 return getModularInstance(user).delete();
5753}
5754
5755class MultiFactorSessionImpl {
5756 constructor(type, credential) {
5757 this.type = type;
5758 this.credential = credential;
5759 }
5760 static _fromIdtoken(idToken) {
5761 return new MultiFactorSessionImpl("enroll" /* ENROLL */, idToken);
5762 }
5763 static _fromMfaPendingCredential(mfaPendingCredential) {
5764 return new MultiFactorSessionImpl("signin" /* SIGN_IN */, mfaPendingCredential);
5765 }
5766 toJSON() {
5767 const key = this.type === "enroll" /* ENROLL */
5768 ? 'idToken'
5769 : 'pendingCredential';
5770 return {
5771 multiFactorSession: {
5772 [key]: this.credential
5773 }
5774 };
5775 }
5776 static fromJSON(obj) {
5777 var _a, _b;
5778 if (obj === null || obj === void 0 ? void 0 : obj.multiFactorSession) {
5779 if ((_a = obj.multiFactorSession) === null || _a === void 0 ? void 0 : _a.pendingCredential) {
5780 return MultiFactorSessionImpl._fromMfaPendingCredential(obj.multiFactorSession.pendingCredential);
5781 }
5782 else if ((_b = obj.multiFactorSession) === null || _b === void 0 ? void 0 : _b.idToken) {
5783 return MultiFactorSessionImpl._fromIdtoken(obj.multiFactorSession.idToken);
5784 }
5785 }
5786 return null;
5787 }
5788}
5789
5790/**
5791 * @license
5792 * Copyright 2020 Google LLC
5793 *
5794 * Licensed under the Apache License, Version 2.0 (the "License");
5795 * you may not use this file except in compliance with the License.
5796 * You may obtain a copy of the License at
5797 *
5798 * http://www.apache.org/licenses/LICENSE-2.0
5799 *
5800 * Unless required by applicable law or agreed to in writing, software
5801 * distributed under the License is distributed on an "AS IS" BASIS,
5802 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5803 * See the License for the specific language governing permissions and
5804 * limitations under the License.
5805 */
5806class MultiFactorResolverImpl {
5807 constructor(session, hints, signInResolver) {
5808 this.session = session;
5809 this.hints = hints;
5810 this.signInResolver = signInResolver;
5811 }
5812 /** @internal */
5813 static _fromError(authExtern, error) {
5814 const auth = _castAuth(authExtern);
5815 const serverResponse = error.customData._serverResponse;
5816 const hints = (serverResponse.mfaInfo || []).map(enrollment => MultiFactorInfoImpl._fromServerResponse(auth, enrollment));
5817 _assert(serverResponse.mfaPendingCredential, auth, "internal-error" /* INTERNAL_ERROR */);
5818 const session = MultiFactorSessionImpl._fromMfaPendingCredential(serverResponse.mfaPendingCredential);
5819 return new MultiFactorResolverImpl(session, hints, async (assertion) => {
5820 const mfaResponse = await assertion._process(auth, session);
5821 // Clear out the unneeded fields from the old login response
5822 delete serverResponse.mfaInfo;
5823 delete serverResponse.mfaPendingCredential;
5824 // Use in the new token & refresh token in the old response
5825 const idTokenResponse = Object.assign(Object.assign({}, serverResponse), { idToken: mfaResponse.idToken, refreshToken: mfaResponse.refreshToken });
5826 // TODO: we should collapse this switch statement into UserCredentialImpl._forOperation and have it support the SIGN_IN case
5827 switch (error.operationType) {
5828 case "signIn" /* SIGN_IN */:
5829 const userCredential = await UserCredentialImpl._fromIdTokenResponse(auth, error.operationType, idTokenResponse);
5830 await auth._updateCurrentUser(userCredential.user);
5831 return userCredential;
5832 case "reauthenticate" /* REAUTHENTICATE */:
5833 _assert(error.user, auth, "internal-error" /* INTERNAL_ERROR */);
5834 return UserCredentialImpl._forOperation(error.user, error.operationType, idTokenResponse);
5835 default:
5836 _fail(auth, "internal-error" /* INTERNAL_ERROR */);
5837 }
5838 });
5839 }
5840 async resolveSignIn(assertionExtern) {
5841 const assertion = assertionExtern;
5842 return this.signInResolver(assertion);
5843 }
5844}
5845/**
5846 * Provides a {@link MultiFactorResolver} suitable for completion of a
5847 * multi-factor flow.
5848 *
5849 * @param auth - The {@link Auth} instance.
5850 * @param error - The {@link MultiFactorError} raised during a sign-in, or
5851 * reauthentication operation.
5852 *
5853 * @public
5854 */
5855function getMultiFactorResolver(auth, error) {
5856 var _a;
5857 const authModular = getModularInstance(auth);
5858 const errorInternal = error;
5859 _assert(error.customData.operationType, authModular, "argument-error" /* ARGUMENT_ERROR */);
5860 _assert((_a = errorInternal.customData._serverResponse) === null || _a === void 0 ? void 0 : _a.mfaPendingCredential, authModular, "argument-error" /* ARGUMENT_ERROR */);
5861 return MultiFactorResolverImpl._fromError(authModular, errorInternal);
5862}
5863
5864/**
5865 * @license
5866 * Copyright 2020 Google LLC
5867 *
5868 * Licensed under the Apache License, Version 2.0 (the "License");
5869 * you may not use this file except in compliance with the License.
5870 * You may obtain a copy of the License at
5871 *
5872 * http://www.apache.org/licenses/LICENSE-2.0
5873 *
5874 * Unless required by applicable law or agreed to in writing, software
5875 * distributed under the License is distributed on an "AS IS" BASIS,
5876 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5877 * See the License for the specific language governing permissions and
5878 * limitations under the License.
5879 */
5880function withdrawMfa(auth, request) {
5881 return _performApiRequest(auth, "POST" /* POST */, "/v2/accounts/mfaEnrollment:withdraw" /* WITHDRAW_MFA */, _addTidIfNecessary(auth, request));
5882}
5883
5884class MultiFactorUserImpl {
5885 constructor(user) {
5886 this.user = user;
5887 this.enrolledFactors = [];
5888 user._onReload(userInfo => {
5889 if (userInfo.mfaInfo) {
5890 this.enrolledFactors = userInfo.mfaInfo.map(enrollment => MultiFactorInfoImpl._fromServerResponse(user.auth, enrollment));
5891 }
5892 });
5893 }
5894 static _fromUser(user) {
5895 return new MultiFactorUserImpl(user);
5896 }
5897 async getSession() {
5898 return MultiFactorSessionImpl._fromIdtoken(await this.user.getIdToken());
5899 }
5900 async enroll(assertionExtern, displayName) {
5901 const assertion = assertionExtern;
5902 const session = (await this.getSession());
5903 const finalizeMfaResponse = await _logoutIfInvalidated(this.user, assertion._process(this.user.auth, session, displayName));
5904 // New tokens will be issued after enrollment of the new second factors.
5905 // They need to be updated on the user.
5906 await this.user._updateTokensIfNecessary(finalizeMfaResponse);
5907 // The user needs to be reloaded to get the new multi-factor information
5908 // from server. USER_RELOADED event will be triggered and `enrolledFactors`
5909 // will be updated.
5910 return this.user.reload();
5911 }
5912 async unenroll(infoOrUid) {
5913 var _a;
5914 const mfaEnrollmentId = typeof infoOrUid === 'string' ? infoOrUid : infoOrUid.uid;
5915 const idToken = await this.user.getIdToken();
5916 const idTokenResponse = await _logoutIfInvalidated(this.user, withdrawMfa(this.user.auth, {
5917 idToken,
5918 mfaEnrollmentId
5919 }));
5920 // Remove the second factor from the user's list.
5921 this.enrolledFactors = this.enrolledFactors.filter(({ uid }) => uid !== mfaEnrollmentId);
5922 // Depending on whether the backend decided to revoke the user's session,
5923 // the tokenResponse may be empty. If the tokens were not updated (and they
5924 // are now invalid), reloading the user will discover this and invalidate
5925 // the user's state accordingly.
5926 await this.user._updateTokensIfNecessary(idTokenResponse);
5927 try {
5928 await this.user.reload();
5929 }
5930 catch (e) {
5931 if (((_a = e) === null || _a === void 0 ? void 0 : _a.code) !== `auth/${"user-token-expired" /* TOKEN_EXPIRED */}`) {
5932 throw e;
5933 }
5934 }
5935 }
5936}
5937const multiFactorUserCache = new WeakMap();
5938/**
5939 * The {@link MultiFactorUser} corresponding to the user.
5940 *
5941 * @remarks
5942 * This is used to access all multi-factor properties and operations related to the user.
5943 *
5944 * @param user - The user.
5945 *
5946 * @public
5947 */
5948function multiFactor(user) {
5949 const userModular = getModularInstance(user);
5950 if (!multiFactorUserCache.has(userModular)) {
5951 multiFactorUserCache.set(userModular, MultiFactorUserImpl._fromUser(userModular));
5952 }
5953 return multiFactorUserCache.get(userModular);
5954}
5955
5956var name = "@firebase/auth";
5957var version = "0.20.5";
5958
5959/**
5960 * @license
5961 * Copyright 2020 Google LLC
5962 *
5963 * Licensed under the Apache License, Version 2.0 (the "License");
5964 * you may not use this file except in compliance with the License.
5965 * You may obtain a copy of the License at
5966 *
5967 * http://www.apache.org/licenses/LICENSE-2.0
5968 *
5969 * Unless required by applicable law or agreed to in writing, software
5970 * distributed under the License is distributed on an "AS IS" BASIS,
5971 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5972 * See the License for the specific language governing permissions and
5973 * limitations under the License.
5974 */
5975class AuthInterop {
5976 constructor(auth) {
5977 this.auth = auth;
5978 this.internalListeners = new Map();
5979 }
5980 getUid() {
5981 var _a;
5982 this.assertAuthConfigured();
5983 return ((_a = this.auth.currentUser) === null || _a === void 0 ? void 0 : _a.uid) || null;
5984 }
5985 async getToken(forceRefresh) {
5986 this.assertAuthConfigured();
5987 await this.auth._initializationPromise;
5988 if (!this.auth.currentUser) {
5989 return null;
5990 }
5991 const accessToken = await this.auth.currentUser.getIdToken(forceRefresh);
5992 return { accessToken };
5993 }
5994 addAuthTokenListener(listener) {
5995 this.assertAuthConfigured();
5996 if (this.internalListeners.has(listener)) {
5997 return;
5998 }
5999 const unsubscribe = this.auth.onIdTokenChanged(user => {
6000 var _a;
6001 listener(((_a = user) === null || _a === void 0 ? void 0 : _a.stsTokenManager.accessToken) || null);
6002 });
6003 this.internalListeners.set(listener, unsubscribe);
6004 this.updateProactiveRefresh();
6005 }
6006 removeAuthTokenListener(listener) {
6007 this.assertAuthConfigured();
6008 const unsubscribe = this.internalListeners.get(listener);
6009 if (!unsubscribe) {
6010 return;
6011 }
6012 this.internalListeners.delete(listener);
6013 unsubscribe();
6014 this.updateProactiveRefresh();
6015 }
6016 assertAuthConfigured() {
6017 _assert(this.auth._initializationPromise, "dependent-sdk-initialized-before-auth" /* DEPENDENT_SDK_INIT_BEFORE_AUTH */);
6018 }
6019 updateProactiveRefresh() {
6020 if (this.internalListeners.size > 0) {
6021 this.auth._startProactiveRefresh();
6022 }
6023 else {
6024 this.auth._stopProactiveRefresh();
6025 }
6026 }
6027}
6028
6029/**
6030 * @license
6031 * Copyright 2020 Google LLC
6032 *
6033 * Licensed under the Apache License, Version 2.0 (the "License");
6034 * you may not use this file except in compliance with the License.
6035 * You may obtain a copy of the License at
6036 *
6037 * http://www.apache.org/licenses/LICENSE-2.0
6038 *
6039 * Unless required by applicable law or agreed to in writing, software
6040 * distributed under the License is distributed on an "AS IS" BASIS,
6041 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6042 * See the License for the specific language governing permissions and
6043 * limitations under the License.
6044 */
6045function getVersionForPlatform(clientPlatform) {
6046 switch (clientPlatform) {
6047 case "Node" /* NODE */:
6048 return 'node';
6049 case "ReactNative" /* REACT_NATIVE */:
6050 return 'rn';
6051 case "Worker" /* WORKER */:
6052 return 'webworker';
6053 case "Cordova" /* CORDOVA */:
6054 return 'cordova';
6055 default:
6056 return undefined;
6057 }
6058}
6059/** @internal */
6060function registerAuth(clientPlatform) {
6061 _registerComponent(new Component("auth" /* AUTH */, (container, { options: deps }) => {
6062 const app = container.getProvider('app').getImmediate();
6063 const heartbeatServiceProvider = container.getProvider('heartbeat');
6064 const { apiKey, authDomain } = app.options;
6065 return ((app, heartbeatServiceProvider) => {
6066 _assert(apiKey && !apiKey.includes(':'), "invalid-api-key" /* INVALID_API_KEY */, { appName: app.name });
6067 // Auth domain is optional if IdP sign in isn't being used
6068 _assert(!(authDomain === null || authDomain === void 0 ? void 0 : authDomain.includes(':')), "argument-error" /* ARGUMENT_ERROR */, {
6069 appName: app.name
6070 });
6071 const config = {
6072 apiKey,
6073 authDomain,
6074 clientPlatform,
6075 apiHost: "identitytoolkit.googleapis.com" /* API_HOST */,
6076 tokenApiHost: "securetoken.googleapis.com" /* TOKEN_API_HOST */,
6077 apiScheme: "https" /* API_SCHEME */,
6078 sdkClientVersion: _getClientVersion(clientPlatform)
6079 };
6080 const authInstance = new AuthImpl(app, heartbeatServiceProvider, config);
6081 _initializeAuthInstance(authInstance, deps);
6082 return authInstance;
6083 })(app, heartbeatServiceProvider);
6084 }, "PUBLIC" /* PUBLIC */)
6085 /**
6086 * Auth can only be initialized by explicitly calling getAuth() or initializeAuth()
6087 * For why we do this, See go/firebase-next-auth-init
6088 */
6089 .setInstantiationMode("EXPLICIT" /* EXPLICIT */)
6090 /**
6091 * Because all firebase products that depend on auth depend on auth-internal directly,
6092 * we need to initialize auth-internal after auth is initialized to make it available to other firebase products.
6093 */
6094 .setInstanceCreatedCallback((container, _instanceIdentifier, _instance) => {
6095 const authInternalProvider = container.getProvider("auth-internal" /* AUTH_INTERNAL */);
6096 authInternalProvider.initialize();
6097 }));
6098 _registerComponent(new Component("auth-internal" /* AUTH_INTERNAL */, container => {
6099 const auth = _castAuth(container.getProvider("auth" /* AUTH */).getImmediate());
6100 return (auth => new AuthInterop(auth))(auth);
6101 }, "PRIVATE" /* PRIVATE */).setInstantiationMode("EXPLICIT" /* EXPLICIT */));
6102 registerVersion(name, version, getVersionForPlatform(clientPlatform));
6103 // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
6104 registerVersion(name, version, 'esm2017');
6105}
6106
6107/**
6108 * @license
6109 * Copyright 2021 Google LLC
6110 *
6111 * Licensed under the Apache License, Version 2.0 (the "License");
6112 * you may not use this file except in compliance with the License.
6113 * You may obtain a copy of the License at
6114 *
6115 * http://www.apache.org/licenses/LICENSE-2.0
6116 *
6117 * Unless required by applicable law or agreed to in writing, software
6118 * distributed under the License is distributed on an "AS IS" BASIS,
6119 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6120 * See the License for the specific language governing permissions and
6121 * limitations under the License.
6122 */
6123// Initialize the fetch polyfill, the types are slightly off so just cast and hope for the best
6124FetchProvider.initialize(fetchImpl.default, fetchImpl.Headers, fetchImpl.Response);
6125// First, we set up the various platform-specific features for Node (register
6126// the version and declare the Node getAuth function)
6127function getAuth(app = getApp()) {
6128 const provider = _getProvider(app, 'auth');
6129 if (provider.isInitialized()) {
6130 return provider.getImmediate();
6131 }
6132 return initializeAuth(app);
6133}
6134registerAuth("Node" /* NODE */);
6135// The rest of this file contains no-ops and errors for browser-specific
6136// methods. We keep the browser and Node entry points the same, but features
6137// that only work in browsers are set to either do nothing (setPersistence) or
6138// to reject with an auth/operation-not-supported-in-this-environment error.
6139// The below exports are pulled into the main entry point by a rollup alias
6140// plugin (overwriting the default browser imports).
6141/** auth/operation-not-supported-in-this-environment */
6142const NOT_AVAILABLE_ERROR = _createError("operation-not-supported-in-this-environment" /* OPERATION_NOT_SUPPORTED */);
6143/** Reject with auth/operation-not-supported-in-this-environment */
6144async function fail() {
6145 throw NOT_AVAILABLE_ERROR;
6146}
6147/**
6148 * A class which will throw with
6149 * auth/operation-not-supported-in-this-environment if instantiated
6150 */
6151class FailClass {
6152 constructor() {
6153 throw NOT_AVAILABLE_ERROR;
6154 }
6155}
6156const browserLocalPersistence = inMemoryPersistence;
6157const browserSessionPersistence = inMemoryPersistence;
6158const indexedDBLocalPersistence = inMemoryPersistence;
6159const browserPopupRedirectResolver = NOT_AVAILABLE_ERROR;
6160const PhoneAuthProvider = FailClass;
6161const signInWithPhoneNumber = fail;
6162const linkWithPhoneNumber = fail;
6163const reauthenticateWithPhoneNumber = fail;
6164const updatePhoneNumber = fail;
6165const signInWithPopup = fail;
6166const linkWithPopup = fail;
6167const reauthenticateWithPopup = fail;
6168const signInWithRedirect = fail;
6169const linkWithRedirect = fail;
6170const reauthenticateWithRedirect = fail;
6171const getRedirectResult = fail;
6172const RecaptchaVerifier = FailClass;
6173class PhoneMultiFactorGenerator {
6174 static assertion() {
6175 throw NOT_AVAILABLE_ERROR;
6176 }
6177}
6178// Set persistence should no-op instead of fail. Changing the prototype will
6179// make sure both setPersistence(auth, persistence) and
6180// auth.setPersistence(persistence) are covered.
6181AuthImpl.prototype.setPersistence = async () => { };
6182
6183export { signInWithCustomToken as $, ActionCodeOperation as A, debugErrorMap as B, prodErrorMap as C, AUTH_ERROR_CODES_MAP_DO_NOT_USE_INTERNALLY as D, initializeAuth as E, FactorId as F, connectAuthEmulator as G, AuthCredential as H, EmailAuthCredential as I, OAuthCredential as J, PhoneAuthCredential as K, inMemoryPersistence as L, EmailAuthProvider as M, FacebookAuthProvider as N, OperationType as O, PhoneAuthProvider as P, GoogleAuthProvider as Q, RecaptchaVerifier as R, SignInMethod as S, GithubAuthProvider as T, OAuthProvider as U, SAMLAuthProvider as V, TwitterAuthProvider as W, signInAnonymously as X, signInWithCredential as Y, linkWithCredential as Z, reauthenticateWithCredential as _, browserSessionPersistence as a, sendPasswordResetEmail as a0, confirmPasswordReset as a1, applyActionCode as a2, checkActionCode as a3, verifyPasswordResetCode as a4, createUserWithEmailAndPassword as a5, signInWithEmailAndPassword as a6, sendSignInLinkToEmail as a7, isSignInWithEmailLink as a8, signInWithEmailLink as a9, BaseOAuthProvider as aA, _emulatorUrl as aB, _performApiRequest as aC, _isIOS7Or8 as aD, _isIOS as aE, _isAndroid as aF, _createError as aG, _isSafari as aH, _isIframe as aI, _isMobileBrowser as aJ, _isIE10 as aK, UserImpl as aL, AuthImpl as aM, _getClientVersion as aN, FetchProvider as aO, SAMLAuthCredential as aP, fetchSignInMethodsForEmail as aa, sendEmailVerification as ab, verifyBeforeUpdateEmail as ac, ActionCodeURL as ad, parseActionCodeURL as ae, updateProfile as af, updateEmail as ag, updatePassword as ah, getIdToken as ai, getIdTokenResult as aj, unlink as ak, getAdditionalUserInfo as al, reload as am, getMultiFactorResolver as an, multiFactor as ao, _getInstance as ap, _assert as aq, _signInWithCredential as ar, _reauthenticate as as, _link as at, signInWithIdp as au, _fail as av, debugAssert as aw, _persistenceKeyName as ax, _castAuth as ay, FederatedAuthProvider as az, browserLocalPersistence as b, signInWithPopup as c, linkWithPopup as d, reauthenticateWithPopup as e, signInWithRedirect as f, linkWithRedirect as g, reauthenticateWithRedirect as h, indexedDBLocalPersistence as i, getRedirectResult as j, browserPopupRedirectResolver as k, linkWithPhoneNumber as l, PhoneMultiFactorGenerator as m, getAuth as n, ProviderId as o, setPersistence as p, onIdTokenChanged as q, reauthenticateWithPhoneNumber as r, signInWithPhoneNumber as s, beforeAuthStateChanged as t, updatePhoneNumber as u, onAuthStateChanged as v, useDeviceLanguage as w, updateCurrentUser as x, signOut as y, deleteUser as z };
6184//# sourceMappingURL=index-f3c5e390.js.map