UNPKG

voluptasmollitia

Version:
174 lines (156 loc) 5.09 kB
/** * @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. */ import * as impl from '@firebase/auth-exp/internal'; import { getUA, isBrowserExtension, isReactNative, isNode, isIE, isIndexedDBAvailable } from '@firebase/util'; declare global { interface Document { documentMode?: number; } } const CORDOVA_ONDEVICEREADY_TIMEOUT_MS = 1000; function _getCurrentScheme(): string | null { return self?.location?.protocol || null; } /** * @return {boolean} Whether the current environment is http or https. */ function _isHttpOrHttps(): boolean { return _getCurrentScheme() === 'http:' || _getCurrentScheme() === 'https:'; } /** * @param {?string=} ua The user agent. * @return {boolean} Whether the app is rendered in a mobile iOS or Android * Cordova environment. */ export function _isAndroidOrIosCordovaScheme(ua: string = getUA()): boolean { return !!( (_getCurrentScheme() === 'file:' || _getCurrentScheme() === 'ionic:') && ua.toLowerCase().match(/iphone|ipad|ipod|android/) ); } /** * @return {boolean} Whether the environment is a native environment, where * CORS checks do not apply. */ function _isNativeEnvironment(): boolean { return isReactNative() || isNode(); } /** * Checks whether the user agent is IE11. * @return {boolean} True if it is IE11. */ function _isIe11(): boolean { return isIE() && document?.documentMode === 11; } /** * Checks whether the user agent is Edge. * @param {string} userAgent The browser user agent string. * @return {boolean} True if it is Edge. */ function _isEdge(ua: string = getUA()): boolean { return /Edge\/\d+/.test(ua); } /** * @param {?string=} opt_userAgent The navigator user agent. * @return {boolean} Whether local storage is not synchronized between an iframe * and a popup of the same domain. */ function _isLocalStorageNotSynchronized(ua: string = getUA()): boolean { return _isIe11() || _isEdge(ua); } /** @return {boolean} Whether web storage is supported. */ export function _isWebStorageSupported(): boolean { try { const storage = self.localStorage; const key = impl._generateEventId(); if (storage) { // setItem will throw an exception if we cannot access WebStorage (e.g., // Safari in private mode). storage['setItem'](key, '1'); storage['removeItem'](key); // For browsers where iframe web storage does not synchronize with a popup // of the same domain, indexedDB is used for persistent storage. These // browsers include IE11 and Edge. // Make sure it is supported (IE11 and Edge private mode does not support // that). if (_isLocalStorageNotSynchronized()) { // In such browsers, if indexedDB is not supported, an iframe cannot be // notified of the popup sign in result. return isIndexedDBAvailable(); } return true; } } catch (e) { // localStorage is not available from a worker. Test availability of // indexedDB. return _isWorker() && isIndexedDBAvailable(); } return false; } /** * @param {?Object=} global The optional global scope. * @return {boolean} Whether current environment is a worker. */ export function _isWorker(): boolean { // WorkerGlobalScope only defined in worker environment. return ( typeof global !== 'undefined' && 'WorkerGlobalScope' in global && 'importScripts' in global ); } export function _isPopupRedirectSupported(): boolean { return ( (_isHttpOrHttps() || isBrowserExtension() || _isAndroidOrIosCordovaScheme()) && // React Native with remote debugging reports its location.protocol as // http. !_isNativeEnvironment() && // Local storage has to be supported for browser popup and redirect // operations to work. _isWebStorageSupported() && // DOM, popups and redirects are not supported within a worker. !_isWorker() ); } /** Quick check that indicates the platform *may* be Cordova */ export function _isLikelyCordova(): boolean { return _isAndroidOrIosCordovaScheme() && typeof document !== 'undefined'; } export async function _isCordova(): Promise<boolean> { if (!_isLikelyCordova()) { return false; } return new Promise(resolve => { const timeoutId = setTimeout(() => { // We've waited long enough; the telltale Cordova event didn't happen resolve(false); }, CORDOVA_ONDEVICEREADY_TIMEOUT_MS); document.addEventListener('deviceready', () => { clearTimeout(timeoutId); resolve(true); }); }); }