UNPKG

@firebase/auth

Version:

The Firebase Authenticaton component of the Firebase JS SDK.

1,154 lines (1,136 loc) • 80.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var index = require('./index-ab3e8e37.js'); var tslib = require('tslib'); var util = require('@firebase/util'); var app = require('@firebase/app'); require('@firebase/logger'); require('@firebase/component'); require('node-fetch'); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function _generateEventId(prefix, digits) { if (prefix === void 0) { prefix = ''; } if (digits === void 0) { digits = 10; } var random = ''; for (var i = 0; i < digits; i++) { random += Math.floor(Math.random() * 10); } return prefix + random; } /** * @license * Copyright 2020 Google LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var AuthPopup = /** @class */ (function () { function AuthPopup(window) { this.window = window; this.associatedEvent = null; } AuthPopup.prototype.close = function () { if (this.window) { try { this.window.close(); } catch (e) { } } }; return AuthPopup; }()); /** * @license * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Chooses a popup/redirect resolver to use. This prefers the override (which * is directly passed in), and falls back to the property set on the auth * object. If neither are available, this function errors w/ an argument error. */ function _withDefaultResolver(auth, resolverOverride) { if (resolverOverride) { return index._getInstance(resolverOverride); } index._assert(auth._popupRedirectResolver, auth, "argument-error" /* ARGUMENT_ERROR */); return auth._popupRedirectResolver; } /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var IdpCredential = /** @class */ (function (_super) { tslib.__extends(IdpCredential, _super); function IdpCredential(params) { var _this = _super.call(this, "custom" /* CUSTOM */, "custom" /* CUSTOM */) || this; _this.params = params; return _this; } IdpCredential.prototype._getIdTokenResponse = function (auth) { return index.signInWithIdp(auth, this._buildIdpRequest()); }; IdpCredential.prototype._linkToIdToken = function (auth, idToken) { return index.signInWithIdp(auth, this._buildIdpRequest(idToken)); }; IdpCredential.prototype._getReauthenticationResolver = function (auth) { return index.signInWithIdp(auth, this._buildIdpRequest()); }; IdpCredential.prototype._buildIdpRequest = function (idToken) { var request = { requestUri: this.params.requestUri, sessionId: this.params.sessionId, postBody: this.params.postBody, tenantId: this.params.tenantId, pendingToken: this.params.pendingToken, returnSecureToken: true, returnIdpCredential: true }; if (idToken) { request.idToken = idToken; } return request; }; return IdpCredential; }(index.AuthCredential)); function _signIn(params) { return index._signInWithCredential(params.auth, new IdpCredential(params), params.bypassAuthState); } function _reauth(params) { var auth = params.auth, user = params.user; index._assert(user, auth, "internal-error" /* INTERNAL_ERROR */); return index._reauthenticate(user, new IdpCredential(params), params.bypassAuthState); } function _link(params) { return tslib.__awaiter(this, void 0, void 0, function () { var auth, user; return tslib.__generator(this, function (_a) { auth = params.auth, user = params.user; index._assert(user, auth, "internal-error" /* INTERNAL_ERROR */); return [2 /*return*/, index._link(user, new IdpCredential(params), params.bypassAuthState)]; }); }); } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Popup event manager. Handles the popup's entire lifecycle; listens to auth * events */ var AbstractPopupRedirectOperation = /** @class */ (function () { function AbstractPopupRedirectOperation(auth, filter, resolver, user, bypassAuthState) { if (bypassAuthState === void 0) { bypassAuthState = false; } this.auth = auth; this.resolver = resolver; this.user = user; this.bypassAuthState = bypassAuthState; this.pendingPromise = null; this.eventManager = null; this.filter = Array.isArray(filter) ? filter : [filter]; } AbstractPopupRedirectOperation.prototype.execute = function () { var _this = this; return new Promise(function (resolve, reject) { return tslib.__awaiter(_this, void 0, void 0, function () { var _a, e_1; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: this.pendingPromise = { resolve: resolve, reject: reject }; _b.label = 1; case 1: _b.trys.push([1, 4, , 5]); _a = this; return [4 /*yield*/, this.resolver._initialize(this.auth)]; case 2: _a.eventManager = _b.sent(); return [4 /*yield*/, this.onExecution()]; case 3: _b.sent(); this.eventManager.registerConsumer(this); return [3 /*break*/, 5]; case 4: e_1 = _b.sent(); this.reject(e_1); return [3 /*break*/, 5]; case 5: return [2 /*return*/]; } }); }); }); }; AbstractPopupRedirectOperation.prototype.onAuthEvent = function (event) { return tslib.__awaiter(this, void 0, void 0, function () { var urlResponse, sessionId, postBody, tenantId, error, type, params, _a, e_2; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: urlResponse = event.urlResponse, sessionId = event.sessionId, postBody = event.postBody, tenantId = event.tenantId, error = event.error, type = event.type; if (error) { this.reject(error); return [2 /*return*/]; } params = { auth: this.auth, requestUri: urlResponse, sessionId: sessionId, tenantId: tenantId || undefined, postBody: postBody || undefined, user: this.user, bypassAuthState: this.bypassAuthState }; _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); _a = this.resolve; return [4 /*yield*/, this.getIdpTask(type)(params)]; case 2: _a.apply(this, [_b.sent()]); return [3 /*break*/, 4]; case 3: e_2 = _b.sent(); this.reject(e_2); return [3 /*break*/, 4]; case 4: return [2 /*return*/]; } }); }); }; AbstractPopupRedirectOperation.prototype.onError = function (error) { this.reject(error); }; AbstractPopupRedirectOperation.prototype.getIdpTask = function (type) { switch (type) { case "signInViaPopup" /* SIGN_IN_VIA_POPUP */: case "signInViaRedirect" /* SIGN_IN_VIA_REDIRECT */: return _signIn; case "linkViaPopup" /* LINK_VIA_POPUP */: case "linkViaRedirect" /* LINK_VIA_REDIRECT */: return _link; case "reauthViaPopup" /* REAUTH_VIA_POPUP */: case "reauthViaRedirect" /* REAUTH_VIA_REDIRECT */: return _reauth; default: index._fail(this.auth, "internal-error" /* INTERNAL_ERROR */); } }; AbstractPopupRedirectOperation.prototype.resolve = function (cred) { index.debugAssert(this.pendingPromise, 'Pending promise was never set'); this.pendingPromise.resolve(cred); this.unregisterAndCleanUp(); }; AbstractPopupRedirectOperation.prototype.reject = function (error) { index.debugAssert(this.pendingPromise, 'Pending promise was never set'); this.pendingPromise.reject(error); this.unregisterAndCleanUp(); }; AbstractPopupRedirectOperation.prototype.unregisterAndCleanUp = function () { if (this.eventManager) { this.eventManager.unregisterConsumer(this); } this.pendingPromise = null; this.cleanUp(); }; return AbstractPopupRedirectOperation; }()); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var PENDING_REDIRECT_KEY = 'pendingRedirect'; // We only get one redirect outcome for any one auth, so just store it // in here. var redirectOutcomeMap = new Map(); var RedirectAction = /** @class */ (function (_super) { tslib.__extends(RedirectAction, _super); function RedirectAction(auth, resolver, bypassAuthState) { if (bypassAuthState === void 0) { bypassAuthState = false; } var _this = _super.call(this, auth, [ "signInViaRedirect" /* SIGN_IN_VIA_REDIRECT */, "linkViaRedirect" /* LINK_VIA_REDIRECT */, "reauthViaRedirect" /* REAUTH_VIA_REDIRECT */, "unknown" /* UNKNOWN */ ], resolver, undefined, bypassAuthState) || this; _this.eventId = null; return _this; } /** * Override the execute function; if we already have a redirect result, then * just return it. */ RedirectAction.prototype.execute = function () { return tslib.__awaiter(this, void 0, void 0, function () { var readyOutcome, hasPendingRedirect, result_1, _a, e_1; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: readyOutcome = redirectOutcomeMap.get(this.auth._key()); if (!!readyOutcome) return [3 /*break*/, 8]; _b.label = 1; case 1: _b.trys.push([1, 6, , 7]); return [4 /*yield*/, _getAndClearPendingRedirectStatus(this.resolver, this.auth)]; case 2: hasPendingRedirect = _b.sent(); if (!hasPendingRedirect) return [3 /*break*/, 4]; return [4 /*yield*/, _super.prototype.execute.call(this)]; case 3: _a = _b.sent(); return [3 /*break*/, 5]; case 4: _a = null; _b.label = 5; case 5: result_1 = _a; readyOutcome = function () { return Promise.resolve(result_1); }; return [3 /*break*/, 7]; case 6: e_1 = _b.sent(); readyOutcome = function () { return Promise.reject(e_1); }; return [3 /*break*/, 7]; case 7: redirectOutcomeMap.set(this.auth._key(), readyOutcome); _b.label = 8; case 8: // If we're not bypassing auth state, the ready outcome should be set to // null. if (!this.bypassAuthState) { redirectOutcomeMap.set(this.auth._key(), function () { return Promise.resolve(null); }); } return [2 /*return*/, readyOutcome()]; } }); }); }; RedirectAction.prototype.onAuthEvent = function (event) { return tslib.__awaiter(this, void 0, void 0, function () { var user; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: if (event.type === "signInViaRedirect" /* SIGN_IN_VIA_REDIRECT */) { return [2 /*return*/, _super.prototype.onAuthEvent.call(this, event)]; } else if (event.type === "unknown" /* UNKNOWN */) { // This is a sentinel value indicating there's no pending redirect this.resolve(null); return [2 /*return*/]; } if (!event.eventId) return [3 /*break*/, 2]; return [4 /*yield*/, this.auth._redirectUserForId(event.eventId)]; case 1: user = _a.sent(); if (user) { this.user = user; return [2 /*return*/, _super.prototype.onAuthEvent.call(this, event)]; } else { this.resolve(null); } _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; RedirectAction.prototype.onExecution = function () { return tslib.__awaiter(this, void 0, void 0, function () { return tslib.__generator(this, function (_a) { return [2 /*return*/]; }); }); }; RedirectAction.prototype.cleanUp = function () { }; return RedirectAction; }(AbstractPopupRedirectOperation)); function _getAndClearPendingRedirectStatus(resolver, auth) { return tslib.__awaiter(this, void 0, void 0, function () { var key, persistence, hasPendingRedirect; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: key = pendingRedirectKey(auth); persistence = resolverPersistence(resolver); return [4 /*yield*/, persistence._isAvailable()]; case 1: if (!(_a.sent())) { return [2 /*return*/, false]; } return [4 /*yield*/, persistence._get(key)]; case 2: hasPendingRedirect = (_a.sent()) === 'true'; return [4 /*yield*/, persistence._remove(key)]; case 3: _a.sent(); return [2 /*return*/, hasPendingRedirect]; } }); }); } function _clearRedirectOutcomes() { redirectOutcomeMap.clear(); } function _overrideRedirectResult(auth, result) { redirectOutcomeMap.set(auth._key(), result); } function resolverPersistence(resolver) { return index._getInstance(resolver._redirectPersistence); } function pendingRedirectKey(auth) { return index._persistenceKeyName(PENDING_REDIRECT_KEY, auth.config.apiKey, auth.name); } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function _getRedirectResult(auth, resolverExtern, bypassAuthState) { if (bypassAuthState === void 0) { bypassAuthState = false; } return tslib.__awaiter(this, void 0, void 0, function () { var authInternal, resolver, action, result; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: authInternal = index._castAuth(auth); resolver = _withDefaultResolver(authInternal, resolverExtern); action = new RedirectAction(authInternal, resolver, bypassAuthState); return [4 /*yield*/, action.execute()]; case 1: result = _a.sent(); if (!(result && !bypassAuthState)) return [3 /*break*/, 4]; delete result.user._redirectEventId; return [4 /*yield*/, authInternal._persistUserIfCurrent(result.user)]; case 2: _a.sent(); return [4 /*yield*/, authInternal._setRedirectUser(null, resolverExtern)]; case 3: _a.sent(); _a.label = 4; case 4: return [2 /*return*/, result]; } }); }); } var STORAGE_AVAILABLE_KEY = '__sak'; /** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // There are two different browser persistence types: local and session. // Both have the same implementation but use a different underlying storage // object. var BrowserPersistenceClass = /** @class */ (function () { function BrowserPersistenceClass(storageRetriever, type) { this.storageRetriever = storageRetriever; this.type = type; } BrowserPersistenceClass.prototype._isAvailable = function () { try { if (!this.storage) { return Promise.resolve(false); } this.storage.setItem(STORAGE_AVAILABLE_KEY, '1'); this.storage.removeItem(STORAGE_AVAILABLE_KEY); return Promise.resolve(true); } catch (_a) { return Promise.resolve(false); } }; BrowserPersistenceClass.prototype._set = function (key, value) { this.storage.setItem(key, JSON.stringify(value)); return Promise.resolve(); }; BrowserPersistenceClass.prototype._get = function (key) { var json = this.storage.getItem(key); return Promise.resolve(json ? JSON.parse(json) : null); }; BrowserPersistenceClass.prototype._remove = function (key) { this.storage.removeItem(key); return Promise.resolve(); }; Object.defineProperty(BrowserPersistenceClass.prototype, "storage", { get: function () { return this.storageRetriever(); }, enumerable: false, configurable: true }); return BrowserPersistenceClass; }()); /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var BrowserSessionPersistence = /** @class */ (function (_super) { tslib.__extends(BrowserSessionPersistence, _super); function BrowserSessionPersistence() { return _super.call(this, function () { return window.sessionStorage; }, "SESSION" /* SESSION */) || this; } BrowserSessionPersistence.prototype._addListener = function (_key, _listener) { // Listeners are not supported for session storage since it cannot be shared across windows return; }; BrowserSessionPersistence.prototype._removeListener = function (_key, _listener) { // Listeners are not supported for session storage since it cannot be shared across windows return; }; BrowserSessionPersistence.type = 'SESSION'; return BrowserSessionPersistence; }(BrowserPersistenceClass)); /** * An implementation of {@link Persistence} of `SESSION` using `sessionStorage` * for the underlying storage. * * @public */ var browserSessionPersistence = BrowserSessionPersistence; /** * @license * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * URL for Authentication widget which will initiate the OAuth handshake * * @internal */ var WIDGET_PATH = '__/auth/handler'; /** * URL for emulated environment * * @internal */ var EMULATOR_WIDGET_PATH = 'emulator/auth/handler'; function _getRedirectUrl(auth, provider, authType, redirectUrl, eventId, additionalParams) { index._assert(auth.config.authDomain, auth, "auth-domain-config-required" /* MISSING_AUTH_DOMAIN */); index._assert(auth.config.apiKey, auth, "invalid-api-key" /* INVALID_API_KEY */); var params = { apiKey: auth.config.apiKey, appName: auth.name, authType: authType, redirectUrl: redirectUrl, v: app.SDK_VERSION, eventId: eventId }; if (provider instanceof index.FederatedAuthProvider) { provider.setDefaultLanguage(auth.languageCode); params.providerId = provider.providerId || ''; if (!util.isEmpty(provider.getCustomParameters())) { params.customParameters = JSON.stringify(provider.getCustomParameters()); } // TODO set additionalParams from the provider as well? for (var _i = 0, _a = Object.entries(additionalParams || {}); _i < _a.length; _i++) { var _b = _a[_i], key = _b[0], value = _b[1]; params[key] = value; } } if (provider instanceof index.BaseOAuthProvider) { var scopes = provider.getScopes().filter(function (scope) { return scope !== ''; }); if (scopes.length > 0) { params.scopes = scopes.join(','); } } if (auth.tenantId) { params.tid = auth.tenantId; } // TODO: maybe set eid as endipointId // TODO: maybe set fw as Frameworks.join(",") var paramsDict = params; for (var _c = 0, _d = Object.keys(paramsDict); _c < _d.length; _c++) { var key = _d[_c]; if (paramsDict[key] === undefined) { delete paramsDict[key]; } } return getHandlerBase(auth) + "?" + util.querystring(paramsDict).slice(1); } function getHandlerBase(_a) { var config = _a.config; if (!config.emulator) { return "https://" + config.authDomain + "/" + WIDGET_PATH; } return index._emulatorUrl(config, EMULATOR_WIDGET_PATH); } /** * @license * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function _cordovaWindow() { return window; } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function _getProjectConfig(auth, request) { if (request === void 0) { request = {}; } return tslib.__awaiter(this, void 0, void 0, function () { return tslib.__generator(this, function (_a) { return [2 /*return*/, index._performApiRequest(auth, "GET" /* GET */, "/v1/projects" /* GET_PROJECT_CONFIG */, request)]; }); }); } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * How long to wait after the app comes back into focus before concluding that * the user closed the sign in tab. */ var REDIRECT_TIMEOUT_MS = 2000; /** * Generates the URL for the OAuth handler. */ function _generateHandlerUrl(auth, event, provider) { var _a; return tslib.__awaiter(this, void 0, void 0, function () { var BuildInfo, sessionDigest, additionalParams; return tslib.__generator(this, function (_b) { switch (_b.label) { case 0: BuildInfo = _cordovaWindow().BuildInfo; index.debugAssert(event.sessionId, 'AuthEvent did not contain a session ID'); return [4 /*yield*/, computeSha256(event.sessionId)]; case 1: sessionDigest = _b.sent(); additionalParams = {}; if (index._isIOS()) { // iOS app identifier additionalParams['ibi'] = BuildInfo.packageName; } else if (index._isAndroid()) { // Android app identifier additionalParams['apn'] = BuildInfo.packageName; } else { index._fail(auth, "operation-not-supported-in-this-environment" /* OPERATION_NOT_SUPPORTED */); } // Add the display name if available if (BuildInfo.displayName) { additionalParams['appDisplayName'] = BuildInfo.displayName; } // Attached the hashed session ID additionalParams['sessionId'] = sessionDigest; return [2 /*return*/, _getRedirectUrl(auth, provider, event.type, undefined, (_a = event.eventId) !== null && _a !== void 0 ? _a : undefined, additionalParams)]; } }); }); } /** * Validates that this app is valid for this project configuration */ function _validateOrigin(auth) { return tslib.__awaiter(this, void 0, void 0, function () { var BuildInfo, request; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: BuildInfo = _cordovaWindow().BuildInfo; request = {}; if (index._isIOS()) { request.iosBundleId = BuildInfo.packageName; } else if (index._isAndroid()) { request.androidPackageName = BuildInfo.packageName; } else { index._fail(auth, "operation-not-supported-in-this-environment" /* OPERATION_NOT_SUPPORTED */); } // Will fail automatically if package name is not authorized return [4 /*yield*/, _getProjectConfig(auth, request)]; case 1: // Will fail automatically if package name is not authorized _a.sent(); return [2 /*return*/]; } }); }); } function _performRedirect(handlerUrl) { // Get the cordova plugins var cordova = _cordovaWindow().cordova; return new Promise(function (resolve) { cordova.plugins.browsertab.isAvailable(function (browserTabIsAvailable) { var iabRef = null; if (browserTabIsAvailable) { cordova.plugins.browsertab.openUrl(handlerUrl); } else { // TODO: Return the inappbrowser ref that's returned from the open call iabRef = cordova.InAppBrowser.open(handlerUrl, index._isIOS7Or8() ? '_blank' : '_system', 'location=yes'); } resolve(iabRef); }); }); } /** * This function waits for app activity to be seen before resolving. It does * this by attaching listeners to various dom events. Once the app is determined * to be visible, this promise resolves. AFTER that resolution, the listeners * are detached and any browser tabs left open will be closed. */ function _waitForAppResume(auth, eventListener, iabRef) { return tslib.__awaiter(this, void 0, void 0, function () { var cordova, cleanup; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: cordova = _cordovaWindow().cordova; cleanup = function () { }; _a.label = 1; case 1: _a.trys.push([1, , 3, 4]); return [4 /*yield*/, new Promise(function (resolve, reject) { var onCloseTimer = null; // DEFINE ALL THE CALLBACKS ===== function authEventSeen() { var _a; // Auth event was detected. Resolve this promise and close the extra // window if it's still open. resolve(); var closeBrowserTab = (_a = cordova.plugins.browsertab) === null || _a === void 0 ? void 0 : _a.close; if (typeof closeBrowserTab === 'function') { closeBrowserTab(); } // Close inappbrowser emebedded webview in iOS7 and 8 case if still // open. if (typeof (iabRef === null || iabRef === void 0 ? void 0 : iabRef.close) === 'function') { iabRef.close(); } } function resumed() { if (onCloseTimer) { // This code already ran; do not rerun. return; } onCloseTimer = window.setTimeout(function () { // Wait two seeconds after resume then reject. reject(index._createError(auth, "redirect-cancelled-by-user" /* REDIRECT_CANCELLED_BY_USER */)); }, REDIRECT_TIMEOUT_MS); } function visibilityChanged() { if ((document === null || document === void 0 ? void 0 : document.visibilityState) === 'visible') { resumed(); } } // ATTACH ALL THE LISTENERS ===== // Listen for the auth event eventListener.addPassiveListener(authEventSeen); // Listen for resume and visibility events document.addEventListener('resume', resumed, false); if (index._isAndroid()) { document.addEventListener('visibilitychange', visibilityChanged, false); } // SETUP THE CLEANUP FUNCTION ===== cleanup = function () { eventListener.removePassiveListener(authEventSeen); document.removeEventListener('resume', resumed, false); document.removeEventListener('visibilitychange', visibilityChanged, false); if (onCloseTimer) { window.clearTimeout(onCloseTimer); } }; })]; case 2: _a.sent(); return [3 /*break*/, 4]; case 3: cleanup(); return [7 /*endfinally*/]; case 4: return [2 /*return*/]; } }); }); } /** * Checks the configuration of the Cordova environment. This has no side effect * if the configuration is correct; otherwise it throws an error with the * missing plugin. */ function _checkCordovaConfiguration(auth) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; var win = _cordovaWindow(); // Check all dependencies installed. // https://github.com/nordnet/cordova-universal-links-plugin // Note that cordova-universal-links-plugin has been abandoned. // A fork with latest fixes is available at: // https://www.npmjs.com/package/cordova-universal-links-plugin-fix index._assert(typeof ((_a = win === null || win === void 0 ? void 0 : win.universalLinks) === null || _a === void 0 ? void 0 : _a.subscribe) === 'function', auth, "invalid-cordova-configuration" /* INVALID_CORDOVA_CONFIGURATION */, { missingPlugin: 'cordova-universal-links-plugin-fix' }); // https://www.npmjs.com/package/cordova-plugin-buildinfo index._assert(typeof ((_b = win === null || win === void 0 ? void 0 : win.BuildInfo) === null || _b === void 0 ? void 0 : _b.packageName) !== 'undefined', auth, "invalid-cordova-configuration" /* INVALID_CORDOVA_CONFIGURATION */, { missingPlugin: 'cordova-plugin-buildInfo' }); // https://github.com/google/cordova-plugin-browsertab index._assert(typeof ((_e = (_d = (_c = win === null || win === void 0 ? void 0 : win.cordova) === null || _c === void 0 ? void 0 : _c.plugins) === null || _d === void 0 ? void 0 : _d.browsertab) === null || _e === void 0 ? void 0 : _e.openUrl) === 'function', auth, "invalid-cordova-configuration" /* INVALID_CORDOVA_CONFIGURATION */, { missingPlugin: 'cordova-plugin-browsertab' }); index._assert(typeof ((_h = (_g = (_f = win === null || win === void 0 ? void 0 : win.cordova) === null || _f === void 0 ? void 0 : _f.plugins) === null || _g === void 0 ? void 0 : _g.browsertab) === null || _h === void 0 ? void 0 : _h.isAvailable) === 'function', auth, "invalid-cordova-configuration" /* INVALID_CORDOVA_CONFIGURATION */, { missingPlugin: 'cordova-plugin-browsertab' }); // https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/ index._assert(typeof ((_k = (_j = win === null || win === void 0 ? void 0 : win.cordova) === null || _j === void 0 ? void 0 : _j.InAppBrowser) === null || _k === void 0 ? void 0 : _k.open) === 'function', auth, "invalid-cordova-configuration" /* INVALID_CORDOVA_CONFIGURATION */, { missingPlugin: 'cordova-plugin-inappbrowser' }); } /** * Computes the SHA-256 of a session ID. The SubtleCrypto interface is only * available in "secure" contexts, which covers Cordova (which is served on a file * protocol). */ function computeSha256(sessionId) { return tslib.__awaiter(this, void 0, void 0, function () { var bytes, buf, arr; return tslib.__generator(this, function (_a) { switch (_a.label) { case 0: bytes = stringToArrayBuffer(sessionId); return [4 /*yield*/, crypto.subtle.digest('SHA-256', bytes)]; case 1: buf = _a.sent(); arr = Array.from(new Uint8Array(buf)); return [2 /*return*/, arr.map(function (num) { return num.toString(16).padStart(2, '0'); }).join('')]; } }); }); } function stringToArrayBuffer(str) { // This function is only meant to deal with an ASCII charset and makes // certain simplifying assumptions. index.debugAssert(/[0-9a-zA-Z]+/.test(str), 'Can only convert alpha-numeric strings'); if (typeof TextEncoder !== 'undefined') { return new TextEncoder().encode(str); } var buff = new ArrayBuffer(str.length); var view = new Uint8Array(buff); for (var i = 0; i < str.length; i++) { view[i] = str.charCodeAt(i); } return view; } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // The amount of time to store the UIDs of seen events; this is // set to 10 min by default var EVENT_DUPLICATION_CACHE_DURATION_MS = 10 * 60 * 1000; var AuthEventManager = /** @class */ (function () { function AuthEventManager(auth) { this.auth = auth; this.cachedEventUids = new Set(); this.consumers = new Set(); this.queuedRedirectEvent = null; this.hasHandledPotentialRedirect = false; this.lastProcessedEventTime = Date.now(); } AuthEventManager.prototype.registerConsumer = function (authEventConsumer) { this.consumers.add(authEventConsumer); if (this.queuedRedirectEvent && this.isEventForConsumer(this.queuedRedirectEvent, authEventConsumer)) { this.sendToConsumer(this.queuedRedirectEvent, authEventConsumer); this.saveEventToCache(this.queuedRedirectEvent); this.queuedRedirectEvent = null; } }; AuthEventManager.prototype.unregisterConsumer = function (authEventConsumer) { this.consumers.delete(authEventConsumer); }; AuthEventManager.prototype.onEvent = function (event) { var _this = this; // Check if the event has already been handled if (this.hasEventBeenHandled(event)) { return false; } var handled = false; this.consumers.forEach(function (consumer) { if (_this.isEventForConsumer(event, consumer)) { handled = true; _this.sendToConsumer(event, consumer); _this.saveEventToCache(event); } }); if (this.hasHandledPotentialRedirect || !isRedirectEvent(event)) { // If we've already seen a redirect before, or this is a popup event, // bail now return handled; } this.hasHandledPotentialRedirect = true; // If the redirect wasn't handled, hang on to it if (!handled) { this.queuedRedirectEvent = event; handled = true; } return handled; }; AuthEventManager.prototype.sendToConsumer = function (event, consumer) { var _a; if (event.error && !isNullRedirectEvent(event)) { var code = ((_a = event.error.code) === null || _a === void 0 ? void 0 : _a.split('auth/')[1]) || "internal-error" /* INTERNAL_ERROR */; consumer.onError(index._createError(this.auth, code)); } else { consumer.onAuthEvent(event); } }; AuthEventManager.prototype.isEventForConsumer = function (event, consumer) { var eventIdMatches = consumer.eventId === null || (!!event.eventId && event.eventId === consumer.eventId); return consumer.filter.includes(event.type) && eventIdMatches; }; AuthEventManager.prototype.hasEventBeenHandled = function (event) { if (Date.now() - this.lastProcessedEventTime >= EVENT_DUPLICATION_CACHE_DURATION_MS) { this.cachedEventUids.clear(); } return this.cachedEventUids.has(eventUid(event)); }; AuthEventManager.prototype.saveEventToCache = function (event) { this.cachedEventUids.add(eventUid(event)); this.lastProcessedEventTime = Date.now(); }; return AuthEventManager; }()); function eventUid(e) { return [e.type, e.eventId, e.sessionId, e.tenantId].filter(function (v) { return v; }).join('-'); } function isNullRedirectEvent(_a) { var type = _a.type, error = _a.error; return (type === "unknown" /* UNKNOWN */ && (error === null || error === void 0 ? void 0 : error.code) === "auth/" + "no-auth-event" /* NO_AUTH_EVENT */); } function isRedirectEvent(event) { switch (event.type) { case "signInViaRedirect" /* SIGN_IN_VIA_REDIRECT */: case "linkViaRedirect" /* LINK_VIA_REDIRECT */: case "reauthViaRedirect" /* REAUTH_VIA_REDIRECT */: return true; case "unknown" /* UNKNOWN */: return isNullRedirectEvent(event); default: return false; } } /** * @license * Copyright 2020 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function _iframeCannotSyncWebStorage() { var ua = util.getUA(); return index._isSafari(ua) || index._isIOS(ua); } // The polling period in case events are not supported var _POLLING_INTERVAL_MS = 1000; // The IE 10 localStorage cross tab synchronization delay in milliseconds var IE10_LOCAL_STORAGE_SYNC_DELAY = 10; var BrowserLocalPersistence = /** @class */ (function (_super) { tslib.__extends(BrowserLocalPersistence, _super); function BrowserLocalPersistence() { var _this = _super.call(this, function () { return window.localStorage; }, "LOCAL" /* LOCAL */) || this; _this.boundEventHandler = function (event, poll) { return _this.onStorageEvent(event, poll); }; _this.listeners = {}; _this.localCache = {}; // setTimeout return value is platform specific // eslint-disable-next-line @typescript-eslint/no-explicit-any _this.pollTimer = null; // Safari or iOS browser and embedded in an iframe. _this.safariLocalStorageNotSynced = _iframeCannotSyncWebStorage() && index._isIframe(); // Whether to use polling instead of depending on window events _this.fallbackToPolling = index._isMobileBrowser(); _this._shouldAllowMigration = true; return _this; } BrowserLocalPersistence.prototype.forAllChangedKeys = function (cb) { // Check all keys with listeners on them. for (var _i = 0, _a = Object.keys(this.listeners); _i < _a.length; _i++) { var key = _a[_i]; // Get value from localStorage. var newValue = this.storage.getItem(key); var oldValue = this.localCache[key]; // If local map value does not match, trigger listener with storage event. // Differentiate this simulated event from the real storage event. if (newValue !== oldValue) { cb(key, oldValue, newValue); } } }; BrowserLocalPersistence.prototype.onSt