1 | import { af as _performApiRequest, ag as _addTidIfNecessary, ah as _createError, ai as _assert, aj as Delay, ak as _window, al as _isHttpOrHttps, am as _isWorker, an as _castAuth, J as signInWithCredential, ao as sendPhoneVerificationCode, ap as startEnrollPhoneMfa, K as linkWithCredential, aq as _assertLinkedStatus, L as reauthenticateWithCredential, ar as _link, x as PhoneAuthCredential, as as debugAssert, at as _generateEventId, au as AbstractPopupRedirectOperation, av as _assertInstanceOf, aw as _withDefaultResolver, ax as FederatedAuthProvider, ay as _fail, az as _getProjectConfig, aA as _getCurrentUrl, aB as _emulatorUrl, aC as _isChromeIOS, aD as _isFirefox, aE as _isIOSStandalone, aF as _isMobileBrowser, aG as _isSafari, aH as _isIOS, f as browserSessionPersistence, aI as _getRedirectResult, aJ as _overrideRedirectResult, aK as _getRedirectUrl, aL as _setWindowLocation, aM as AuthEventManager, aN as debugFail, aO as finalizeEnrollPhoneMfa, r as registerAuth, i as initializeAuth, c as indexedDBLocalPersistence, e as browserLocalPersistence } from './popup_redirect-212c98e6.js';
|
2 | export { A as ActionCodeOperation, a3 as ActionCodeURL, v as AuthCredential, q as AuthErrorCodes, aS as AuthImpl, E as EmailAuthCredential, z as EmailAuthProvider, B as FacebookAuthProvider, F as FactorId, aU as FetchProvider, C as GithubAuthProvider, G as GoogleAuthProvider, w as OAuthCredential, D as OAuthProvider, O as OperationType, x as PhoneAuthCredential, P as ProviderId, aV as SAMLAuthCredential, H as SAMLAuthProvider, S as SignInMethod, T as TwitterAuthProvider, aQ as UserImpl, ai as _assert, an as _castAuth, ay as _fail, at as _generateEventId, aT as _getClientVersion, aR as _getInstance, aI as _getRedirectResult, aJ as _overrideRedirectResult, aP as _persistenceKeyName, R as applyActionCode, h as beforeAuthStateChanged, e as browserLocalPersistence, f as browserSessionPersistence, U as checkActionCode, Q as confirmPasswordReset, t as connectAuthEmulator, d as cordovaPopupRedirectResolver, W as createUserWithEmailAndPassword, n as debugErrorMap, m as deleteUser, a0 as fetchSignInMethodsForEmail, ab as getAdditionalUserInfo, a8 as getIdToken, a9 as getIdTokenResult, ad as getMultiFactorResolver, g as getRedirectResult, y as inMemoryPersistence, c as indexedDBLocalPersistence, i as initializeAuth, Z as isSignInWithEmailLink, K as linkWithCredential, aX as linkWithRedirect, ae as multiFactor, j as onAuthStateChanged, o as onIdTokenChanged, a4 as parseActionCodeURL, p as prodErrorMap, L as reauthenticateWithCredential, aY as reauthenticateWithRedirect, ac as reload, a1 as sendEmailVerification, N as sendPasswordResetEmail, Y as sendSignInLinkToEmail, s as setPersistence, I as signInAnonymously, J as signInWithCredential, M as signInWithCustomToken, X as signInWithEmailAndPassword, $ as signInWithEmailLink, aW as signInWithRedirect, l as signOut, aa as unlink, k as updateCurrentUser, a6 as updateEmail, a7 as updatePassword, a5 as updateProfile, u as useDeviceLanguage, a2 as verifyBeforeUpdateEmail, V as verifyPasswordResetCode } from './popup_redirect-212c98e6.js';
|
3 | import { __awaiter, __generator, __assign, __extends, __spreadArray } from 'tslib';
|
4 | import { querystring, getModularInstance, getUA } from '@firebase/util';
|
5 | import { SDK_VERSION, getApp, _getProvider } from '@firebase/app';
|
6 | import '@firebase/component';
|
7 | import '@firebase/logger';
|
8 |
|
9 | /**
|
10 | * @license
|
11 | * Copyright 2020 Google LLC
|
12 | *
|
13 | * Licensed under the Apache License, Version 2.0 (the "License");
|
14 | * you may not use this file except in compliance with the License.
|
15 | * You may obtain a copy of the License at
|
16 | *
|
17 | * http://www.apache.org/licenses/LICENSE-2.0
|
18 | *
|
19 | * Unless required by applicable law or agreed to in writing, software
|
20 | * distributed under the License is distributed on an "AS IS" BASIS,
|
21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
22 | * See the License for the specific language governing permissions and
|
23 | * limitations under the License.
|
24 | */
|
25 | function startSignInPhoneMfa(auth, request) {
|
26 | return _performApiRequest(auth, "POST" /* POST */, "/v2/accounts/mfaSignIn:start" /* START_PHONE_MFA_SIGN_IN */, _addTidIfNecessary(auth, request));
|
27 | }
|
28 | function finalizeSignInPhoneMfa(auth, request) {
|
29 | return _performApiRequest(auth, "POST" /* POST */, "/v2/accounts/mfaSignIn:finalize" /* FINALIZE_PHONE_MFA_SIGN_IN */, _addTidIfNecessary(auth, request));
|
30 | }
|
31 |
|
32 | /**
|
33 | * @license
|
34 | * Copyright 2020 Google LLC
|
35 | *
|
36 | * Licensed under the Apache License, Version 2.0 (the "License");
|
37 | * you may not use this file except in compliance with the License.
|
38 | * You may obtain a copy of the License at
|
39 | *
|
40 | * http://www.apache.org/licenses/LICENSE-2.0
|
41 | *
|
42 | * Unless required by applicable law or agreed to in writing, software
|
43 | * distributed under the License is distributed on an "AS IS" BASIS,
|
44 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
45 | * See the License for the specific language governing permissions and
|
46 | * limitations under the License.
|
47 | */
|
48 | function getRecaptchaParams(auth) {
|
49 | return __awaiter(this, void 0, void 0, function () {
|
50 | return __generator(this, function (_a) {
|
51 | switch (_a.label) {
|
52 | case 0: return [4 /*yield*/, _performApiRequest(auth, "GET" /* GET */, "/v1/recaptchaParams" /* GET_RECAPTCHA_PARAM */)];
|
53 | case 1: return [2 /*return*/, ((_a.sent()).recaptchaSiteKey || '')];
|
54 | }
|
55 | });
|
56 | });
|
57 | }
|
58 |
|
59 | /**
|
60 | * @license
|
61 | * Copyright 2020 Google LLC
|
62 | *
|
63 | * Licensed under the Apache License, Version 2.0 (the "License");
|
64 | * you may not use this file except in compliance with the License.
|
65 | * You may obtain a copy of the License at
|
66 | *
|
67 | * http://www.apache.org/licenses/LICENSE-2.0
|
68 | *
|
69 | * Unless required by applicable law or agreed to in writing, software
|
70 | * distributed under the License is distributed on an "AS IS" BASIS,
|
71 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
72 | * See the License for the specific language governing permissions and
|
73 | * limitations under the License.
|
74 | */
|
75 | function getScriptParentElement() {
|
76 | var _a, _b;
|
77 | return (_b = (_a = document.getElementsByTagName('head')) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : document;
|
78 | }
|
79 | function _loadJS(url) {
|
80 | // TODO: consider adding timeout support & cancellation
|
81 | return new Promise(function (resolve, reject) {
|
82 | var el = document.createElement('script');
|
83 | el.setAttribute('src', url);
|
84 | el.onload = resolve;
|
85 | el.onerror = function (e) {
|
86 | var error = _createError("internal-error" /* INTERNAL_ERROR */);
|
87 | error.customData = e;
|
88 | reject(error);
|
89 | };
|
90 | el.type = 'text/javascript';
|
91 | el.charset = 'UTF-8';
|
92 | getScriptParentElement().appendChild(el);
|
93 | });
|
94 | }
|
95 | function _generateCallbackName(prefix) {
|
96 | return "__" + prefix + Math.floor(Math.random() * 1000000);
|
97 | }
|
98 |
|
99 | /**
|
100 | * @license
|
101 | * Copyright 2020 Google LLC
|
102 | *
|
103 | * Licensed under the Apache License, Version 2.0 (the "License");
|
104 | * you may not use this file except in compliance with the License.
|
105 | * You may obtain a copy of the License at
|
106 | *
|
107 | * http://www.apache.org/licenses/LICENSE-2.0
|
108 | *
|
109 | * Unless required by applicable law or agreed to in writing, software
|
110 | * distributed under the License is distributed on an "AS IS" BASIS,
|
111 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
112 | * See the License for the specific language governing permissions and
|
113 | * limitations under the License.
|
114 | */
|
115 | var _SOLVE_TIME_MS = 500;
|
116 | var _EXPIRATION_TIME_MS = 60000;
|
117 | var _WIDGET_ID_START = 1000000000000;
|
118 | var MockReCaptcha = /** @class */ (function () {
|
119 | function MockReCaptcha(auth) {
|
120 | this.auth = auth;
|
121 | this.counter = _WIDGET_ID_START;
|
122 | this._widgets = new Map();
|
123 | }
|
124 | MockReCaptcha.prototype.render = function (container, parameters) {
|
125 | var id = this.counter;
|
126 | this._widgets.set(id, new MockWidget(container, this.auth.name, parameters || {}));
|
127 | this.counter++;
|
128 | return id;
|
129 | };
|
130 | MockReCaptcha.prototype.reset = function (optWidgetId) {
|
131 | var _a;
|
132 | var id = optWidgetId || _WIDGET_ID_START;
|
133 | void ((_a = this._widgets.get(id)) === null || _a === void 0 ? void 0 : _a.delete());
|
134 | this._widgets.delete(id);
|
135 | };
|
136 | MockReCaptcha.prototype.getResponse = function (optWidgetId) {
|
137 | var _a;
|
138 | var id = optWidgetId || _WIDGET_ID_START;
|
139 | return ((_a = this._widgets.get(id)) === null || _a === void 0 ? void 0 : _a.getResponse()) || '';
|
140 | };
|
141 | MockReCaptcha.prototype.execute = function (optWidgetId) {
|
142 | var _a;
|
143 | return __awaiter(this, void 0, void 0, function () {
|
144 | var id;
|
145 | return __generator(this, function (_b) {
|
146 | id = optWidgetId || _WIDGET_ID_START;
|
147 | void ((_a = this._widgets.get(id)) === null || _a === void 0 ? void 0 : _a.execute());
|
148 | return [2 /*return*/, ''];
|
149 | });
|
150 | });
|
151 | };
|
152 | return MockReCaptcha;
|
153 | }());
|
154 | var MockWidget = /** @class */ (function () {
|
155 | function MockWidget(containerOrId, appName, params) {
|
156 | var _this = this;
|
157 | this.params = params;
|
158 | this.timerId = null;
|
159 | this.deleted = false;
|
160 | this.responseToken = null;
|
161 | this.clickHandler = function () {
|
162 | _this.execute();
|
163 | };
|
164 | var container = typeof containerOrId === 'string'
|
165 | ? document.getElementById(containerOrId)
|
166 | : containerOrId;
|
167 | _assert(container, "argument-error" /* ARGUMENT_ERROR */, { appName: appName });
|
168 | this.container = container;
|
169 | this.isVisible = this.params.size !== 'invisible';
|
170 | if (this.isVisible) {
|
171 | this.execute();
|
172 | }
|
173 | else {
|
174 | this.container.addEventListener('click', this.clickHandler);
|
175 | }
|
176 | }
|
177 | MockWidget.prototype.getResponse = function () {
|
178 | this.checkIfDeleted();
|
179 | return this.responseToken;
|
180 | };
|
181 | MockWidget.prototype.delete = function () {
|
182 | this.checkIfDeleted();
|
183 | this.deleted = true;
|
184 | if (this.timerId) {
|
185 | clearTimeout(this.timerId);
|
186 | this.timerId = null;
|
187 | }
|
188 | this.container.removeEventListener('click', this.clickHandler);
|
189 | };
|
190 | MockWidget.prototype.execute = function () {
|
191 | var _this = this;
|
192 | this.checkIfDeleted();
|
193 | if (this.timerId) {
|
194 | return;
|
195 | }
|
196 | this.timerId = window.setTimeout(function () {
|
197 | _this.responseToken = generateRandomAlphaNumericString(50);
|
198 | var _a = _this.params, callback = _a.callback, expiredCallback = _a["expired-callback"];
|
199 | if (callback) {
|
200 | try {
|
201 | callback(_this.responseToken);
|
202 | }
|
203 | catch (e) { }
|
204 | }
|
205 | _this.timerId = window.setTimeout(function () {
|
206 | _this.timerId = null;
|
207 | _this.responseToken = null;
|
208 | if (expiredCallback) {
|
209 | try {
|
210 | expiredCallback();
|
211 | }
|
212 | catch (e) { }
|
213 | }
|
214 | if (_this.isVisible) {
|
215 | _this.execute();
|
216 | }
|
217 | }, _EXPIRATION_TIME_MS);
|
218 | }, _SOLVE_TIME_MS);
|
219 | };
|
220 | MockWidget.prototype.checkIfDeleted = function () {
|
221 | if (this.deleted) {
|
222 | throw new Error('reCAPTCHA mock was already deleted!');
|
223 | }
|
224 | };
|
225 | return MockWidget;
|
226 | }());
|
227 | function generateRandomAlphaNumericString(len) {
|
228 | var chars = [];
|
229 | var allowedChars = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
230 | for (var i = 0; i < len; i++) {
|
231 | chars.push(allowedChars.charAt(Math.floor(Math.random() * allowedChars.length)));
|
232 | }
|
233 | return chars.join('');
|
234 | }
|
235 |
|
236 | /**
|
237 | * @license
|
238 | * Copyright 2020 Google LLC
|
239 | *
|
240 | * Licensed under the Apache License, Version 2.0 (the "License");
|
241 | * you may not use this file except in compliance with the License.
|
242 | * You may obtain a copy of the License at
|
243 | *
|
244 | * http://www.apache.org/licenses/LICENSE-2.0
|
245 | *
|
246 | * Unless required by applicable law or agreed to in writing, software
|
247 | * distributed under the License is distributed on an "AS IS" BASIS,
|
248 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
249 | * See the License for the specific language governing permissions and
|
250 | * limitations under the License.
|
251 | */
|
252 | // ReCaptcha will load using the same callback, so the callback function needs
|
253 | // to be kept around
|
254 | var _JSLOAD_CALLBACK = _generateCallbackName('rcb');
|
255 | var NETWORK_TIMEOUT_DELAY = new Delay(30000, 60000);
|
256 | var RECAPTCHA_BASE = 'https://www.google.com/recaptcha/api.js?';
|
257 | /**
|
258 | * Loader for the GReCaptcha library. There should only ever be one of this.
|
259 | */
|
260 | var ReCaptchaLoaderImpl = /** @class */ (function () {
|
261 | function ReCaptchaLoaderImpl() {
|
262 | this.hostLanguage = '';
|
263 | this.counter = 0;
|
264 | this.librarySeparatelyLoaded = !!_window().grecaptcha;
|
265 | }
|
266 | ReCaptchaLoaderImpl.prototype.load = function (auth, hl) {
|
267 | var _this = this;
|
268 | if (hl === void 0) { hl = ''; }
|
269 | _assert(isHostLanguageValid(hl), auth, "argument-error" /* ARGUMENT_ERROR */);
|
270 | if (this.shouldResolveImmediately(hl)) {
|
271 | return Promise.resolve(_window().grecaptcha);
|
272 | }
|
273 | return new Promise(function (resolve, reject) {
|
274 | var networkTimeout = _window().setTimeout(function () {
|
275 | reject(_createError(auth, "network-request-failed" /* NETWORK_REQUEST_FAILED */));
|
276 | }, NETWORK_TIMEOUT_DELAY.get());
|
277 | _window()[_JSLOAD_CALLBACK] = function () {
|
278 | _window().clearTimeout(networkTimeout);
|
279 | delete _window()[_JSLOAD_CALLBACK];
|
280 | var recaptcha = _window().grecaptcha;
|
281 | if (!recaptcha) {
|
282 | reject(_createError(auth, "internal-error" /* INTERNAL_ERROR */));
|
283 | return;
|
284 | }
|
285 | // Wrap the greptcha render function so that we know if the developer has
|
286 | // called it separately
|
287 | var render = recaptcha.render;
|
288 | recaptcha.render = function (container, params) {
|
289 | var widgetId = render(container, params);
|
290 | _this.counter++;
|
291 | return widgetId;
|
292 | };
|
293 | _this.hostLanguage = hl;
|
294 | resolve(recaptcha);
|
295 | };
|
296 | var url = RECAPTCHA_BASE + "?" + querystring({
|
297 | onload: _JSLOAD_CALLBACK,
|
298 | render: 'explicit',
|
299 | hl: hl
|
300 | });
|
301 | _loadJS(url).catch(function () {
|
302 | clearTimeout(networkTimeout);
|
303 | reject(_createError(auth, "internal-error" /* INTERNAL_ERROR */));
|
304 | });
|
305 | });
|
306 | };
|
307 | ReCaptchaLoaderImpl.prototype.clearedOneInstance = function () {
|
308 | this.counter--;
|
309 | };
|
310 | ReCaptchaLoaderImpl.prototype.shouldResolveImmediately = function (hl) {
|
311 | // We can resolve immediately if:
|
312 | // • grecaptcha is already defined AND (
|
313 | // 1. the requested language codes are the same OR
|
314 | // 2. there exists already a ReCaptcha on the page
|
315 | // 3. the library was already loaded by the app
|
316 | // In cases (2) and (3), we _can't_ reload as it would break the recaptchas
|
317 | // that are already in the page
|
318 | return (!!_window().grecaptcha &&
|
319 | (hl === this.hostLanguage ||
|
320 | this.counter > 0 ||
|
321 | this.librarySeparatelyLoaded));
|
322 | };
|
323 | return ReCaptchaLoaderImpl;
|
324 | }());
|
325 | function isHostLanguageValid(hl) {
|
326 | return hl.length <= 6 && /^\s*[a-zA-Z0-9\-]*\s*$/.test(hl);
|
327 | }
|
328 | var MockReCaptchaLoaderImpl = /** @class */ (function () {
|
329 | function MockReCaptchaLoaderImpl() {
|
330 | }
|
331 | MockReCaptchaLoaderImpl.prototype.load = function (auth) {
|
332 | return __awaiter(this, void 0, void 0, function () {
|
333 | return __generator(this, function (_a) {
|
334 | return [2 /*return*/, new MockReCaptcha(auth)];
|
335 | });
|
336 | });
|
337 | };
|
338 | MockReCaptchaLoaderImpl.prototype.clearedOneInstance = function () { };
|
339 | return MockReCaptchaLoaderImpl;
|
340 | }());
|
341 |
|
342 | /**
|
343 | * @license
|
344 | * Copyright 2020 Google LLC
|
345 | *
|
346 | * Licensed under the Apache License, Version 2.0 (the "License");
|
347 | * you may not use this file except in compliance with the License.
|
348 | * You may obtain a copy of the License at
|
349 | *
|
350 | * http://www.apache.org/licenses/LICENSE-2.0
|
351 | *
|
352 | * Unless required by applicable law or agreed to in writing, software
|
353 | * distributed under the License is distributed on an "AS IS" BASIS,
|
354 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
355 | * See the License for the specific language governing permissions and
|
356 | * limitations under the License.
|
357 | */
|
358 | var RECAPTCHA_VERIFIER_TYPE = 'recaptcha';
|
359 | var DEFAULT_PARAMS = {
|
360 | theme: 'light',
|
361 | type: 'image'
|
362 | };
|
363 | /**
|
364 | * An {@link https://www.google.com/recaptcha/ | reCAPTCHA}-based application verifier.
|
365 | *
|
366 | * @public
|
367 | */
|
368 | var RecaptchaVerifier = /** @class */ (function () {
|
369 | /**
|
370 | *
|
371 | * @param containerOrId - The reCAPTCHA container parameter.
|
372 | *
|
373 | * @remarks
|
374 | * This has different meaning depending on whether the reCAPTCHA is hidden or visible. For a
|
375 | * visible reCAPTCHA the container must be empty. If a string is used, it has to correspond to
|
376 | * an element ID. The corresponding element must also must be in the DOM at the time of
|
377 | * initialization.
|
378 | *
|
379 | * @param parameters - The optional reCAPTCHA parameters.
|
380 | *
|
381 | * @remarks
|
382 | * Check the reCAPTCHA docs for a comprehensive list. All parameters are accepted except for
|
383 | * the sitekey. Firebase Auth backend provisions a reCAPTCHA for each project and will
|
384 | * configure this upon rendering. For an invisible reCAPTCHA, a size key must have the value
|
385 | * 'invisible'.
|
386 | *
|
387 | * @param authExtern - The corresponding Firebase {@link Auth} instance.
|
388 | *
|
389 | * @remarks
|
390 | * If none is provided, the default Firebase {@link Auth} instance is used. A Firebase {@link Auth} instance
|
391 | * must be initialized with an API key, otherwise an error will be thrown.
|
392 | */
|
393 | function RecaptchaVerifier(containerOrId, parameters, authExtern) {
|
394 | if (parameters === void 0) { parameters = __assign({}, DEFAULT_PARAMS); }
|
395 | this.parameters = parameters;
|
396 | /**
|
397 | * The application verifier type.
|
398 | *
|
399 | * @remarks
|
400 | * For a reCAPTCHA verifier, this is 'recaptcha'.
|
401 | */
|
402 | this.type = RECAPTCHA_VERIFIER_TYPE;
|
403 | this.destroyed = false;
|
404 | this.widgetId = null;
|
405 | this.tokenChangeListeners = new Set();
|
406 | this.renderPromise = null;
|
407 | this.recaptcha = null;
|
408 | this.auth = _castAuth(authExtern);
|
409 | this.isInvisible = this.parameters.size === 'invisible';
|
410 | _assert(typeof document !== 'undefined', this.auth, "operation-not-supported-in-this-environment" /* OPERATION_NOT_SUPPORTED */);
|
411 | var container = typeof containerOrId === 'string'
|
412 | ? document.getElementById(containerOrId)
|
413 | : containerOrId;
|
414 | _assert(container, this.auth, "argument-error" /* ARGUMENT_ERROR */);
|
415 | this.container = container;
|
416 | this.parameters.callback = this.makeTokenCallback(this.parameters.callback);
|
417 | this._recaptchaLoader = this.auth.settings.appVerificationDisabledForTesting
|
418 | ? new MockReCaptchaLoaderImpl()
|
419 | : new ReCaptchaLoaderImpl();
|
420 | this.validateStartingState();
|
421 | // TODO: Figure out if sdk version is needed
|
422 | }
|
423 | /**
|
424 | * Waits for the user to solve the reCAPTCHA and resolves with the reCAPTCHA token.
|
425 | *
|
426 | * @returns A Promise for the reCAPTCHA token.
|
427 | */
|
428 | RecaptchaVerifier.prototype.verify = function () {
|
429 | return __awaiter(this, void 0, void 0, function () {
|
430 | var id, recaptcha, response;
|
431 | var _this = this;
|
432 | return __generator(this, function (_a) {
|
433 | switch (_a.label) {
|
434 | case 0:
|
435 | this.assertNotDestroyed();
|
436 | return [4 /*yield*/, this.render()];
|
437 | case 1:
|
438 | id = _a.sent();
|
439 | recaptcha = this.getAssertedRecaptcha();
|
440 | response = recaptcha.getResponse(id);
|
441 | if (response) {
|
442 | return [2 /*return*/, response];
|
443 | }
|
444 | return [2 /*return*/, new Promise(function (resolve) {
|
445 | var tokenChange = function (token) {
|
446 | if (!token) {
|
447 | return; // Ignore token expirations.
|
448 | }
|
449 | _this.tokenChangeListeners.delete(tokenChange);
|
450 | resolve(token);
|
451 | };
|
452 | _this.tokenChangeListeners.add(tokenChange);
|
453 | if (_this.isInvisible) {
|
454 | recaptcha.execute(id);
|
455 | }
|
456 | })];
|
457 | }
|
458 | });
|
459 | });
|
460 | };
|
461 | /**
|
462 | * Renders the reCAPTCHA widget on the page.
|
463 | *
|
464 | * @returns A Promise that resolves with the reCAPTCHA widget ID.
|
465 | */
|
466 | RecaptchaVerifier.prototype.render = function () {
|
467 | var _this = this;
|
468 | try {
|
469 | this.assertNotDestroyed();
|
470 | }
|
471 | catch (e) {
|
472 | // This method returns a promise. Since it's not async (we want to return the
|
473 | // _same_ promise if rendering is still occurring), the API surface should
|
474 | // reject with the error rather than just throw
|
475 | return Promise.reject(e);
|
476 | }
|
477 | if (this.renderPromise) {
|
478 | return this.renderPromise;
|
479 | }
|
480 | this.renderPromise = this.makeRenderPromise().catch(function (e) {
|
481 | _this.renderPromise = null;
|
482 | throw e;
|
483 | });
|
484 | return this.renderPromise;
|
485 | };
|
486 | /** @internal */
|
487 | RecaptchaVerifier.prototype._reset = function () {
|
488 | this.assertNotDestroyed();
|
489 | if (this.widgetId !== null) {
|
490 | this.getAssertedRecaptcha().reset(this.widgetId);
|
491 | }
|
492 | };
|
493 | /**
|
494 | * Clears the reCAPTCHA widget from the page and destroys the instance.
|
495 | */
|
496 | RecaptchaVerifier.prototype.clear = function () {
|
497 | var _this = this;
|
498 | this.assertNotDestroyed();
|
499 | this.destroyed = true;
|
500 | this._recaptchaLoader.clearedOneInstance();
|
501 | if (!this.isInvisible) {
|
502 | this.container.childNodes.forEach(function (node) {
|
503 | _this.container.removeChild(node);
|
504 | });
|
505 | }
|
506 | };
|
507 | RecaptchaVerifier.prototype.validateStartingState = function () {
|
508 | _assert(!this.parameters.sitekey, this.auth, "argument-error" /* ARGUMENT_ERROR */);
|
509 | _assert(this.isInvisible || !this.container.hasChildNodes(), this.auth, "argument-error" /* ARGUMENT_ERROR */);
|
510 | _assert(typeof document !== 'undefined', this.auth, "operation-not-supported-in-this-environment" /* OPERATION_NOT_SUPPORTED */);
|
511 | };
|
512 | RecaptchaVerifier.prototype.makeTokenCallback = function (existing) {
|
513 | var _this = this;
|
514 | return function (token) {
|
515 | _this.tokenChangeListeners.forEach(function (listener) { return listener(token); });
|
516 | if (typeof existing === 'function') {
|
517 | existing(token);
|
518 | }
|
519 | else if (typeof existing === 'string') {
|
520 | var globalFunc = _window()[existing];
|
521 | if (typeof globalFunc === 'function') {
|
522 | globalFunc(token);
|
523 | }
|
524 | }
|
525 | };
|
526 | };
|
527 | RecaptchaVerifier.prototype.assertNotDestroyed = function () {
|
528 | _assert(!this.destroyed, this.auth, "internal-error" /* INTERNAL_ERROR */);
|
529 | };
|
530 | RecaptchaVerifier.prototype.makeRenderPromise = function () {
|
531 | return __awaiter(this, void 0, void 0, function () {
|
532 | var container, guaranteedEmpty;
|
533 | return __generator(this, function (_a) {
|
534 | switch (_a.label) {
|
535 | case 0: return [4 /*yield*/, this.init()];
|
536 | case 1:
|
537 | _a.sent();
|
538 | if (!this.widgetId) {
|
539 | container = this.container;
|
540 | if (!this.isInvisible) {
|
541 | guaranteedEmpty = document.createElement('div');
|
542 | container.appendChild(guaranteedEmpty);
|
543 | container = guaranteedEmpty;
|
544 | }
|
545 | this.widgetId = this.getAssertedRecaptcha().render(container, this.parameters);
|
546 | }
|
547 | return [2 /*return*/, this.widgetId];
|
548 | }
|
549 | });
|
550 | });
|
551 | };
|
552 | RecaptchaVerifier.prototype.init = function () {
|
553 | return __awaiter(this, void 0, void 0, function () {
|
554 | var _a, siteKey;
|
555 | return __generator(this, function (_b) {
|
556 | switch (_b.label) {
|
557 | case 0:
|
558 | _assert(_isHttpOrHttps() && !_isWorker(), this.auth, "internal-error" /* INTERNAL_ERROR */);
|
559 | return [4 /*yield*/, domReady()];
|
560 | case 1:
|
561 | _b.sent();
|
562 | _a = this;
|
563 | return [4 /*yield*/, this._recaptchaLoader.load(this.auth, this.auth.languageCode || undefined)];
|
564 | case 2:
|
565 | _a.recaptcha = _b.sent();
|
566 | return [4 /*yield*/, getRecaptchaParams(this.auth)];
|
567 | case 3:
|
568 | siteKey = _b.sent();
|
569 | _assert(siteKey, this.auth, "internal-error" /* INTERNAL_ERROR */);
|
570 | this.parameters.sitekey = siteKey;
|
571 | return [2 /*return*/];
|
572 | }
|
573 | });
|
574 | });
|
575 | };
|
576 | RecaptchaVerifier.prototype.getAssertedRecaptcha = function () {
|
577 | _assert(this.recaptcha, this.auth, "internal-error" /* INTERNAL_ERROR */);
|
578 | return this.recaptcha;
|
579 | };
|
580 | return RecaptchaVerifier;
|
581 | }());
|
582 | function domReady() {
|
583 | var resolver = null;
|
584 | return new Promise(function (resolve) {
|
585 | if (document.readyState === 'complete') {
|
586 | resolve();
|
587 | return;
|
588 | }
|
589 | // Document not ready, wait for load before resolving.
|
590 | // Save resolver, so we can remove listener in case it was externally
|
591 | // cancelled.
|
592 | resolver = function () { return resolve(); };
|
593 | window.addEventListener('load', resolver);
|
594 | }).catch(function (e) {
|
595 | if (resolver) {
|
596 | window.removeEventListener('load', resolver);
|
597 | }
|
598 | throw e;
|
599 | });
|
600 | }
|
601 |
|
602 | /**
|
603 | * @license
|
604 | * Copyright 2020 Google LLC
|
605 | *
|
606 | * Licensed under the Apache License, Version 2.0 (the "License");
|
607 | * you may not use this file except in compliance with the License.
|
608 | * You may obtain a copy of the License at
|
609 | *
|
610 | * http://www.apache.org/licenses/LICENSE-2.0
|
611 | *
|
612 | * Unless required by applicable law or agreed to in writing, software
|
613 | * distributed under the License is distributed on an "AS IS" BASIS,
|
614 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
615 | * See the License for the specific language governing permissions and
|
616 | * limitations under the License.
|
617 | */
|
618 | var ConfirmationResultImpl = /** @class */ (function () {
|
619 | function ConfirmationResultImpl(verificationId, onConfirmation) {
|
620 | this.verificationId = verificationId;
|
621 | this.onConfirmation = onConfirmation;
|
622 | }
|
623 | ConfirmationResultImpl.prototype.confirm = function (verificationCode) {
|
624 | var authCredential = PhoneAuthCredential._fromVerification(this.verificationId, verificationCode);
|
625 | return this.onConfirmation(authCredential);
|
626 | };
|
627 | return ConfirmationResultImpl;
|
628 | }());
|
629 | /**
|
630 | * Asynchronously signs in using a phone number.
|
631 | *
|
632 | * @remarks
|
633 | * This method sends a code via SMS to the given
|
634 | * phone number, and returns a {@link ConfirmationResult}. After the user
|
635 | * provides the code sent to their phone, call {@link ConfirmationResult.confirm}
|
636 | * with the code to sign the user in.
|
637 | *
|
638 | * For abuse prevention, this method also requires a {@link ApplicationVerifier}.
|
639 | * This SDK includes a reCAPTCHA-based implementation, {@link RecaptchaVerifier}.
|
640 | * This function can work on other platforms that do not support the
|
641 | * {@link RecaptchaVerifier} (like React Native), but you need to use a
|
642 | * third-party {@link ApplicationVerifier} implementation.
|
643 | *
|
644 | * @example
|
645 | * ```javascript
|
646 | * // 'recaptcha-container' is the ID of an element in the DOM.
|
647 | * const applicationVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
|
648 | * const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, applicationVerifier);
|
649 | * // Obtain a verificationCode from the user.
|
650 | * const credential = await confirmationResult.confirm(verificationCode);
|
651 | * ```
|
652 | *
|
653 | * @param auth - The {@link Auth} instance.
|
654 | * @param phoneNumber - The user's phone number in E.164 format (e.g. +16505550101).
|
655 | * @param appVerifier - The {@link ApplicationVerifier}.
|
656 | *
|
657 | * @public
|
658 | */
|
659 | function signInWithPhoneNumber(auth, phoneNumber, appVerifier) {
|
660 | return __awaiter(this, void 0, void 0, function () {
|
661 | var authInternal, verificationId;
|
662 | return __generator(this, function (_a) {
|
663 | switch (_a.label) {
|
664 | case 0:
|
665 | authInternal = _castAuth(auth);
|
666 | return [4 /*yield*/, _verifyPhoneNumber(authInternal, phoneNumber, getModularInstance(appVerifier))];
|
667 | case 1:
|
668 | verificationId = _a.sent();
|
669 | return [2 /*return*/, new ConfirmationResultImpl(verificationId, function (cred) {
|
670 | return signInWithCredential(authInternal, cred);
|
671 | })];
|
672 | }
|
673 | });
|
674 | });
|
675 | }
|
676 | /**
|
677 | * Links the user account with the given phone number.
|
678 | *
|
679 | * @param user - The user.
|
680 | * @param phoneNumber - The user's phone number in E.164 format (e.g. +16505550101).
|
681 | * @param appVerifier - The {@link ApplicationVerifier}.
|
682 | *
|
683 | * @public
|
684 | */
|
685 | function linkWithPhoneNumber(user, phoneNumber, appVerifier) {
|
686 | return __awaiter(this, void 0, void 0, function () {
|
687 | var userInternal, verificationId;
|
688 | return __generator(this, function (_a) {
|
689 | switch (_a.label) {
|
690 | case 0:
|
691 | userInternal = getModularInstance(user);
|
692 | return [4 /*yield*/, _assertLinkedStatus(false, userInternal, "phone" /* PHONE */)];
|
693 | case 1:
|
694 | _a.sent();
|
695 | return [4 /*yield*/, _verifyPhoneNumber(userInternal.auth, phoneNumber, getModularInstance(appVerifier))];
|
696 | case 2:
|
697 | verificationId = _a.sent();
|
698 | return [2 /*return*/, new ConfirmationResultImpl(verificationId, function (cred) {
|
699 | return linkWithCredential(userInternal, cred);
|
700 | })];
|
701 | }
|
702 | });
|
703 | });
|
704 | }
|
705 | /**
|
706 | * Re-authenticates a user using a fresh phone credential.
|
707 | *
|
708 | * @remarks Use before operations such as {@link updatePassword} that require tokens from recent sign-in attempts.
|
709 | *
|
710 | * @param user - The user.
|
711 | * @param phoneNumber - The user's phone number in E.164 format (e.g. +16505550101).
|
712 | * @param appVerifier - The {@link ApplicationVerifier}.
|
713 | *
|
714 | * @public
|
715 | */
|
716 | function reauthenticateWithPhoneNumber(user, phoneNumber, appVerifier) {
|
717 | return __awaiter(this, void 0, void 0, function () {
|
718 | var userInternal, verificationId;
|
719 | return __generator(this, function (_a) {
|
720 | switch (_a.label) {
|
721 | case 0:
|
722 | userInternal = getModularInstance(user);
|
723 | return [4 /*yield*/, _verifyPhoneNumber(userInternal.auth, phoneNumber, getModularInstance(appVerifier))];
|
724 | case 1:
|
725 | verificationId = _a.sent();
|
726 | return [2 /*return*/, new ConfirmationResultImpl(verificationId, function (cred) {
|
727 | return reauthenticateWithCredential(userInternal, cred);
|
728 | })];
|
729 | }
|
730 | });
|
731 | });
|
732 | }
|
733 | /**
|
734 | * Returns a verification ID to be used in conjunction with the SMS code that is sent.
|
735 | *
|
736 | */
|
737 | function _verifyPhoneNumber(auth, options, verifier) {
|
738 | var _a;
|
739 | return __awaiter(this, void 0, void 0, function () {
|
740 | var recaptchaToken, phoneInfoOptions, session, response, mfaEnrollmentId, response, sessionInfo;
|
741 | return __generator(this, function (_b) {
|
742 | switch (_b.label) {
|
743 | case 0: return [4 /*yield*/, verifier.verify()];
|
744 | case 1:
|
745 | recaptchaToken = _b.sent();
|
746 | _b.label = 2;
|
747 | case 2:
|
748 | _b.trys.push([2, , 10, 11]);
|
749 | _assert(typeof recaptchaToken === 'string', auth, "argument-error" /* ARGUMENT_ERROR */);
|
750 | _assert(verifier.type === RECAPTCHA_VERIFIER_TYPE, auth, "argument-error" /* ARGUMENT_ERROR */);
|
751 | phoneInfoOptions = void 0;
|
752 | if (typeof options === 'string') {
|
753 | phoneInfoOptions = {
|
754 | phoneNumber: options
|
755 | };
|
756 | }
|
757 | else {
|
758 | phoneInfoOptions = options;
|
759 | }
|
760 | if (!('session' in phoneInfoOptions)) return [3 /*break*/, 7];
|
761 | session = phoneInfoOptions.session;
|
762 | if (!('phoneNumber' in phoneInfoOptions)) return [3 /*break*/, 4];
|
763 | _assert(session.type === "enroll" /* ENROLL */, auth, "internal-error" /* INTERNAL_ERROR */);
|
764 | return [4 /*yield*/, startEnrollPhoneMfa(auth, {
|
765 | idToken: session.credential,
|
766 | phoneEnrollmentInfo: {
|
767 | phoneNumber: phoneInfoOptions.phoneNumber,
|
768 | recaptchaToken: recaptchaToken
|
769 | }
|
770 | })];
|
771 | case 3:
|
772 | response = _b.sent();
|
773 | return [2 /*return*/, response.phoneSessionInfo.sessionInfo];
|
774 | case 4:
|
775 | _assert(session.type === "signin" /* SIGN_IN */, auth, "internal-error" /* INTERNAL_ERROR */);
|
776 | mfaEnrollmentId = ((_a = phoneInfoOptions.multiFactorHint) === null || _a === void 0 ? void 0 : _a.uid) ||
|
777 | phoneInfoOptions.multiFactorUid;
|
778 | _assert(mfaEnrollmentId, auth, "missing-multi-factor-info" /* MISSING_MFA_INFO */);
|
779 | return [4 /*yield*/, startSignInPhoneMfa(auth, {
|
780 | mfaPendingCredential: session.credential,
|
781 | mfaEnrollmentId: mfaEnrollmentId,
|
782 | phoneSignInInfo: {
|
783 | recaptchaToken: recaptchaToken
|
784 | }
|
785 | })];
|
786 | case 5:
|
787 | response = _b.sent();
|
788 | return [2 /*return*/, response.phoneResponseInfo.sessionInfo];
|
789 | case 6: return [3 /*break*/, 9];
|
790 | case 7: return [4 /*yield*/, sendPhoneVerificationCode(auth, {
|
791 | phoneNumber: phoneInfoOptions.phoneNumber,
|
792 | recaptchaToken: recaptchaToken
|
793 | })];
|
794 | case 8:
|
795 | sessionInfo = (_b.sent()).sessionInfo;
|
796 | return [2 /*return*/, sessionInfo];
|
797 | case 9: return [3 /*break*/, 11];
|
798 | case 10:
|
799 | verifier._reset();
|
800 | return [7 /*endfinally*/];
|
801 | case 11: return [2 /*return*/];
|
802 | }
|
803 | });
|
804 | });
|
805 | }
|
806 | /**
|
807 | * Updates the user's phone number.
|
808 | *
|
809 | * @example
|
810 | * ```
|
811 | * // 'recaptcha-container' is the ID of an element in the DOM.
|
812 | * const applicationVerifier = new RecaptchaVerifier('recaptcha-container');
|
813 | * const provider = new PhoneAuthProvider(auth);
|
814 | * const verificationId = await provider.verifyPhoneNumber('+16505550101', applicationVerifier);
|
815 | * // Obtain the verificationCode from the user.
|
816 | * const phoneCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
|
817 | * await updatePhoneNumber(user, phoneCredential);
|
818 | * ```
|
819 | *
|
820 | * @param user - The user.
|
821 | * @param credential - A credential authenticating the new phone number.
|
822 | *
|
823 | * @public
|
824 | */
|
825 | function updatePhoneNumber(user, credential) {
|
826 | return __awaiter(this, void 0, void 0, function () {
|
827 | return __generator(this, function (_a) {
|
828 | switch (_a.label) {
|
829 | case 0: return [4 /*yield*/, _link(getModularInstance(user), credential)];
|
830 | case 1:
|
831 | _a.sent();
|
832 | return [2 /*return*/];
|
833 | }
|
834 | });
|
835 | });
|
836 | }
|
837 |
|
838 | /**
|
839 | * @license
|
840 | * Copyright 2020 Google LLC
|
841 | *
|
842 | * Licensed under the Apache License, Version 2.0 (the "License");
|
843 | * you may not use this file except in compliance with the License.
|
844 | * You may obtain a copy of the License at
|
845 | *
|
846 | * http://www.apache.org/licenses/LICENSE-2.0
|
847 | *
|
848 | * Unless required by applicable law or agreed to in writing, software
|
849 | * distributed under the License is distributed on an "AS IS" BASIS,
|
850 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
851 | * See the License for the specific language governing permissions and
|
852 | * limitations under the License.
|
853 | */
|
854 | /**
|
855 | * Provider for generating an {@link PhoneAuthCredential}.
|
856 | *
|
857 | * @example
|
858 | * ```javascript
|
859 | * // 'recaptcha-container' is the ID of an element in the DOM.
|
860 | * const applicationVerifier = new RecaptchaVerifier('recaptcha-container');
|
861 | * const provider = new PhoneAuthProvider(auth);
|
862 | * const verificationId = await provider.verifyPhoneNumber('+16505550101', applicationVerifier);
|
863 | * // Obtain the verificationCode from the user.
|
864 | * const phoneCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
|
865 | * const userCredential = await signInWithCredential(auth, phoneCredential);
|
866 | * ```
|
867 | *
|
868 | * @public
|
869 | */
|
870 | var PhoneAuthProvider = /** @class */ (function () {
|
871 | /**
|
872 | * @param auth - The Firebase {@link Auth} instance in which sign-ins should occur.
|
873 | *
|
874 | */
|
875 | function PhoneAuthProvider(auth) {
|
876 | /** Always set to {@link ProviderId}.PHONE. */
|
877 | this.providerId = PhoneAuthProvider.PROVIDER_ID;
|
878 | this.auth = _castAuth(auth);
|
879 | }
|
880 | /**
|
881 | *
|
882 | * Starts a phone number authentication flow by sending a verification code to the given phone
|
883 | * number.
|
884 | *
|
885 | * @example
|
886 | * ```javascript
|
887 | * const provider = new PhoneAuthProvider(auth);
|
888 | * const verificationId = await provider.verifyPhoneNumber(phoneNumber, applicationVerifier);
|
889 | * // Obtain verificationCode from the user.
|
890 | * const authCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
|
891 | * const userCredential = await signInWithCredential(auth, authCredential);
|
892 | * ```
|
893 | *
|
894 | * @example
|
895 | * An alternative flow is provided using the `signInWithPhoneNumber` method.
|
896 | * ```javascript
|
897 | * const confirmationResult = signInWithPhoneNumber(auth, phoneNumber, applicationVerifier);
|
898 | * // Obtain verificationCode from the user.
|
899 | * const userCredential = confirmationResult.confirm(verificationCode);
|
900 | * ```
|
901 | *
|
902 | * @param phoneInfoOptions - The user's {@link PhoneInfoOptions}. The phone number should be in
|
903 | * E.164 format (e.g. +16505550101).
|
904 | * @param applicationVerifier - For abuse prevention, this method also requires a
|
905 | * {@link ApplicationVerifier}. This SDK includes a reCAPTCHA-based implementation,
|
906 | * {@link RecaptchaVerifier}.
|
907 | *
|
908 | * @returns A Promise for a verification ID that can be passed to
|
909 | * {@link PhoneAuthProvider.credential} to identify this flow..
|
910 | */
|
911 | PhoneAuthProvider.prototype.verifyPhoneNumber = function (phoneOptions, applicationVerifier) {
|
912 | return _verifyPhoneNumber(this.auth, phoneOptions, getModularInstance(applicationVerifier));
|
913 | };
|
914 | /**
|
915 | * Creates a phone auth credential, given the verification ID from
|
916 | * {@link PhoneAuthProvider.verifyPhoneNumber} and the code that was sent to the user's
|
917 | * mobile device.
|
918 | *
|
919 | * @example
|
920 | * ```javascript
|
921 | * const provider = new PhoneAuthProvider(auth);
|
922 | * const verificationId = provider.verifyPhoneNumber(phoneNumber, applicationVerifier);
|
923 | * // Obtain verificationCode from the user.
|
924 | * const authCredential = PhoneAuthProvider.credential(verificationId, verificationCode);
|
925 | * const userCredential = signInWithCredential(auth, authCredential);
|
926 | * ```
|
927 | *
|
928 | * @example
|
929 | * An alternative flow is provided using the `signInWithPhoneNumber` method.
|
930 | * ```javascript
|
931 | * const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, applicationVerifier);
|
932 | * // Obtain verificationCode from the user.
|
933 | * const userCredential = await confirmationResult.confirm(verificationCode);
|
934 | * ```
|
935 | *
|
936 | * @param verificationId - The verification ID returned from {@link PhoneAuthProvider.verifyPhoneNumber}.
|
937 | * @param verificationCode - The verification code sent to the user's mobile device.
|
938 | *
|
939 | * @returns The auth provider credential.
|
940 | */
|
941 | PhoneAuthProvider.credential = function (verificationId, verificationCode) {
|
942 | return PhoneAuthCredential._fromVerification(verificationId, verificationCode);
|
943 | };
|
944 | /**
|
945 | * Generates an {@link AuthCredential} from a {@link UserCredential}.
|
946 | * @param userCredential - The user credential.
|
947 | */
|
948 | PhoneAuthProvider.credentialFromResult = function (userCredential) {
|
949 | var credential = userCredential;
|
950 | return PhoneAuthProvider.credentialFromTaggedObject(credential);
|
951 | };
|
952 | /**
|
953 | * Returns an {@link AuthCredential} when passed an error.
|
954 | *
|
955 | * @remarks
|
956 | *
|
957 | * This method works for errors like
|
958 | * `auth/account-exists-with-different-credentials`. This is useful for
|
959 | * recovering when attempting to set a user's phone number but the number
|
960 | * in question is already tied to another account. For example, the following
|
961 | * code tries to update the current user's phone number, and if that
|
962 | * fails, links the user with the account associated with that number:
|
963 | *
|
964 | * ```js
|
965 | * const provider = new PhoneAuthProvider(auth);
|
966 | * const verificationId = await provider.verifyPhoneNumber(number, verifier);
|
967 | * try {
|
968 | * const code = ''; // Prompt the user for the verification code
|
969 | * await updatePhoneNumber(
|
970 | * auth.currentUser,
|
971 | * PhoneAuthProvider.credential(verificationId, code));
|
972 | * } catch (e) {
|
973 | * if (e.code === 'auth/account-exists-with-different-credential') {
|
974 | * const cred = PhoneAuthProvider.credentialFromError(e);
|
975 | * await linkWithCredential(auth.currentUser, cred);
|
976 | * }
|
977 | * }
|
978 | *
|
979 | * // At this point, auth.currentUser.phoneNumber === number.
|
980 | * ```
|
981 | *
|
982 | * @param error - The error to generate a credential from.
|
983 | */
|
984 | PhoneAuthProvider.credentialFromError = function (error) {
|
985 | return PhoneAuthProvider.credentialFromTaggedObject((error.customData || {}));
|
986 | };
|
987 | PhoneAuthProvider.credentialFromTaggedObject = function (_a) {
|
988 | var tokenResponse = _a._tokenResponse;
|
989 | if (!tokenResponse) {
|
990 | return null;
|
991 | }
|
992 | var _b = tokenResponse, phoneNumber = _b.phoneNumber, temporaryProof = _b.temporaryProof;
|
993 | if (phoneNumber && temporaryProof) {
|
994 | return PhoneAuthCredential._fromTokenResponse(phoneNumber, temporaryProof);
|
995 | }
|
996 | return null;
|
997 | };
|
998 | /** Always set to {@link ProviderId}.PHONE. */
|
999 | PhoneAuthProvider.PROVIDER_ID = "phone" /* PHONE */;
|
1000 | /** Always set to {@link SignInMethod}.PHONE. */
|
1001 | PhoneAuthProvider.PHONE_SIGN_IN_METHOD = "phone" /* PHONE */;
|
1002 | return PhoneAuthProvider;
|
1003 | }());
|
1004 |
|
1005 | /**
|
1006 | * @license
|
1007 | * Copyright 2020 Google LLC
|
1008 | *
|
1009 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1010 | * you may not use this file except in compliance with the License.
|
1011 | * You may obtain a copy of the License at
|
1012 | *
|
1013 | * http://www.apache.org/licenses/LICENSE-2.0
|
1014 | *
|
1015 | * Unless required by applicable law or agreed to in writing, software
|
1016 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1017 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1018 | * See the License for the specific language governing permissions and
|
1019 | * limitations under the License.
|
1020 | */
|
1021 | var _POLL_WINDOW_CLOSE_TIMEOUT = new Delay(2000, 10000);
|
1022 | /**
|
1023 | * Authenticates a Firebase client using a popup-based OAuth authentication flow.
|
1024 | *
|
1025 | * @remarks
|
1026 | * If succeeds, returns the signed in user along with the provider's credential. If sign in was
|
1027 | * unsuccessful, returns an error object containing additional information about the error.
|
1028 | *
|
1029 | * @example
|
1030 | * ```javascript
|
1031 | * // Sign in using a popup.
|
1032 | * const provider = new FacebookAuthProvider();
|
1033 | * const result = await signInWithPopup(auth, provider);
|
1034 | *
|
1035 | * // The signed-in user info.
|
1036 | * const user = result.user;
|
1037 | * // This gives you a Facebook Access Token.
|
1038 | * const credential = provider.credentialFromResult(auth, result);
|
1039 | * const token = credential.accessToken;
|
1040 | * ```
|
1041 | *
|
1042 | * @param auth - The {@link Auth} instance.
|
1043 | * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
|
1044 | * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
|
1045 | * @param resolver - An instance of {@link PopupRedirectResolver}, optional
|
1046 | * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
|
1047 | *
|
1048 | *
|
1049 | * @public
|
1050 | */
|
1051 | function signInWithPopup(auth, provider, resolver) {
|
1052 | return __awaiter(this, void 0, void 0, function () {
|
1053 | var authInternal, resolverInternal, action;
|
1054 | return __generator(this, function (_a) {
|
1055 | authInternal = _castAuth(auth);
|
1056 | _assertInstanceOf(auth, provider, FederatedAuthProvider);
|
1057 | resolverInternal = _withDefaultResolver(authInternal, resolver);
|
1058 | action = new PopupOperation(authInternal, "signInViaPopup" /* SIGN_IN_VIA_POPUP */, provider, resolverInternal);
|
1059 | return [2 /*return*/, action.executeNotNull()];
|
1060 | });
|
1061 | });
|
1062 | }
|
1063 | /**
|
1064 | * Reauthenticates the current user with the specified {@link OAuthProvider} using a pop-up based
|
1065 | * OAuth flow.
|
1066 | *
|
1067 | * @remarks
|
1068 | * If the reauthentication is successful, the returned result will contain the user and the
|
1069 | * provider's credential.
|
1070 | *
|
1071 | * @example
|
1072 | * ```javascript
|
1073 | * // Sign in using a popup.
|
1074 | * const provider = new FacebookAuthProvider();
|
1075 | * const result = await signInWithPopup(auth, provider);
|
1076 | * // Reauthenticate using a popup.
|
1077 | * await reauthenticateWithPopup(result.user, provider);
|
1078 | * ```
|
1079 | *
|
1080 | * @param user - The user.
|
1081 | * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
|
1082 | * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
|
1083 | * @param resolver - An instance of {@link PopupRedirectResolver}, optional
|
1084 | * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
|
1085 | *
|
1086 | * @public
|
1087 | */
|
1088 | function reauthenticateWithPopup(user, provider, resolver) {
|
1089 | return __awaiter(this, void 0, void 0, function () {
|
1090 | var userInternal, resolverInternal, action;
|
1091 | return __generator(this, function (_a) {
|
1092 | userInternal = getModularInstance(user);
|
1093 | _assertInstanceOf(userInternal.auth, provider, FederatedAuthProvider);
|
1094 | resolverInternal = _withDefaultResolver(userInternal.auth, resolver);
|
1095 | action = new PopupOperation(userInternal.auth, "reauthViaPopup" /* REAUTH_VIA_POPUP */, provider, resolverInternal, userInternal);
|
1096 | return [2 /*return*/, action.executeNotNull()];
|
1097 | });
|
1098 | });
|
1099 | }
|
1100 | /**
|
1101 | * Links the authenticated provider to the user account using a pop-up based OAuth flow.
|
1102 | *
|
1103 | * @remarks
|
1104 | * If the linking is successful, the returned result will contain the user and the provider's credential.
|
1105 | *
|
1106 | *
|
1107 | * @example
|
1108 | * ```javascript
|
1109 | * // Sign in using some other provider.
|
1110 | * const result = await signInWithEmailAndPassword(auth, email, password);
|
1111 | * // Link using a popup.
|
1112 | * const provider = new FacebookAuthProvider();
|
1113 | * await linkWithPopup(result.user, provider);
|
1114 | * ```
|
1115 | *
|
1116 | * @param user - The user.
|
1117 | * @param provider - The provider to authenticate. The provider has to be an {@link OAuthProvider}.
|
1118 | * Non-OAuth providers like {@link EmailAuthProvider} will throw an error.
|
1119 | * @param resolver - An instance of {@link PopupRedirectResolver}, optional
|
1120 | * if already supplied to {@link initializeAuth} or provided by {@link getAuth}.
|
1121 | *
|
1122 | * @public
|
1123 | */
|
1124 | function linkWithPopup(user, provider, resolver) {
|
1125 | return __awaiter(this, void 0, void 0, function () {
|
1126 | var userInternal, resolverInternal, action;
|
1127 | return __generator(this, function (_a) {
|
1128 | userInternal = getModularInstance(user);
|
1129 | _assertInstanceOf(userInternal.auth, provider, FederatedAuthProvider);
|
1130 | resolverInternal = _withDefaultResolver(userInternal.auth, resolver);
|
1131 | action = new PopupOperation(userInternal.auth, "linkViaPopup" /* LINK_VIA_POPUP */, provider, resolverInternal, userInternal);
|
1132 | return [2 /*return*/, action.executeNotNull()];
|
1133 | });
|
1134 | });
|
1135 | }
|
1136 | /**
|
1137 | * Popup event manager. Handles the popup's entire lifecycle; listens to auth
|
1138 | * events
|
1139 | *
|
1140 | */
|
1141 | var PopupOperation = /** @class */ (function (_super) {
|
1142 | __extends(PopupOperation, _super);
|
1143 | function PopupOperation(auth, filter, provider, resolver, user) {
|
1144 | var _this = _super.call(this, auth, filter, resolver, user) || this;
|
1145 | _this.provider = provider;
|
1146 | _this.authWindow = null;
|
1147 | _this.pollId = null;
|
1148 | if (PopupOperation.currentPopupAction) {
|
1149 | PopupOperation.currentPopupAction.cancel();
|
1150 | }
|
1151 | PopupOperation.currentPopupAction = _this;
|
1152 | return _this;
|
1153 | }
|
1154 | PopupOperation.prototype.executeNotNull = function () {
|
1155 | return __awaiter(this, void 0, void 0, function () {
|
1156 | var result;
|
1157 | return __generator(this, function (_a) {
|
1158 | switch (_a.label) {
|
1159 | case 0: return [4 /*yield*/, this.execute()];
|
1160 | case 1:
|
1161 | result = _a.sent();
|
1162 | _assert(result, this.auth, "internal-error" /* INTERNAL_ERROR */);
|
1163 | return [2 /*return*/, result];
|
1164 | }
|
1165 | });
|
1166 | });
|
1167 | };
|
1168 | PopupOperation.prototype.onExecution = function () {
|
1169 | return __awaiter(this, void 0, void 0, function () {
|
1170 | var eventId, _a;
|
1171 | var _this = this;
|
1172 | return __generator(this, function (_b) {
|
1173 | switch (_b.label) {
|
1174 | case 0:
|
1175 | debugAssert(this.filter.length === 1, 'Popup operations only handle one event');
|
1176 | eventId = _generateEventId();
|
1177 | _a = this;
|
1178 | return [4 /*yield*/, this.resolver._openPopup(this.auth, this.provider, this.filter[0], // There's always one, see constructor
|
1179 | eventId)];
|
1180 | case 1:
|
1181 | _a.authWindow = _b.sent();
|
1182 | this.authWindow.associatedEvent = eventId;
|
1183 | // Check for web storage support and origin validation _after_ the popup is
|
1184 | // loaded. These operations are slow (~1 second or so) Rather than
|
1185 | // waiting on them before opening the window, optimistically open the popup
|
1186 | // and check for storage support at the same time. If storage support is
|
1187 | // not available, this will cause the whole thing to reject properly. It
|
1188 | // will also close the popup, but since the promise has already rejected,
|
1189 | // the popup closed by user poll will reject into the void.
|
1190 | this.resolver._originValidation(this.auth).catch(function (e) {
|
1191 | _this.reject(e);
|
1192 | });
|
1193 | this.resolver._isIframeWebStorageSupported(this.auth, function (isSupported) {
|
1194 | if (!isSupported) {
|
1195 | _this.reject(_createError(_this.auth, "web-storage-unsupported" /* WEB_STORAGE_UNSUPPORTED */));
|
1196 | }
|
1197 | });
|
1198 | // Handle user closure. Notice this does *not* use await
|
1199 | this.pollUserCancellation();
|
1200 | return [2 /*return*/];
|
1201 | }
|
1202 | });
|
1203 | });
|
1204 | };
|
1205 | Object.defineProperty(PopupOperation.prototype, "eventId", {
|
1206 | get: function () {
|
1207 | var _a;
|
1208 | return ((_a = this.authWindow) === null || _a === void 0 ? void 0 : _a.associatedEvent) || null;
|
1209 | },
|
1210 | enumerable: false,
|
1211 | configurable: true
|
1212 | });
|
1213 | PopupOperation.prototype.cancel = function () {
|
1214 | this.reject(_createError(this.auth, "cancelled-popup-request" /* EXPIRED_POPUP_REQUEST */));
|
1215 | };
|
1216 | PopupOperation.prototype.cleanUp = function () {
|
1217 | if (this.authWindow) {
|
1218 | this.authWindow.close();
|
1219 | }
|
1220 | if (this.pollId) {
|
1221 | window.clearTimeout(this.pollId);
|
1222 | }
|
1223 | this.authWindow = null;
|
1224 | this.pollId = null;
|
1225 | PopupOperation.currentPopupAction = null;
|
1226 | };
|
1227 | PopupOperation.prototype.pollUserCancellation = function () {
|
1228 | var _this = this;
|
1229 | var poll = function () {
|
1230 | var _a, _b;
|
1231 | if ((_b = (_a = _this.authWindow) === null || _a === void 0 ? void 0 : _a.window) === null || _b === void 0 ? void 0 : _b.closed) {
|
1232 | // Make sure that there is sufficient time for whatever action to
|
1233 | // complete. The window could have closed but the sign in network
|
1234 | // call could still be in flight.
|
1235 | _this.pollId = window.setTimeout(function () {
|
1236 | _this.pollId = null;
|
1237 | _this.reject(_createError(_this.auth, "popup-closed-by-user" /* POPUP_CLOSED_BY_USER */));
|
1238 | }, 2000 /* AUTH_EVENT */);
|
1239 | return;
|
1240 | }
|
1241 | _this.pollId = window.setTimeout(poll, _POLL_WINDOW_CLOSE_TIMEOUT.get());
|
1242 | };
|
1243 | poll();
|
1244 | };
|
1245 | // Only one popup is ever shown at once. The lifecycle of the current popup
|
1246 | // can be managed / cancelled by the constructor.
|
1247 | PopupOperation.currentPopupAction = null;
|
1248 | return PopupOperation;
|
1249 | }(AbstractPopupRedirectOperation));
|
1250 |
|
1251 | /**
|
1252 | * @license
|
1253 | * Copyright 2020 Google LLC
|
1254 | *
|
1255 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1256 | * you may not use this file except in compliance with the License.
|
1257 | * You may obtain a copy of the License at
|
1258 | *
|
1259 | * http://www.apache.org/licenses/LICENSE-2.0
|
1260 | *
|
1261 | * Unless required by applicable law or agreed to in writing, software
|
1262 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1263 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1264 | * See the License for the specific language governing permissions and
|
1265 | * limitations under the License.
|
1266 | */
|
1267 | var IP_ADDRESS_REGEX = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
1268 | var HTTP_REGEX = /^https?/;
|
1269 | function _validateOrigin(auth) {
|
1270 | return __awaiter(this, void 0, void 0, function () {
|
1271 | var authorizedDomains, _i, authorizedDomains_1, domain;
|
1272 | return __generator(this, function (_a) {
|
1273 | switch (_a.label) {
|
1274 | case 0:
|
1275 | // Skip origin validation if we are in an emulated environment
|
1276 | if (auth.config.emulator) {
|
1277 | return [2 /*return*/];
|
1278 | }
|
1279 | return [4 /*yield*/, _getProjectConfig(auth)];
|
1280 | case 1:
|
1281 | authorizedDomains = (_a.sent()).authorizedDomains;
|
1282 | for (_i = 0, authorizedDomains_1 = authorizedDomains; _i < authorizedDomains_1.length; _i++) {
|
1283 | domain = authorizedDomains_1[_i];
|
1284 | try {
|
1285 | if (matchDomain(domain)) {
|
1286 | return [2 /*return*/];
|
1287 | }
|
1288 | }
|
1289 | catch (_b) {
|
1290 | // Do nothing if there's a URL error; just continue searching
|
1291 | }
|
1292 | }
|
1293 | // In the old SDK, this error also provides helpful messages.
|
1294 | _fail(auth, "unauthorized-domain" /* INVALID_ORIGIN */);
|
1295 | return [2 /*return*/];
|
1296 | }
|
1297 | });
|
1298 | });
|
1299 | }
|
1300 | function matchDomain(expected) {
|
1301 | var currentUrl = _getCurrentUrl();
|
1302 | var _a = new URL(currentUrl), protocol = _a.protocol, hostname = _a.hostname;
|
1303 | if (expected.startsWith('chrome-extension://')) {
|
1304 | var ceUrl = new URL(expected);
|
1305 | if (ceUrl.hostname === '' && hostname === '') {
|
1306 | // For some reason we're not parsing chrome URLs properly
|
1307 | return (protocol === 'chrome-extension:' &&
|
1308 | expected.replace('chrome-extension://', '') ===
|
1309 | currentUrl.replace('chrome-extension://', ''));
|
1310 | }
|
1311 | return protocol === 'chrome-extension:' && ceUrl.hostname === hostname;
|
1312 | }
|
1313 | if (!HTTP_REGEX.test(protocol)) {
|
1314 | return false;
|
1315 | }
|
1316 | if (IP_ADDRESS_REGEX.test(expected)) {
|
1317 | // The domain has to be exactly equal to the pattern, as an IP domain will
|
1318 | // only contain the IP, no extra character.
|
1319 | return hostname === expected;
|
1320 | }
|
1321 | // Dots in pattern should be escaped.
|
1322 | var escapedDomainPattern = expected.replace(/\./g, '\\.');
|
1323 | // Non ip address domains.
|
1324 | // domain.com = *.domain.com OR domain.com
|
1325 | var re = new RegExp('^(.+\\.' + escapedDomainPattern + '|' + escapedDomainPattern + ')$', 'i');
|
1326 | return re.test(hostname);
|
1327 | }
|
1328 |
|
1329 | /**
|
1330 | * @license
|
1331 | * Copyright 2020 Google LLC.
|
1332 | *
|
1333 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1334 | * you may not use this file except in compliance with the License.
|
1335 | * You may obtain a copy of the License at
|
1336 | *
|
1337 | * http://www.apache.org/licenses/LICENSE-2.0
|
1338 | *
|
1339 | * Unless required by applicable law or agreed to in writing, software
|
1340 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1341 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1342 | * See the License for the specific language governing permissions and
|
1343 | * limitations under the License.
|
1344 | */
|
1345 | var NETWORK_TIMEOUT = new Delay(30000, 60000);
|
1346 | /**
|
1347 | * Reset unlaoded GApi modules. If gapi.load fails due to a network error,
|
1348 | * it will stop working after a retrial. This is a hack to fix this issue.
|
1349 | */
|
1350 | function resetUnloadedGapiModules() {
|
1351 | // Clear last failed gapi.load state to force next gapi.load to first
|
1352 | // load the failed gapi.iframes module.
|
1353 | // Get gapix.beacon context.
|
1354 | var beacon = _window().___jsl;
|
1355 | // Get current hint.
|
1356 | if (beacon === null || beacon === void 0 ? void 0 : beacon.H) {
|
1357 | // Get gapi hint.
|
1358 | for (var _i = 0, _a = Object.keys(beacon.H); _i < _a.length; _i++) {
|
1359 | var hint = _a[_i];
|
1360 | // Requested modules.
|
1361 | beacon.H[hint].r = beacon.H[hint].r || [];
|
1362 | // Loaded modules.
|
1363 | beacon.H[hint].L = beacon.H[hint].L || [];
|
1364 | // Set requested modules to a copy of the loaded modules.
|
1365 | beacon.H[hint].r = __spreadArray([], beacon.H[hint].L);
|
1366 | // Clear pending callbacks.
|
1367 | if (beacon.CP) {
|
1368 | for (var i = 0; i < beacon.CP.length; i++) {
|
1369 | // Remove all failed pending callbacks.
|
1370 | beacon.CP[i] = null;
|
1371 | }
|
1372 | }
|
1373 | }
|
1374 | }
|
1375 | }
|
1376 | function loadGapi(auth) {
|
1377 | return new Promise(function (resolve, reject) {
|
1378 | var _a, _b, _c;
|
1379 | // Function to run when gapi.load is ready.
|
1380 | function loadGapiIframe() {
|
1381 | // The developer may have tried to previously run gapi.load and failed.
|
1382 | // Run this to fix that.
|
1383 | resetUnloadedGapiModules();
|
1384 | gapi.load('gapi.iframes', {
|
1385 | callback: function () {
|
1386 | resolve(gapi.iframes.getContext());
|
1387 | },
|
1388 | ontimeout: function () {
|
1389 | // The above reset may be sufficient, but having this reset after
|
1390 | // failure ensures that if the developer calls gapi.load after the
|
1391 | // connection is re-established and before another attempt to embed
|
1392 | // the iframe, it would work and would not be broken because of our
|
1393 | // failed attempt.
|
1394 | // Timeout when gapi.iframes.Iframe not loaded.
|
1395 | resetUnloadedGapiModules();
|
1396 | reject(_createError(auth, "network-request-failed" /* NETWORK_REQUEST_FAILED */));
|
1397 | },
|
1398 | timeout: NETWORK_TIMEOUT.get()
|
1399 | });
|
1400 | }
|
1401 | if ((_b = (_a = _window().gapi) === null || _a === void 0 ? void 0 : _a.iframes) === null || _b === void 0 ? void 0 : _b.Iframe) {
|
1402 | // If gapi.iframes.Iframe available, resolve.
|
1403 | resolve(gapi.iframes.getContext());
|
1404 | }
|
1405 | else if (!!((_c = _window().gapi) === null || _c === void 0 ? void 0 : _c.load)) {
|
1406 | // Gapi loader ready, load gapi.iframes.
|
1407 | loadGapiIframe();
|
1408 | }
|
1409 | else {
|
1410 | // Create a new iframe callback when this is called so as not to overwrite
|
1411 | // any previous defined callback. This happens if this method is called
|
1412 | // multiple times in parallel and could result in the later callback
|
1413 | // overwriting the previous one. This would end up with a iframe
|
1414 | // timeout.
|
1415 | var cbName = _generateCallbackName('iframefcb');
|
1416 | // GApi loader not available, dynamically load platform.js.
|
1417 | _window()[cbName] = function () {
|
1418 | // GApi loader should be ready.
|
1419 | if (!!gapi.load) {
|
1420 | loadGapiIframe();
|
1421 | }
|
1422 | else {
|
1423 | // Gapi loader failed, throw error.
|
1424 | reject(_createError(auth, "network-request-failed" /* NETWORK_REQUEST_FAILED */));
|
1425 | }
|
1426 | };
|
1427 | // Load GApi loader.
|
1428 | return _loadJS("https://apis.google.com/js/api.js?onload=" + cbName).catch(function (e) { return reject(e); });
|
1429 | }
|
1430 | }).catch(function (error) {
|
1431 | // Reset cached promise to allow for retrial.
|
1432 | cachedGApiLoader = null;
|
1433 | throw error;
|
1434 | });
|
1435 | }
|
1436 | var cachedGApiLoader = null;
|
1437 | function _loadGapi(auth) {
|
1438 | cachedGApiLoader = cachedGApiLoader || loadGapi(auth);
|
1439 | return cachedGApiLoader;
|
1440 | }
|
1441 |
|
1442 | /**
|
1443 | * @license
|
1444 | * Copyright 2020 Google LLC.
|
1445 | *
|
1446 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1447 | * you may not use this file except in compliance with the License.
|
1448 | * You may obtain a copy of the License at
|
1449 | *
|
1450 | * http://www.apache.org/licenses/LICENSE-2.0
|
1451 | *
|
1452 | * Unless required by applicable law or agreed to in writing, software
|
1453 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1454 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1455 | * See the License for the specific language governing permissions and
|
1456 | * limitations under the License.
|
1457 | */
|
1458 | var PING_TIMEOUT = new Delay(5000, 15000);
|
1459 | var IFRAME_PATH = '__/auth/iframe';
|
1460 | var EMULATED_IFRAME_PATH = 'emulator/auth/iframe';
|
1461 | var IFRAME_ATTRIBUTES = {
|
1462 | style: {
|
1463 | position: 'absolute',
|
1464 | top: '-100px',
|
1465 | width: '1px',
|
1466 | height: '1px'
|
1467 | },
|
1468 | 'aria-hidden': 'true',
|
1469 | tabindex: '-1'
|
1470 | };
|
1471 | // Map from apiHost to endpoint ID for passing into iframe. In current SDK, apiHost can be set to
|
1472 | // anything (not from a list of endpoints with IDs as in legacy), so this is the closest we can get.
|
1473 | var EID_FROM_APIHOST = new Map([
|
1474 | ["identitytoolkit.googleapis.com" /* API_HOST */, 'p'],
|
1475 | ['staging-identitytoolkit.sandbox.googleapis.com', 's'],
|
1476 | ['test-identitytoolkit.sandbox.googleapis.com', 't'] // test
|
1477 | ]);
|
1478 | function getIframeUrl(auth) {
|
1479 | var config = auth.config;
|
1480 | _assert(config.authDomain, auth, "auth-domain-config-required" /* MISSING_AUTH_DOMAIN */);
|
1481 | var url = config.emulator
|
1482 | ? _emulatorUrl(config, EMULATED_IFRAME_PATH)
|
1483 | : "https://" + auth.config.authDomain + "/" + IFRAME_PATH;
|
1484 | var params = {
|
1485 | apiKey: config.apiKey,
|
1486 | appName: auth.name,
|
1487 | v: SDK_VERSION
|
1488 | };
|
1489 | var eid = EID_FROM_APIHOST.get(auth.config.apiHost);
|
1490 | if (eid) {
|
1491 | params.eid = eid;
|
1492 | }
|
1493 | var frameworks = auth._getFrameworks();
|
1494 | if (frameworks.length) {
|
1495 | params.fw = frameworks.join(',');
|
1496 | }
|
1497 | return url + "?" + querystring(params).slice(1);
|
1498 | }
|
1499 | function _openIframe(auth) {
|
1500 | return __awaiter(this, void 0, void 0, function () {
|
1501 | var context, gapi;
|
1502 | var _this = this;
|
1503 | return __generator(this, function (_a) {
|
1504 | switch (_a.label) {
|
1505 | case 0: return [4 /*yield*/, _loadGapi(auth)];
|
1506 | case 1:
|
1507 | context = _a.sent();
|
1508 | gapi = _window().gapi;
|
1509 | _assert(gapi, auth, "internal-error" /* INTERNAL_ERROR */);
|
1510 | return [2 /*return*/, context.open({
|
1511 | where: document.body,
|
1512 | url: getIframeUrl(auth),
|
1513 | messageHandlersFilter: gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER,
|
1514 | attributes: IFRAME_ATTRIBUTES,
|
1515 | dontclear: true
|
1516 | }, function (iframe) {
|
1517 | return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
|
1518 | // Clear timer and resolve pending iframe ready promise.
|
1519 | function clearTimerAndResolve() {
|
1520 | _window().clearTimeout(networkErrorTimer);
|
1521 | resolve(iframe);
|
1522 | }
|
1523 | var networkError, networkErrorTimer;
|
1524 | return __generator(this, function (_a) {
|
1525 | switch (_a.label) {
|
1526 | case 0: return [4 /*yield*/, iframe.restyle({
|
1527 | // Prevent iframe from closing on mouse out.
|
1528 | setHideOnLeave: false
|
1529 | })];
|
1530 | case 1:
|
1531 | _a.sent();
|
1532 | networkError = _createError(auth, "network-request-failed" /* NETWORK_REQUEST_FAILED */);
|
1533 | networkErrorTimer = _window().setTimeout(function () {
|
1534 | reject(networkError);
|
1535 | }, PING_TIMEOUT.get());
|
1536 | // This returns an IThenable. However the reject part does not call
|
1537 | // when the iframe is not loaded.
|
1538 | iframe.ping(clearTimerAndResolve).then(clearTimerAndResolve, function () {
|
1539 | reject(networkError);
|
1540 | });
|
1541 | return [2 /*return*/];
|
1542 | }
|
1543 | });
|
1544 | }); });
|
1545 | })];
|
1546 | }
|
1547 | });
|
1548 | });
|
1549 | }
|
1550 |
|
1551 | /**
|
1552 | * @license
|
1553 | * Copyright 2020 Google LLC.
|
1554 | *
|
1555 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1556 | * you may not use this file except in compliance with the License.
|
1557 | * You may obtain a copy of the License at
|
1558 | *
|
1559 | * http://www.apache.org/licenses/LICENSE-2.0
|
1560 | *
|
1561 | * Unless required by applicable law or agreed to in writing, software
|
1562 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1563 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1564 | * See the License for the specific language governing permissions and
|
1565 | * limitations under the License.
|
1566 | */
|
1567 | var BASE_POPUP_OPTIONS = {
|
1568 | location: 'yes',
|
1569 | resizable: 'yes',
|
1570 | statusbar: 'yes',
|
1571 | toolbar: 'no'
|
1572 | };
|
1573 | var DEFAULT_WIDTH = 500;
|
1574 | var DEFAULT_HEIGHT = 600;
|
1575 | var TARGET_BLANK = '_blank';
|
1576 | var FIREFOX_EMPTY_URL = 'http://localhost';
|
1577 | var AuthPopup = /** @class */ (function () {
|
1578 | function AuthPopup(window) {
|
1579 | this.window = window;
|
1580 | this.associatedEvent = null;
|
1581 | }
|
1582 | AuthPopup.prototype.close = function () {
|
1583 | if (this.window) {
|
1584 | try {
|
1585 | this.window.close();
|
1586 | }
|
1587 | catch (e) { }
|
1588 | }
|
1589 | };
|
1590 | return AuthPopup;
|
1591 | }());
|
1592 | function _open(auth, url, name, width, height) {
|
1593 | if (width === void 0) { width = DEFAULT_WIDTH; }
|
1594 | if (height === void 0) { height = DEFAULT_HEIGHT; }
|
1595 | var top = Math.max((window.screen.availHeight - height) / 2, 0).toString();
|
1596 | var left = Math.max((window.screen.availWidth - width) / 2, 0).toString();
|
1597 | var target = '';
|
1598 | var options = __assign(__assign({}, BASE_POPUP_OPTIONS), { width: width.toString(), height: height.toString(), top: top,
|
1599 | left: left });
|
1600 | // Chrome iOS 7 and 8 is returning an undefined popup win when target is
|
1601 | // specified, even though the popup is not necessarily blocked.
|
1602 | var ua = getUA().toLowerCase();
|
1603 | if (name) {
|
1604 | target = _isChromeIOS(ua) ? TARGET_BLANK : name;
|
1605 | }
|
1606 | if (_isFirefox(ua)) {
|
1607 | // Firefox complains when invalid URLs are popped out. Hacky way to bypass.
|
1608 | url = url || FIREFOX_EMPTY_URL;
|
1609 | // Firefox disables by default scrolling on popup windows, which can create
|
1610 | // issues when the user has many Google accounts, for instance.
|
1611 | options.scrollbars = 'yes';
|
1612 | }
|
1613 | var optionsString = Object.entries(options).reduce(function (accum, _a) {
|
1614 | var key = _a[0], value = _a[1];
|
1615 | return "" + accum + key + "=" + value + ",";
|
1616 | }, '');
|
1617 | if (_isIOSStandalone(ua) && target !== '_self') {
|
1618 | openAsNewWindowIOS(url || '', target);
|
1619 | return new AuthPopup(null);
|
1620 | }
|
1621 | // about:blank getting sanitized causing browsers like IE/Edge to display
|
1622 | // brief error message before redirecting to handler.
|
1623 | var newWin = window.open(url || '', target, optionsString);
|
1624 | _assert(newWin, auth, "popup-blocked" /* POPUP_BLOCKED */);
|
1625 | // Flaky on IE edge, encapsulate with a try and catch.
|
1626 | try {
|
1627 | newWin.focus();
|
1628 | }
|
1629 | catch (e) { }
|
1630 | return new AuthPopup(newWin);
|
1631 | }
|
1632 | function openAsNewWindowIOS(url, target) {
|
1633 | var el = document.createElement('a');
|
1634 | el.href = url;
|
1635 | el.target = target;
|
1636 | var click = document.createEvent('MouseEvent');
|
1637 | click.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 1, null);
|
1638 | el.dispatchEvent(click);
|
1639 | }
|
1640 |
|
1641 | /**
|
1642 | * @license
|
1643 | * Copyright 2020 Google LLC
|
1644 | *
|
1645 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1646 | * you may not use this file except in compliance with the License.
|
1647 | * You may obtain a copy of the License at
|
1648 | *
|
1649 | * http://www.apache.org/licenses/LICENSE-2.0
|
1650 | *
|
1651 | * Unless required by applicable law or agreed to in writing, software
|
1652 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1653 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1654 | * See the License for the specific language governing permissions and
|
1655 | * limitations under the License.
|
1656 | */
|
1657 | /**
|
1658 | * The special web storage event
|
1659 | *
|
1660 | */
|
1661 | var WEB_STORAGE_SUPPORT_KEY = 'webStorageSupport';
|
1662 | var BrowserPopupRedirectResolver = /** @class */ (function () {
|
1663 | function BrowserPopupRedirectResolver() {
|
1664 | this.eventManagers = {};
|
1665 | this.iframes = {};
|
1666 | this.originValidationPromises = {};
|
1667 | this._redirectPersistence = browserSessionPersistence;
|
1668 | this._completeRedirectFn = _getRedirectResult;
|
1669 | this._overrideRedirectResult = _overrideRedirectResult;
|
1670 | }
|
1671 | // Wrapping in async even though we don't await anywhere in order
|
1672 | // to make sure errors are raised as promise rejections
|
1673 | BrowserPopupRedirectResolver.prototype._openPopup = function (auth, provider, authType, eventId) {
|
1674 | var _a;
|
1675 | return __awaiter(this, void 0, void 0, function () {
|
1676 | var url;
|
1677 | return __generator(this, function (_b) {
|
1678 | debugAssert((_a = this.eventManagers[auth._key()]) === null || _a === void 0 ? void 0 : _a.manager, '_initialize() not called before _openPopup()');
|
1679 | url = _getRedirectUrl(auth, provider, authType, _getCurrentUrl(), eventId);
|
1680 | return [2 /*return*/, _open(auth, url, _generateEventId())];
|
1681 | });
|
1682 | });
|
1683 | };
|
1684 | BrowserPopupRedirectResolver.prototype._openRedirect = function (auth, provider, authType, eventId) {
|
1685 | return __awaiter(this, void 0, void 0, function () {
|
1686 | return __generator(this, function (_a) {
|
1687 | switch (_a.label) {
|
1688 | case 0: return [4 /*yield*/, this._originValidation(auth)];
|
1689 | case 1:
|
1690 | _a.sent();
|
1691 | _setWindowLocation(_getRedirectUrl(auth, provider, authType, _getCurrentUrl(), eventId));
|
1692 | return [2 /*return*/, new Promise(function () { })];
|
1693 | }
|
1694 | });
|
1695 | });
|
1696 | };
|
1697 | BrowserPopupRedirectResolver.prototype._initialize = function (auth) {
|
1698 | var _this = this;
|
1699 | var key = auth._key();
|
1700 | if (this.eventManagers[key]) {
|
1701 | var _a = this.eventManagers[key], manager = _a.manager, promise_1 = _a.promise;
|
1702 | if (manager) {
|
1703 | return Promise.resolve(manager);
|
1704 | }
|
1705 | else {
|
1706 | debugAssert(promise_1, 'If manager is not set, promise should be');
|
1707 | return promise_1;
|
1708 | }
|
1709 | }
|
1710 | var promise = this.initAndGetManager(auth);
|
1711 | this.eventManagers[key] = { promise: promise };
|
1712 | // If the promise is rejected, the key should be removed so that the
|
1713 | // operation can be retried later.
|
1714 | promise.catch(function () {
|
1715 | delete _this.eventManagers[key];
|
1716 | });
|
1717 | return promise;
|
1718 | };
|
1719 | BrowserPopupRedirectResolver.prototype.initAndGetManager = function (auth) {
|
1720 | return __awaiter(this, void 0, void 0, function () {
|
1721 | var iframe, manager;
|
1722 | return __generator(this, function (_a) {
|
1723 | switch (_a.label) {
|
1724 | case 0: return [4 /*yield*/, _openIframe(auth)];
|
1725 | case 1:
|
1726 | iframe = _a.sent();
|
1727 | manager = new AuthEventManager(auth);
|
1728 | iframe.register('authEvent', function (iframeEvent) {
|
1729 | _assert(iframeEvent === null || iframeEvent === void 0 ? void 0 : iframeEvent.authEvent, auth, "invalid-auth-event" /* INVALID_AUTH_EVENT */);
|
1730 | // TODO: Consider splitting redirect and popup events earlier on
|
1731 | var handled = manager.onEvent(iframeEvent.authEvent);
|
1732 | return { status: handled ? "ACK" /* ACK */ : "ERROR" /* ERROR */ };
|
1733 | }, gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER);
|
1734 | this.eventManagers[auth._key()] = { manager: manager };
|
1735 | this.iframes[auth._key()] = iframe;
|
1736 | return [2 /*return*/, manager];
|
1737 | }
|
1738 | });
|
1739 | });
|
1740 | };
|
1741 | BrowserPopupRedirectResolver.prototype._isIframeWebStorageSupported = function (auth, cb) {
|
1742 | var iframe = this.iframes[auth._key()];
|
1743 | iframe.send(WEB_STORAGE_SUPPORT_KEY, { type: WEB_STORAGE_SUPPORT_KEY }, function (result) {
|
1744 | var _a;
|
1745 | var isSupported = (_a = result === null || result === void 0 ? void 0 : result[0]) === null || _a === void 0 ? void 0 : _a[WEB_STORAGE_SUPPORT_KEY];
|
1746 | if (isSupported !== undefined) {
|
1747 | cb(!!isSupported);
|
1748 | }
|
1749 | _fail(auth, "internal-error" /* INTERNAL_ERROR */);
|
1750 | }, gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER);
|
1751 | };
|
1752 | BrowserPopupRedirectResolver.prototype._originValidation = function (auth) {
|
1753 | var key = auth._key();
|
1754 | if (!this.originValidationPromises[key]) {
|
1755 | this.originValidationPromises[key] = _validateOrigin(auth);
|
1756 | }
|
1757 | return this.originValidationPromises[key];
|
1758 | };
|
1759 | Object.defineProperty(BrowserPopupRedirectResolver.prototype, "_shouldInitProactively", {
|
1760 | get: function () {
|
1761 | // Mobile browsers and Safari need to optimistically initialize
|
1762 | return _isMobileBrowser() || _isSafari() || _isIOS();
|
1763 | },
|
1764 | enumerable: false,
|
1765 | configurable: true
|
1766 | });
|
1767 | return BrowserPopupRedirectResolver;
|
1768 | }());
|
1769 | /**
|
1770 | * An implementation of {@link PopupRedirectResolver} suitable for browser
|
1771 | * based applications.
|
1772 | *
|
1773 | * @public
|
1774 | */
|
1775 | var browserPopupRedirectResolver = BrowserPopupRedirectResolver;
|
1776 |
|
1777 | var MultiFactorAssertionImpl = /** @class */ (function () {
|
1778 | function MultiFactorAssertionImpl(factorId) {
|
1779 | this.factorId = factorId;
|
1780 | }
|
1781 | MultiFactorAssertionImpl.prototype._process = function (auth, session, displayName) {
|
1782 | switch (session.type) {
|
1783 | case "enroll" /* ENROLL */:
|
1784 | return this._finalizeEnroll(auth, session.credential, displayName);
|
1785 | case "signin" /* SIGN_IN */:
|
1786 | return this._finalizeSignIn(auth, session.credential);
|
1787 | default:
|
1788 | return debugFail('unexpected MultiFactorSessionType');
|
1789 | }
|
1790 | };
|
1791 | return MultiFactorAssertionImpl;
|
1792 | }());
|
1793 |
|
1794 | /**
|
1795 | * {@inheritdoc PhoneMultiFactorAssertion}
|
1796 | *
|
1797 | * @public
|
1798 | */
|
1799 | var PhoneMultiFactorAssertionImpl = /** @class */ (function (_super) {
|
1800 | __extends(PhoneMultiFactorAssertionImpl, _super);
|
1801 | function PhoneMultiFactorAssertionImpl(credential) {
|
1802 | var _this = _super.call(this, "phone" /* PHONE */) || this;
|
1803 | _this.credential = credential;
|
1804 | return _this;
|
1805 | }
|
1806 | /** @internal */
|
1807 | PhoneMultiFactorAssertionImpl._fromCredential = function (credential) {
|
1808 | return new PhoneMultiFactorAssertionImpl(credential);
|
1809 | };
|
1810 | /** @internal */
|
1811 | PhoneMultiFactorAssertionImpl.prototype._finalizeEnroll = function (auth, idToken, displayName) {
|
1812 | return finalizeEnrollPhoneMfa(auth, {
|
1813 | idToken: idToken,
|
1814 | displayName: displayName,
|
1815 | phoneVerificationInfo: this.credential._makeVerificationRequest()
|
1816 | });
|
1817 | };
|
1818 | /** @internal */
|
1819 | PhoneMultiFactorAssertionImpl.prototype._finalizeSignIn = function (auth, mfaPendingCredential) {
|
1820 | return finalizeSignInPhoneMfa(auth, {
|
1821 | mfaPendingCredential: mfaPendingCredential,
|
1822 | phoneVerificationInfo: this.credential._makeVerificationRequest()
|
1823 | });
|
1824 | };
|
1825 | return PhoneMultiFactorAssertionImpl;
|
1826 | }(MultiFactorAssertionImpl));
|
1827 | /**
|
1828 | * Provider for generating a {@link PhoneMultiFactorAssertion}.
|
1829 | *
|
1830 | * @public
|
1831 | */
|
1832 | var PhoneMultiFactorGenerator = /** @class */ (function () {
|
1833 | function PhoneMultiFactorGenerator() {
|
1834 | }
|
1835 | /**
|
1836 | * Provides a {@link PhoneMultiFactorAssertion} to confirm ownership of the phone second factor.
|
1837 | *
|
1838 | * @param phoneAuthCredential - A credential provided by {@link PhoneAuthProvider.credential}.
|
1839 | * @returns A {@link PhoneMultiFactorAssertion} which can be used with
|
1840 | * {@link MultiFactorResolver.resolveSignIn}
|
1841 | */
|
1842 | PhoneMultiFactorGenerator.assertion = function (credential) {
|
1843 | return PhoneMultiFactorAssertionImpl._fromCredential(credential);
|
1844 | };
|
1845 | /**
|
1846 | * The identifier of the phone second factor: `phone`.
|
1847 | */
|
1848 | PhoneMultiFactorGenerator.FACTOR_ID = 'phone';
|
1849 | return PhoneMultiFactorGenerator;
|
1850 | }());
|
1851 |
|
1852 | /**
|
1853 | * @license
|
1854 | * Copyright 2021 Google LLC
|
1855 | *
|
1856 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1857 | * you may not use this file except in compliance with the License.
|
1858 | * You may obtain a copy of the License at
|
1859 | *
|
1860 | * http://www.apache.org/licenses/LICENSE-2.0
|
1861 | *
|
1862 | * Unless required by applicable law or agreed to in writing, software
|
1863 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1864 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1865 | * See the License for the specific language governing permissions and
|
1866 | * limitations under the License.
|
1867 | */
|
1868 | /**
|
1869 | * Returns the Auth instance associated with the provided {@link @firebase/app#FirebaseApp}.
|
1870 | * If no instance exists, initializes an Auth instance with platform-specific default dependencies.
|
1871 | *
|
1872 | * @param app - The Firebase App.
|
1873 | *
|
1874 | * @public
|
1875 | */
|
1876 | function getAuth(app) {
|
1877 | if (app === void 0) { app = getApp(); }
|
1878 | var provider = _getProvider(app, 'auth');
|
1879 | if (provider.isInitialized()) {
|
1880 | return provider.getImmediate();
|
1881 | }
|
1882 | return initializeAuth(app, {
|
1883 | popupRedirectResolver: browserPopupRedirectResolver,
|
1884 | persistence: [
|
1885 | indexedDBLocalPersistence,
|
1886 | browserLocalPersistence,
|
1887 | browserSessionPersistence
|
1888 | ]
|
1889 | });
|
1890 | }
|
1891 | registerAuth("Browser" /* BROWSER */);
|
1892 |
|
1893 | /**
|
1894 | * @license
|
1895 | * Copyright 2017 Google LLC
|
1896 | *
|
1897 | * Licensed under the Apache License, Version 2.0 (the "License");
|
1898 | * you may not use this file except in compliance with the License.
|
1899 | * You may obtain a copy of the License at
|
1900 | *
|
1901 | * http://www.apache.org/licenses/LICENSE-2.0
|
1902 | *
|
1903 | * Unless required by applicable law or agreed to in writing, software
|
1904 | * distributed under the License is distributed on an "AS IS" BASIS,
|
1905 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
1906 | * See the License for the specific language governing permissions and
|
1907 | * limitations under the License.
|
1908 | */
|
1909 | // This function should only be called by frameworks (e.g. FirebaseUI-web) to log their usage.
|
1910 | // It is not intended for direct use by developer apps. NO jsdoc here to intentionally leave it out
|
1911 | // of autogenerated documentation pages to reduce accidental misuse.
|
1912 | function addFrameworkForLogging(auth, framework) {
|
1913 | _castAuth(auth)._logFramework(framework);
|
1914 | }
|
1915 |
|
1916 | export { AuthPopup, PhoneAuthProvider, PhoneMultiFactorGenerator, RecaptchaVerifier, addFrameworkForLogging, browserPopupRedirectResolver, getAuth, linkWithPhoneNumber, linkWithPopup, reauthenticateWithPhoneNumber, reauthenticateWithPopup, signInWithPhoneNumber, signInWithPopup, updatePhoneNumber };
|
1917 | //# sourceMappingURL=internal.js.map
|