From 67e63d7a9ad58e4942106e02ab3a02bdd799922e Mon Sep 17 00:00:00 2001 From: Xin Li Date: Tue, 23 Jun 2020 12:18:10 -0700 Subject: [PATCH 01/11] release updates on accountchooser.com warnings & fix some issues --- README.md | 28 +- demo/public/app.js | 2 +- javascript/testing/auth.js | 4 +- javascript/testing/mockhelper.js | 4 +- javascript/utils/acclient.js | 8 +- javascript/widgets/config.js | 19 +- javascript/widgets/config_test.js | 28 + javascript/widgets/firebaseuihandler.js | 2 +- javascript/widgets/handler/common.js | 8 + javascript/widgets/handler/common_test.js | 56 ++ javascript/widgets/handler/testhelper.js | 4 +- package-lock.json | 992 +++++----------------- package.json | 2 +- stylesheet/firebase-ui.css | 1 + 14 files changed, 364 insertions(+), 794 deletions(-) diff --git a/README.md b/README.md index 34464cef..915c1a66 100644 --- a/README.md +++ b/README.md @@ -139,12 +139,10 @@ FirebaseUI includes the following flows: *"One account per email address"* setting is enabled in the [Firebase console](https://console.firebase.google.com). This setting is enabled by default.) -6. [Account Chooser](https://www.accountchooser.com/learnmore.html?lang=en) for -remembering emails -7. Integration with +6. Integration with [one-tap sign-up](https://developers.google.com/identity/one-tap/web/) -8. Ability to upgrade anonymous users through sign-in/sign-up. -9. Sign-in as a guest +7. Ability to upgrade anonymous users through sign-in/sign-up. +8. Sign-in as a guest ### Configuring sign-in providers @@ -364,8 +362,11 @@ FirebaseUI supports the following configuration parameters. The Credential Helper to use. See Credential Helper.
- Default: + Default (before July 31st, 2020): firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM +
+ Default (after July 31st, 2020): + firebaseui.auth.CredentialHelper.NONE @@ -458,6 +459,9 @@ FirebaseUI supports the following credential helpers: - [accountchooser.com](https://www.accountchooser.com/learnmore.html) #### accountchooser.com +(`accountchooser.com` will be operating in "universal opt-out" mode +starting July 31st, 2020, it should no longer be used as a `CredentialHelper`. +Learn more at https://accountchooser.net/developers.) When [accountchooser.com](https://www.accountchooser.com/learnmore.html) is enabled (enabled by default), upon signing in or @@ -526,11 +530,11 @@ being rendered after the user signs out. To see FirebaseUI in action with one-tap sign-up, check out the FirebaseUI [demo app](https://fir-ui-demo-84a6c.firebaseapp.com/). -|Credential Helper |Value | -|------------------|------------------------------------------------------| -|accountchooser.com|`firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM`| -|One-tap sign-up |`firebaseui.auth.CredentialHelper.GOOGLE_YOLO` | -|None (disable) |`firebaseui.auth.CredentialHelper.NONE` | +|Credential Helper |Value | +|----------------------------------|------------------------------------------------------| +|accountchooser.com (deprecated) |`firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM`| +|One-tap sign-up |`firebaseui.auth.CredentialHelper.GOOGLE_YOLO` | +|None (disable) |`firebaseui.auth.CredentialHelper.NONE` | ### Available providers @@ -1274,7 +1278,7 @@ FirebaseUI is displayed. document.getElementById('loader').style.display = 'none'; } }, - credentialHelper: firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM, + credentialHelper: firebaseui.auth.CredentialHelper.NONE, // Query parameter name for mode. queryParameterForWidgetMode: 'mode', // Query parameter name for sign in success url. diff --git a/demo/public/app.js b/demo/public/app.js index 745a2027..9a127c26 100644 --- a/demo/public/app.js +++ b/demo/public/app.js @@ -83,7 +83,7 @@ function getUiConfig() { 'privacyPolicyUrl': 'https://www.google.com', 'credentialHelper': CLIENT_ID && CLIENT_ID != 'YOUR_OAUTH_CLIENT_ID' ? firebaseui.auth.CredentialHelper.GOOGLE_YOLO : - firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM + firebaseui.auth.CredentialHelper.NONE }; } diff --git a/javascript/testing/auth.js b/javascript/testing/auth.js index a6f4bdad..6b1b2aa5 100644 --- a/javascript/testing/auth.js +++ b/javascript/testing/auth.js @@ -115,7 +115,7 @@ class FakeAuthClient extends MockHelper { */ onAuthStateChanged(nextOrObserver, opt_error, opt_completed) { // Simplified version of the observer for testing purpose only. - var observer = (goog.isFunction(nextOrObserver) && nextOrObserver) || + var observer = (typeof nextOrObserver === 'function' && nextOrObserver) || nextOrObserver['next']; if (!observer) { throw 'onAuthStateChanged must be called with an Observer or up to three ' + @@ -154,7 +154,7 @@ class FakeAuthClient extends MockHelper { */ onIdTokenChanged(nextOrObserver, opt_error, opt_completed) { // Simplified version of the observer for testing purpose only. - var observer = (goog.isFunction(nextOrObserver) && nextOrObserver) || + var observer = (typeof nextOrObserver === 'function' && nextOrObserver) || nextOrObserver['next']; if (!observer) { throw 'onIdTokenChanged must be called with an Observer or up to three ' + diff --git a/javascript/testing/mockhelper.js b/javascript/testing/mockhelper.js index 54594965..13cf9887 100644 --- a/javascript/testing/mockhelper.js +++ b/javascript/testing/mockhelper.js @@ -196,13 +196,13 @@ class MockHelper extends Disposable { // Resolve API promise if not already resolved. resolveAssert(); if (error) { - if (goog.isFunction(error)) { + if (typeof error === 'function') { req['reject'](error()); } else { req['reject'](error); } } else { - if (goog.isFunction(resp)) { + if (typeof resp === 'function') { req['resolve'](resp()); } else { req['resolve'](resp); diff --git a/javascript/utils/acclient.js b/javascript/utils/acclient.js index 3890770e..a31ee784 100644 --- a/javascript/utils/acclient.js +++ b/javascript/utils/acclient.js @@ -231,7 +231,7 @@ firebaseui.auth.acClient.DummyApi = class { * Triggers the onEmpty callback. */ fireOnEmpty() { - if (goog.isFunction(this.config_['callbacks']['empty'])) { + if (typeof this.config_['callbacks']['empty'] === 'function') { this.config_['callbacks']['empty'](); } } @@ -245,7 +245,7 @@ firebaseui.auth.acClient.DummyApi = class { * @param {Object=} opt_config The optional client configuration. */ store(accounts, opt_config) { - if (goog.isFunction(this.config_['callbacks']['store'])) { + if (typeof this.config_['callbacks']['store'] === 'function') { this.config_['callbacks']['store']( undefined, firebaseui.auth.acClient.DummyApi.UNAVAILABLE_ERROR_); } @@ -260,7 +260,7 @@ firebaseui.auth.acClient.DummyApi = class { * @param {Object=} opt_config The optional client configuration. */ select(accounts, opt_config) { - if (goog.isFunction(this.config_['callbacks']['select'])) { + if (typeof this.config_['callbacks']['select'] === 'function') { this.config_['callbacks']['select']( undefined, firebaseui.auth.acClient.DummyApi.UNAVAILABLE_ERROR_); } @@ -275,7 +275,7 @@ firebaseui.auth.acClient.DummyApi = class { * @param {Object=} opt_config The optional client configuration. */ update(account, opt_config) { - if (goog.isFunction(this.config_['callbacks']['update'])) { + if (typeof this.config_['callbacks']['update'] === 'function') { this.config_['callbacks']['update']( undefined, firebaseui.auth.acClient.DummyApi.UNAVAILABLE_ERROR_); } diff --git a/javascript/widgets/config.js b/javascript/widgets/config.js index d996fc60..10bd4bbd 100644 --- a/javascript/widgets/config.js +++ b/javascript/widgets/config.js @@ -528,7 +528,7 @@ class Config { 'Privacy Policy URL is missing, the link will not be displayed.'); } if (tosUrl && privacyPolicyUrl) { - if (goog.isFunction(tosUrl)) { + if (typeof tosUrl === 'function') { return /** @type {function()} */ (tosUrl); } else if (typeof tosUrl === 'string') { return () => { @@ -554,7 +554,7 @@ class Config { 'Term of Service URL is missing, the link will not be displayed.'); } if (tosUrl && privacyPolicyUrl) { - if (goog.isFunction(privacyPolicyUrl)) { + if (typeof privacyPolicyUrl === 'function') { return /** @type {function()} */ (privacyPolicyUrl); } else if (typeof privacyPolicyUrl === 'string') { return () => { @@ -769,10 +769,7 @@ class Config { } /** - * TODO: for now, only accountchooser.com is available and all logic related - * to credential helper relies on it, so this method is provided for ease of - * use. It should be removed in the future when FirebaseUI supports several - * credential helpers. + * TODO: Remove during accountchooser.com opt-out period. * @return {boolean} Whether accountchooser.com is enabled. */ isAccountChooserEnabled() { @@ -792,10 +789,16 @@ class Config { return Config.CredentialHelper.NONE; } const credentialHelper = this.config_.get('credentialHelper'); + if (credentialHelper === Config.CredentialHelper.ACCOUNT_CHOOSER_COM) { + log.warning( + 'AccountChooser.com will be operating in "universal opt-out" mode ' + + 'starting July 31st, 2020, ' + + 'it should no longer be used as a CredentialHelper.' + + ' Learn more at https://accountchooser.net/developers'); + } // Make sure the credential helper is valid. for (let key in Config.CredentialHelper) { - if (Config.CredentialHelper[key] == - credentialHelper) { + if (Config.CredentialHelper[key] === credentialHelper) { // Return valid flow. return Config.CredentialHelper[key]; } diff --git a/javascript/widgets/config_test.js b/javascript/widgets/config_test.js index 60d9b593..7ad41516 100644 --- a/javascript/widgets/config_test.js +++ b/javascript/widgets/config_test.js @@ -1488,6 +1488,34 @@ testSuite({ assertArrayEquals([], warningLogMessages); }, + testAccountChooserWarningMessage() { + const expectedWarningMessage = 'AccountChooser.com will be operating ' + + 'in "universal opt-out" mode starting July 31st, 2020, ' + + 'it should no longer be used as a CredentialHelper. ' + + 'Learn more at https://accountchooser.net/developers'; + config.update( + 'credentialHelper', Config.CredentialHelper.ACCOUNT_CHOOSER_COM); + assertEquals( + Config.CredentialHelper.ACCOUNT_CHOOSER_COM, + config.getCredentialHelper()); + assertArrayEquals([expectedWarningMessage], warningLogMessages); + + // Reset warnings. + warningLogMessages = []; + config.update( + 'credentialHelper', Config.CredentialHelper.GOOGLE_YOLO); + assertEquals( + Config.CredentialHelper.GOOGLE_YOLO, + config.getCredentialHelper()); + assertArrayEquals([], warningLogMessages); + + // Reset warnings. + warningLogMessages = []; + config.update('credentialHelper', Config.CredentialHelper.NONE); + assertEquals(Config.CredentialHelper.NONE, config.getCredentialHelper()); + assertArrayEquals([], warningLogMessages); + }, + testGetCredentialHelper_httpOrHttps() { // Test credential helper configuration setting, as well as the // accountchooser.com enabled helper method, in a HTTP or HTTPS environment. diff --git a/javascript/widgets/firebaseuihandler.js b/javascript/widgets/firebaseuihandler.js index 4bf2561f..10d914a0 100644 --- a/javascript/widgets/firebaseuihandler.js +++ b/javascript/widgets/firebaseuihandler.js @@ -544,7 +544,7 @@ class FirebaseUiHandler { const message = getLocalizedErrorMessage(error['code']) || error['message']; this.disposeCurrentComponent_(); let onRetryClick; - if (error['retry'] && goog.isFunction(error['retry'])) { + if (error['retry'] && typeof error['retry'] === 'function') { onRetryClick = () => { this.reset(); error['retry'](); diff --git a/javascript/widgets/handler/common.js b/javascript/widgets/handler/common.js index 5ac9d1be..d79baab4 100644 --- a/javascript/widgets/handler/common.js +++ b/javascript/widgets/handler/common.js @@ -77,6 +77,14 @@ firebaseui.auth.widget.handler.common.acForceUiShown_ = false; */ firebaseui.auth.widget.handler.common.acLoader_ = null; +/** + * Resets accountchooser.com loader and removes global accountchooser namespace. + * This is useful for testing. + */ +firebaseui.auth.widget.handler.common.resetAcLoader = function() { + firebaseui.auth.widget.handler.common.acLoader_ = null; + goog.global['accountchooser'] = undefined; +}; /** * Loads the accountchooser.com client library if it is not loaded before and diff --git a/javascript/widgets/handler/common_test.js b/javascript/widgets/handler/common_test.js index 4d6891b1..868d94f1 100644 --- a/javascript/widgets/handler/common_test.js +++ b/javascript/widgets/handler/common_test.js @@ -48,6 +48,7 @@ goog.require('firebaseui.auth.widget.handler.handleSignIn'); goog.require('firebaseui.auth.widget.handler.testHelper'); goog.require('goog.Promise'); goog.require('goog.dom.forms'); +goog.require('goog.net.jsloader'); goog.require('goog.testing.AsyncTestCase'); goog.require('goog.testing.recordFunction'); @@ -1893,6 +1894,61 @@ function testHandleSignInWithEmail_acNotEnabled() { } +function testHandleSignInWithEmail_accountChooserNotFound() { + // This tests when accountchooser.com JS dependency fails to load + // that the flow continues to work as expected. This test is needed + // to confirm that after accountchooser.com is shutdown, the library + // continues to work. + + // This is the actual error that gets thrown when jsloader fails to load. + const expectedError = new Error( + 'Jsloader error (code #0): Error while loading script ' + + '//www.gstatic.com/accountchooser/client.js'); + // Uninstall mock acClient. It is better to test the real thing to ensure + // that when the dependency fails to load, the flow will continue to work. + testAc.uninstall(); + firebaseui.auth.widget.handler.common.resetAcLoader(); + // Track that loading error is triggered. + let errorTriggered = false; + // Simulate accountchooser.com dependency not found and jsloader failing. + testStubs.reset(); + // Assume widget already rendered and AuthUI global reference set. + testStubs.replace(firebaseui.auth.AuthUI, 'getAuthUi', function() { + return app; + }); + testStubs.set(firebaseui.auth.util, 'supportsCors', function() { + return true; + }); + // Simulate the loading error. + testStubs.replace( + goog.net.jsloader, 'safeLoad', function() { + errorTriggered = true; + return goog.Promise.reject(expectedError); + }); + + // Start sign-in with email handler. + // signIn page should be rendered despite accountchooser.com JS dependencies + // failing to load. + app.setConfig({ + 'credentialHelper': + firebaseui.auth.widget.Config.CredentialHelper.ACCOUNT_CHOOSER_COM, + }); + firebaseui.auth.widget.handler.common.handleSignInWithEmail(app, container); + asyncTestCase.waitForSignals(1); + + // Wait 2 cycles to give enough time for logic to run. + return goog.Promise.resolve().then(() => { + return goog.Promise.resolve(); + }).then(() => { + // Confirm error triggered. + assertTrue(errorTriggered); + // signIn page should be rendered. + assertSignInPage(); + asyncTestCase.signal(); + }); +} + + function testHandleSignInWithEmail_prefillEmail() { const prefilledEmail = 'user@example'; testStubs.replace( diff --git a/javascript/widgets/handler/testhelper.js b/javascript/widgets/handler/testhelper.js index 52be1756..832c4fe9 100644 --- a/javascript/widgets/handler/testhelper.js +++ b/javascript/widgets/handler/testhelper.js @@ -889,7 +889,7 @@ function assertTosPpLinkClicked_(tosUrl, privacyPolicyUrl) { 'firebaseui-tos-link', container); var ppLinkElement = goog.dom.getElementByClass( 'firebaseui-pp-link', container); - if (goog.isFunction(tosUrl)) { + if (typeof tosUrl === 'function') { assertEquals(0, tosUrl.getCallCount()); goog.testing.events.fireClickSequence(tosLinkElement); assertEquals(1, tosUrl.getCallCount()); @@ -897,7 +897,7 @@ function assertTosPpLinkClicked_(tosUrl, privacyPolicyUrl) { goog.testing.events.fireClickSequence(tosLinkElement); testUtil.assertOpen(tosUrl, '_blank'); } - if (goog.isFunction(privacyPolicyUrl)) { + if (typeof privacyPolicyUrl === 'function') { assertEquals(0, privacyPolicyUrl.getCallCount()); goog.testing.events.fireClickSequence(ppLinkElement); assertEquals(1, privacyPolicyUrl.getCallCount()); diff --git a/package-lock.json b/package-lock.json index 7e112bd6..0322834e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,213 +5,231 @@ "requires": true, "dependencies": { "@firebase/analytics": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.2.17.tgz", - "integrity": "sha512-5/b3DdRmFdhuqWufk9qrFms0fjDEYIDt/dMNJ3BFNPF+j4Uo89q8DPT71vxgXdx1Dsj4aJENFmrxSRpLe3n8sQ==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.3.7.tgz", + "integrity": "sha512-xIxbrnnyMcbmMVFhbbAeBrRcPv3c0/gEjPR0okvqUp0A1KsUvKetyq4ajYW7UAzyFPQIJ9v5M+y47TAB9oRefQ==", "dev": true, "requires": { - "@firebase/analytics-types": "0.2.8", - "@firebase/component": "0.1.7", - "@firebase/installations": "0.4.5", - "@firebase/util": "0.2.42", - "tslib": "1.11.1" + "@firebase/analytics-types": "0.3.1", + "@firebase/component": "0.1.14", + "@firebase/installations": "0.4.12", + "@firebase/logger": "0.2.5", + "@firebase/util": "0.2.49", + "tslib": "^1.11.1" } }, "@firebase/analytics-types": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.2.8.tgz", - "integrity": "sha512-7djG+mVLubSFy5ZEf8Gyn7XzrsLvpXCRj+vj6ta3KtwF2iCsOG4HvGv1TiU+sNwR017cAm2F0qmaAMac90Qq0g==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.3.1.tgz", + "integrity": "sha512-63vVJ5NIBh/JF8l9LuPrQYSzFimk7zYHySQB4Dk9rVdJ8kV/vGQoVTvRu1UW05sEc2Ug5PqtEChtTHU+9hvPcA==", "dev": true }, "@firebase/app": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.5.6.tgz", - "integrity": "sha512-FzO0dgIXQgLFOETdM3p6zMdGTee+hnOUqU0KC24n8+gqX833atGX4Vrc47H53EAiR7sW6ESHsyAfJcvGPBi37Q==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.6.6.tgz", + "integrity": "sha512-9NNhFedXHhUWDsbJL/A7vgiq9EDeqktFbkPYRfqN/GONIfVHfgAXOwQkEgz1trYV+XBP/n0Wyz8+lzXxu0+m8g==", "dev": true, "requires": { - "@firebase/app-types": "0.5.3", - "@firebase/component": "0.1.7", - "@firebase/logger": "0.1.37", - "@firebase/util": "0.2.42", + "@firebase/app-types": "0.6.1", + "@firebase/component": "0.1.14", + "@firebase/logger": "0.2.5", + "@firebase/util": "0.2.49", "dom-storage": "2.1.0", - "tslib": "1.11.1", + "tslib": "^1.11.1", "xmlhttprequest": "1.8.0" } }, "@firebase/app-types": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.5.3.tgz", - "integrity": "sha512-PH1egwhlEhZSp7/jiUNszG1BX1NBUuL86Zd1ZoXT3qaFS9YSGGEY7n0DKgI0fWoVa5GzfbzKOC+J1e4T/+PY1Q==", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.1.tgz", + "integrity": "sha512-L/ZnJRAq7F++utfuoTKX4CLBG5YR7tFO3PLzG1/oXXKEezJ0kRL3CMRoueBEmTCzVb/6SIs2Qlaw++uDgi5Xyg==", "dev": true }, "@firebase/auth": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.14.0.tgz", - "integrity": "sha512-3g3VylIUwNzzQ9xhfF5b+M3W+51bcvvbz+J/u9oXcvEvmy+MC1jJVrTYdQ5zg5vt+PrKzpRCY28N+uVcDO+Dug==", + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.14.7.tgz", + "integrity": "sha512-NTQY9luV70XUA6zGYOWloDSaOT+l0/R4u3W7ptqVCfZNc4DAt7euUkTbj7SDD14902sHF54j+tk5kmpEmMd0jA==", "dev": true, "requires": { - "@firebase/auth-types": "0.10.0" + "@firebase/auth-types": "0.10.1" } }, "@firebase/auth-interop-types": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.4.tgz", - "integrity": "sha512-CLKNS84KGAv5lRnHTQZFWoR11Ti7gIPFirDDXWek/fSU+TdYdnxJFR5XSD4OuGyzUYQ3Dq7aVj5teiRdyBl9hA==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.5.tgz", + "integrity": "sha512-88h74TMQ6wXChPA6h9Q3E1Jg6TkTHep2+k63OWg3s0ozyGVMeY+TTOti7PFPzq5RhszQPQOoCi59es4MaRvgCw==", "dev": true }, "@firebase/auth-types": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.10.0.tgz", - "integrity": "sha512-VuW7c+RAk3AYPU0Hxmun3RzXn7fbJDdjQbxvvpRMnQ9zrhk8mH42cY466M0n4e/UGQ+0smlx5BqZII8aYQ5XPg==", + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.10.1.tgz", + "integrity": "sha512-/+gBHb1O9x/YlG7inXfxff/6X3BPZt4zgBv4kql6HEmdzNQCodIRlEYnI+/da+lN+dha7PjaFH7C7ewMmfV7rw==", "dev": true }, "@firebase/component": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.7.tgz", - "integrity": "sha512-FAoi1ELlrVY9Uy9zzTlhc+3nn5VdYe36C/OpDnFXb2K/AH0jR6wcVTvLqGYFBPFVjgqO5MKCn3Mq3DCnro8QGg==", + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.14.tgz", + "integrity": "sha512-jbcTAne5mn5T508TY5BFrDOT1v/hXiX/22eMXweCXFbD+9JbsMztwQhNwqjwB8ihNAYG2FKw64UfI9NM04lD/g==", "dev": true, "requires": { - "@firebase/util": "0.2.42", - "tslib": "1.11.1" + "@firebase/util": "0.2.49", + "tslib": "^1.11.1" } }, "@firebase/database": { - "version": "0.5.23", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.23.tgz", - "integrity": "sha512-6zVa3dJoUT8bpiSai/aIbGPEDrGaFwR1iMMmXCYSf6su46ZYMLOYjSV/+nOHZaT4/TyQZY3D+iIL0WyRuEVOjA==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.6.5.tgz", + "integrity": "sha512-4AnsLUscnCZ48nRGe0YKmHq/cQ4pcM3pRV9O4Uh6mPQpTSixPDLMveuAHYJFUI9tgj5I+FNqjxezUFLS7+9XOw==", "dev": true, "requires": { - "@firebase/auth-interop-types": "0.1.4", - "@firebase/component": "0.1.7", - "@firebase/database-types": "0.4.13", - "@firebase/logger": "0.1.37", - "@firebase/util": "0.2.42", + "@firebase/auth-interop-types": "0.1.5", + "@firebase/component": "0.1.14", + "@firebase/database-types": "0.5.1", + "@firebase/logger": "0.2.5", + "@firebase/util": "0.2.49", "faye-websocket": "0.11.3", - "tslib": "1.11.1" + "tslib": "^1.11.1" } }, "@firebase/database-types": { - "version": "0.4.13", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.4.13.tgz", - "integrity": "sha512-7bDsD90Q9YmmB/A90UnZLv7jqgULClxAT1C4aw1dGfcS49XEUh2uuoW3NqS5vvtbMHJiurrN73ADddwgCrltww==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.5.1.tgz", + "integrity": "sha512-onQxom1ZBYBJ648w/VNRzUewovEDAH7lvnrrpCd69ukkyrMk6rGEO/PQ9BcNEbhlNtukpsqRS0oNOFlHs0FaSA==", "dev": true, "requires": { - "@firebase/app-types": "0.5.3" + "@firebase/app-types": "0.6.1" } }, "@firebase/firestore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.12.1.tgz", - "integrity": "sha512-HE++zHqOtLb/N7bhsiBR5uzBnHPVmEunz2vMC/jaJSIR/oBYVTIanMTzUxzOavUrII/9wnqFw3R2p0CY/CD9ow==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.15.4.tgz", + "integrity": "sha512-Q8YSHSO8D7MEoykHOdPWbgr2EN5AKTrEpHAmvFfDD5HMVTU6m8WfWqos8VawfZCfMkk65NJ5x+Pi+mzHj58ZcA==", "dev": true, "requires": { - "@firebase/component": "0.1.7", - "@firebase/firestore-types": "1.10.1", - "@firebase/logger": "0.1.37", - "@firebase/util": "0.2.42", - "@firebase/webchannel-wrapper": "0.2.37", + "@firebase/component": "0.1.14", + "@firebase/firestore-types": "1.11.0", + "@firebase/logger": "0.2.5", + "@firebase/util": "0.2.49", + "@firebase/webchannel-wrapper": "0.2.41", + "@grpc/grpc-js": "^1.0.0", "@grpc/proto-loader": "^0.5.0", - "grpc": "1.24.2", - "tslib": "1.11.1" + "tslib": "^1.11.1" + }, + "dependencies": { + "@grpc/grpc-js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.1.1.tgz", + "integrity": "sha512-mhZRszS0SKwnWPJaNyrECePZ9U7vaHFGqrzxQbWinWR3WznBIU+nmh2L5J3elF+lp5DEUIzARXkifbs6LQVAHA==", + "dev": true, + "requires": { + "semver": "^6.2.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@firebase/firestore-types": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-1.10.1.tgz", - "integrity": "sha512-vyKdm+AYUFT8XeUX62IOqaqPFCs/mAMoSEsqIz9HnSVsqCw/IocNjtjSa+3M80kRw4V8fI7JI+Xz6Wg5VJXLqA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-1.11.0.tgz", + "integrity": "sha512-hD7+cmMUvT5OJeWVrcRkE87PPuj/0/Wic6bntCopJE1WIX/Dm117AUkHgKd3S7Ici6DLp4bdlx1MjjwWL5942w==", "dev": true }, "@firebase/functions": { - "version": "0.4.37", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.4.37.tgz", - "integrity": "sha512-nNIW6KEQ8V0JVFlwSfJUs10LJIr3pjltSVA3ulDow3SeYl+VO+1tKsZUaG59CCSqHCIDkJJ3quBpFK36v141vQ==", + "version": "0.4.46", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.4.46.tgz", + "integrity": "sha512-Vr7CmlIRcocDPG7XTuepU9gTEZ58ZUjLwaaFNPlF6fo/9fGlnGDwrZa6Y1HPqXmkNIcHQWl2UteSXKnDuPKczg==", "dev": true, "requires": { - "@firebase/component": "0.1.7", - "@firebase/functions-types": "0.3.16", - "@firebase/messaging-types": "0.4.4", + "@firebase/component": "0.1.14", + "@firebase/functions-types": "0.3.17", + "@firebase/messaging-types": "0.4.5", "isomorphic-fetch": "2.2.1", - "tslib": "1.11.1" + "tslib": "^1.11.1" } }, "@firebase/functions-types": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.3.16.tgz", - "integrity": "sha512-kHhBvSYiY2prY4vNQCALYs1+OruTdylvGemHG6G6Bs/rj3qw7ui3WysBsDU/rInJitHIcsZ35qrtanoJeQUIXQ==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.3.17.tgz", + "integrity": "sha512-DGR4i3VI55KnYk4IxrIw7+VG7Q3gA65azHnZxo98Il8IvYLr2UTBlSh72dTLlDf25NW51HqvJgYJDKvSaAeyHQ==", "dev": true }, "@firebase/installations": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.4.5.tgz", - "integrity": "sha512-mIWpG9r98fiuh6yc0mPSoXzw/UV7UVSuvxpIqrdBT7P2o3ADDH1usyTq6QhSmb94HJhSG3QTj7VdV9wu/rcy7w==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.4.12.tgz", + "integrity": "sha512-DFN+lfrh+Yl2VoEuCZ4JpZQ2+F1C44gbOvmfVDoYEW4qDYgul7kP2jH+38xxdPubOpaNKZKmGKid4EkgtMnX0A==", "dev": true, "requires": { - "@firebase/component": "0.1.7", - "@firebase/installations-types": "0.3.3", - "@firebase/util": "0.2.42", + "@firebase/component": "0.1.14", + "@firebase/installations-types": "0.3.4", + "@firebase/util": "0.2.49", "idb": "3.0.2", - "tslib": "1.11.1" + "tslib": "^1.11.1" } }, "@firebase/installations-types": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.3.3.tgz", - "integrity": "sha512-XvWhPPAGeZlc+CfCA8jTt2pv19Jovi/nUV73u30QbjBbk5xci9bp5I29aBZukHsR6YNBjFCLSkLPbno4m/bLUg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.3.4.tgz", + "integrity": "sha512-RfePJFovmdIXb6rYwtngyxuEcWnOrzdZd9m7xAW0gRxDIjBT20n3BOhjpmgRWXo/DAxRmS7bRjWAyTHY9cqN7Q==", "dev": true }, "@firebase/logger": { - "version": "0.1.37", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.37.tgz", - "integrity": "sha512-uiVVfVlhCZLfUBqOCUuh8V3t+8lKTFJ6mgDoH99YFbuWYUUch8OHWQG70qg/I6m7IRIZLtHyPt3OCxYgI0R6Yw==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.5.tgz", + "integrity": "sha512-qqw3m0tWs/qrg7axTZG/QZq24DIMdSY6dGoWuBn08ddq7+GLF5HiqkRj71XznYeUUbfRq5W9C/PSFnN4JxX+WA==", "dev": true }, "@firebase/messaging": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.6.9.tgz", - "integrity": "sha512-MIkvpD56JX8NhcrWYI1DsgOUyEq/NpkdecqxeJx6IUK64W4GmJW7Msh3xGrvHpRetoErjM6OqKYzlJqEixL6wg==", + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.6.18.tgz", + "integrity": "sha512-pu2K+kXuPO4i+9oeQ6nbh0Xxnb1XaQmAiuRRXUmr9sGmo6Sw2ZpYNEhHIHVxvFDn3OUg+QvGgM/ft16kG3DHRQ==", "dev": true, "requires": { - "@firebase/component": "0.1.7", - "@firebase/installations": "0.4.5", - "@firebase/messaging-types": "0.4.4", - "@firebase/util": "0.2.42", + "@firebase/component": "0.1.14", + "@firebase/installations": "0.4.12", + "@firebase/messaging-types": "0.4.5", + "@firebase/util": "0.2.49", "idb": "3.0.2", - "tslib": "1.11.1" + "tslib": "^1.11.1" } }, "@firebase/messaging-types": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.4.4.tgz", - "integrity": "sha512-JGtkr+1A1Dw7+yCqQigqBfGKtq0gTCruFScBD4MVjqZHiqGIYpnQisWnpGbkzPR6aOt6iQxgwxUhHG1ulUQGeg==", + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.4.5.tgz", + "integrity": "sha512-sux4fgqr/0KyIxqzHlatI04Ajs5rc3WM+WmtCpxrKP1E5Bke8xu/0M+2oy4lK/sQ7nov9z15n3iltAHCgTRU3Q==", "dev": true }, "@firebase/performance": { - "version": "0.2.35", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.2.35.tgz", - "integrity": "sha512-FMHjxfy/8E1Y9aurLS0sEpPII2xsNiYAantFS95IwXvVAa2cpnZFCzOn/XUT2ytfuxgUo2Ly4gOvplcI07oE5w==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.3.7.tgz", + "integrity": "sha512-H4yts/IZ6/8zy5rdsLH0ZbW7Qg5Yj13lCLlvNFxqtDlKI8UbgxvuBkDmXLApA+Ze2Ah2vRSSJ4J3LdxxRnC62Q==", "dev": true, "requires": { - "@firebase/component": "0.1.7", - "@firebase/installations": "0.4.5", - "@firebase/logger": "0.1.37", - "@firebase/performance-types": "0.0.12", - "@firebase/util": "0.2.42", - "tslib": "1.11.1" + "@firebase/component": "0.1.14", + "@firebase/installations": "0.4.12", + "@firebase/logger": "0.2.5", + "@firebase/performance-types": "0.0.13", + "@firebase/util": "0.2.49", + "tslib": "^1.11.1" } }, "@firebase/performance-types": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.0.12.tgz", - "integrity": "sha512-eIDF7CHetOE5sc+hCaUebEn/2Aiaju7UkgZDTl7lNQHz5fK9wJ/11HaE8WdnDr//ngS3lQAGC2RB4lAZeEWraA==", + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.0.13.tgz", + "integrity": "sha512-6fZfIGjQpwo9S5OzMpPyqgYAUZcFzZxHFqOyNtorDIgNXq33nlldTL/vtaUZA8iT9TT5cJlCrF/jthKU7X21EA==", "dev": true }, "@firebase/polyfill": { - "version": "0.3.32", - "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.32.tgz", - "integrity": "sha512-Q6n7s3YAKI1xpBUBKOoDqC2i4bTYEZ2BLDgwhkWF+aMi0pWrhODDrV50s/Cza1Z2quaWu3jCZ0Bg9TzG1+zGbg==", + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.36.tgz", + "integrity": "sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==", "dev": true, "requires": { - "core-js": "3.6.4", + "core-js": "3.6.5", "promise-polyfill": "8.1.3", "whatwg-fetch": "2.0.4" }, @@ -225,56 +243,56 @@ } }, "@firebase/remote-config": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.1.16.tgz", - "integrity": "sha512-Fo6fPJ/e5MsU8AZtFcS/5JMvU+wcb4Mf0SSIclhwWaX8JKePYF0TG92pbGoSs9RdsdxxlzXIQjtcvmi40eMN6Q==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.1.23.tgz", + "integrity": "sha512-psirtTiu9tfVxSVHo82iIdaD0IXP+DgpAPdtxahDlq/b7Ln26fqdJ8KTM1AKI20ZV2h6d4U/HqeouObl+LyrJg==", "dev": true, "requires": { - "@firebase/component": "0.1.7", - "@firebase/installations": "0.4.5", - "@firebase/logger": "0.1.37", - "@firebase/remote-config-types": "0.1.8", - "@firebase/util": "0.2.42", - "tslib": "1.11.1" + "@firebase/component": "0.1.14", + "@firebase/installations": "0.4.12", + "@firebase/logger": "0.2.5", + "@firebase/remote-config-types": "0.1.9", + "@firebase/util": "0.2.49", + "tslib": "^1.11.1" } }, "@firebase/remote-config-types": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.1.8.tgz", - "integrity": "sha512-K12IBHO7OD4gCW0FEqZL9zMqVAfS4+joC4YIn3bHezZfu3RL+Bw1wCb0cAD7RfDPcQxWJjxOHpce4YhuqSxPFA==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.1.9.tgz", + "integrity": "sha512-G96qnF3RYGbZsTRut7NBX0sxyczxt1uyCgXQuH/eAfUCngxjEGcZQnBdy6mvSdqdJh5mC31rWPO4v9/s7HwtzA==", "dev": true }, "@firebase/storage": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.3.29.tgz", - "integrity": "sha512-vFNq282bbVXytSDUvyD2NYOodtB9fXmKUNgWNQxUAcXGBMJXq1NSLrmfetAS+kPTs2ejUS/VUdW7BlSfYyAF3Q==", + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.3.36.tgz", + "integrity": "sha512-DcxULwmoyZnpulW6e/G2y6gKXCMwnKWy8snw+7f4yvb6RI7WFMYB8nIb2CSArWmrnT7YD7e+G9BA1a6nZ0eycQ==", "dev": true, "requires": { - "@firebase/component": "0.1.7", - "@firebase/storage-types": "0.3.11", - "@firebase/util": "0.2.42", - "tslib": "1.11.1" + "@firebase/component": "0.1.14", + "@firebase/storage-types": "0.3.12", + "@firebase/util": "0.2.49", + "tslib": "^1.11.1" } }, "@firebase/storage-types": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.3.11.tgz", - "integrity": "sha512-EMOo5aeiJIa8eQ/VqjIa/DYlDcEJX1V84FOxmLfNWZIlmCSvcqx9E9mcNlOnoUB4iePqQjTMQRtKlIBvvEVhVg==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.3.12.tgz", + "integrity": "sha512-DDV6Fs6aYoGw3w/zZZTkqiipxihnsvHf6znbeZYjIIHit3tr1uLJdGPDPiCTfZcTGPpg2ux6ZmvNDvVgJdHALw==", "dev": true }, "@firebase/util": { - "version": "0.2.42", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.42.tgz", - "integrity": "sha512-ihFavcy7OdSMwZySidRSi58RkiqVVcmVAVy2J5VSKWaCQcBL8+4+H0ytmmXplxKCaQAsyqj1XhJx+MaCJyXknQ==", + "version": "0.2.49", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.49.tgz", + "integrity": "sha512-SjUoxSqIfcSvDBiMiFEF5SmUOcWNbMH2asJ0VZ1T3vPBlCIRp6tk+T3LMvUWAI8OCnTpbGtpX1fTKiUDLP4xkQ==", "dev": true, "requires": { - "tslib": "1.11.1" + "tslib": "^1.11.1" } }, "@firebase/webchannel-wrapper": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.37.tgz", - "integrity": "sha512-jreLH4/jlrULywKPQKMCjNGKY/ynZPZxiM8T6vD+JxpjOBqtXWcuBEzOktcQ5lWs3BlRi77NHOTLs23hkFXZiQ==", + "version": "0.2.41", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.41.tgz", + "integrity": "sha512-XcdMT5PSZHiuf7LJIhzKIe+RyYa25S3LHRRvLnZc6iFjwXkrSDJ8J/HWO6VT8d2ZTbawp3VcLEjRF/VN8glCrA==", "dev": true }, "@google-cloud/paginator": { @@ -456,16 +474,6 @@ "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", "dev": true }, - "@types/bytebuffer": { - "version": "5.0.40", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.40.tgz", - "integrity": "sha512-h48dyzZrPMz25K6Q4+NCwWaxwXany2FhQg/ErOcdZS1ZpsaDnDMZg8JYLMTGz7uvXKrcKGJUZJlZObyfgdaN9g==", - "dev": true, - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, "@types/duplexify": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", @@ -1037,16 +1045,6 @@ "integrity": "sha1-TwSAXYf4/OjlEbwhCPjl46KH1Uc=", "dev": true }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "dev": true, - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -1608,9 +1606,9 @@ } }, "browserify": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.0.tgz", - "integrity": "sha512-6bfI3cl76YLAnCZ75AGu/XPOsqUhRyc0F/olGIJeCxtfxF2HvPKEcmjU9M8oAPxl4uBY1U7Nry33Q6koV3f2iw==", + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.1.tgz", + "integrity": "sha512-EQX0h59Pp+0GtSRb5rL6OTfrttlzv+uyaUVlK6GX3w11SQ0jKPKyjC/54RhPR2ib2KmfcELM06e8FxcI5XNU2A==", "dev": true, "requires": { "JSONStream": "^1.0.3", @@ -1618,7 +1616,7 @@ "browser-pack": "^6.0.1", "browser-resolve": "^1.11.0", "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", + "buffer": "~5.2.1", "cached-path-relative": "^1.0.0", "concat-stream": "^1.6.0", "console-browserify": "^1.1.0", @@ -1636,7 +1634,7 @@ "inherits": "~2.0.1", "insert-module-globals": "^7.0.0", "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", + "mkdirp-classic": "^0.5.2", "module-deps": "^6.0.0", "os-browserify": "~0.3.0", "parents": "^1.0.1", @@ -1661,6 +1659,18 @@ "util": "~0.10.1", "vm-browserify": "^1.0.0", "xtend": "^4.0.0" + }, + "dependencies": { + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + } } }, "browserify-aes": { @@ -1865,23 +1875,6 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dev": true, - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - } - } - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -2195,6 +2188,21 @@ "jsonfile": "^4.0.0", "universalify": "^0.1.0" } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } } } }, @@ -2252,12 +2260,6 @@ "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", "dev": true }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", - "dev": true - }, "combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -2512,9 +2514,9 @@ } }, "core-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", - "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", "dev": true }, "core-util-is": { @@ -2845,9 +2847,9 @@ "dev": true }, "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", "dev": true, "requires": { "decompress-tar": "^4.0.0", @@ -3888,25 +3890,25 @@ } }, "firebase": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-7.11.0.tgz", - "integrity": "sha512-8grsK7aSu1WmaVzxkueOylqZJM7Gf2S4OZO5gQRYwvPnmCsnjfKkSbPrxlEt5znyKuAOgud0ECUXFpj/e0OBtg==", - "dev": true, - "requires": { - "@firebase/analytics": "0.2.17", - "@firebase/app": "0.5.6", - "@firebase/app-types": "0.5.3", - "@firebase/auth": "0.14.0", - "@firebase/database": "0.5.23", - "@firebase/firestore": "1.12.1", - "@firebase/functions": "0.4.37", - "@firebase/installations": "0.4.5", - "@firebase/messaging": "0.6.9", - "@firebase/performance": "0.2.35", - "@firebase/polyfill": "0.3.32", - "@firebase/remote-config": "0.1.16", - "@firebase/storage": "0.3.29", - "@firebase/util": "0.2.42" + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-7.15.4.tgz", + "integrity": "sha512-pj9xa9WY4sinH6ebb4yqSgaz+DIg19VqGUV+gTj0MTkN877ePZti0k1GIzaqrbnEUow2Sf56Xz8LyZg+HCBCmA==", + "dev": true, + "requires": { + "@firebase/analytics": "0.3.7", + "@firebase/app": "0.6.6", + "@firebase/app-types": "0.6.1", + "@firebase/auth": "0.14.7", + "@firebase/database": "0.6.5", + "@firebase/firestore": "1.15.4", + "@firebase/functions": "0.4.46", + "@firebase/installations": "0.4.12", + "@firebase/messaging": "0.6.18", + "@firebase/performance": "0.3.7", + "@firebase/polyfill": "0.3.36", + "@firebase/remote-config": "0.1.23", + "@firebase/storage": "0.3.36", + "@firebase/util": "0.2.49" } }, "firebase-tools": { @@ -5623,503 +5625,6 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, - "grpc": { - "version": "1.24.2", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.2.tgz", - "integrity": "sha512-EG3WH6AWMVvAiV15d+lr+K77HJ/KV/3FvMpjKjulXHbTwgDZkhkcWbwhxFAoTdxTkQvy0WFcO3Nog50QBbHZWw==", - "dev": true, - "requires": { - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "node-pre-gyp": "^0.14.0", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.4", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - } - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "needle": { - "version": "2.4.0", - "bundled": true, - "dev": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true - }, - "npm-packlist": { - "version": "1.4.6", - "bundled": true, - "dev": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dev": true, - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "dev": true - } - } - }, "gtoken": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.1.4.tgz", @@ -8199,12 +7704,6 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -8900,22 +8399,20 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } + "minimist": "^1.2.5" } }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "module-deps": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.2.tgz", @@ -9442,12 +8939,6 @@ } } }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", - "dev": true - }, "ora": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", @@ -9834,9 +9325,9 @@ } }, "portfinder": { - "version": "1.0.25", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", - "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", + "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", "dev": true, "requires": { "async": "^2.6.2", @@ -9952,7 +9443,7 @@ "selenium-webdriver": "3.6.0", "source-map-support": "~0.4.0", "webdriver-js-extender": "2.1.0", - "webdriver-manager": "^12.0.6" + "webdriver-manager": "^12.1.7" }, "dependencies": { "webdriver-manager": { @@ -12607,12 +12098,6 @@ } } }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, "winston": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/winston/-/winston-1.1.2.tgz", @@ -12732,21 +12217,6 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, "yargs-parser": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", diff --git a/package.json b/package.json index afac479b..5710af2a 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "license": "Apache-2.0", "devDependencies": { "closure-builder": "^2.3.8", - "firebase": "^7.11.0", + "firebase": "^7.15.4", "firebase-tools": "^7.0.2", "fs-extra": "^3.0.1", "google-closure-compiler": "^20190415.0.0", diff --git a/stylesheet/firebase-ui.css b/stylesheet/firebase-ui.css index a2ebaab8..c3d8174d 100644 --- a/stylesheet/firebase-ui.css +++ b/stylesheet/firebase-ui.css @@ -499,6 +499,7 @@ input.firebaseui-input-invalid{ } .mdl-spinner.firebaseui-busy-indicator { + direction: initial; height: 56px; left: 0px; margin: auto; From d1d46726306d523396bbcca7f8c5315fd2b9c271 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Tue, 23 Jun 2020 15:50:55 -0700 Subject: [PATCH 02/11] add CHANGELOG updates --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29b..e7915144 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +* Remove usage of goog.isFunction. +* Fix FirebaseUI-web spinner off for RTL languages. +* Show warning on accountchooser.com becomes universally opt-out. +* Add unit test to confirm that if accountchooser.com JS dependency fails to load that the sign in flow would continue to work as expected. \ No newline at end of file From 2dd303f13837129eff74767da0839569ad9a4eb0 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Thu, 25 Jun 2020 18:08:14 -0700 Subject: [PATCH 03/11] edit changelog --- CHANGELOG.md | 6 ++---- demo/public/widget.html | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7915144..41d0f5de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,2 @@ -* Remove usage of goog.isFunction. -* Fix FirebaseUI-web spinner off for RTL languages. -* Show warning on accountchooser.com becomes universally opt-out. -* Add unit test to confirm that if accountchooser.com JS dependency fails to load that the sign in flow would continue to work as expected. \ No newline at end of file +* Fixes FirebaseUI-web spinner off for RTL languages. +* Log warning on accountchooser.com being deprecated and switching to universal opt-out mode starting in July 31st, 2020. \ No newline at end of file diff --git a/demo/public/widget.html b/demo/public/widget.html index 2f33c365..329c2c4f 100644 --- a/demo/public/widget.html +++ b/demo/public/widget.html @@ -65,7 +65,7 @@ 'tosUrl': 'https://www.google.com', 'credentialHelper': CLIENT_ID && CLIENT_ID != 'YOUR_OAUTH_CLIENT_ID' ? firebaseui.auth.CredentialHelper.GOOGLE_YOLO : - firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM + firebaseui.auth.CredentialHelper.NONE }; // Initialize the FirebaseUI Widget using Firebase. From 95fc1fb75d2781f3ea043143f0581568b53093d2 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Thu, 25 Jun 2020 18:18:12 -0700 Subject: [PATCH 04/11] changelog typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41d0f5de..153a01d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,2 @@ -* Fixes FirebaseUI-web spinner off for RTL languages. +* Fixes FirebaseUI-web spinner for RTL languages. * Log warning on accountchooser.com being deprecated and switching to universal opt-out mode starting in July 31st, 2020. \ No newline at end of file From 4437ab0192aad2430276706ee13dfae3c7504f40 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Fri, 26 Jun 2020 11:23:13 -0700 Subject: [PATCH 05/11] package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5710af2a..0bbd462c 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ "firebase": "^7.15.4", "firebase-tools": "^7.0.2", "fs-extra": "^3.0.1", - "google-closure-compiler": "^20190415.0.0", - "google-closure-library": "^20190415.0.0", + "google-closure-compiler": "^20200112.0.0", + "google-closure-library": "^20200224.0.0", "google-closure-templates": "^20150410.0.0", "gulp": "^4.0.0", "gulp-clean-css": "^4.2.0", From a5da7217daf5751d24824347914bc932ca4c0194 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Fri, 26 Jun 2020 12:00:23 -0700 Subject: [PATCH 06/11] update packagejson --- package.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 483ef3a5..7d60a12b 100644 --- a/package.json +++ b/package.json @@ -39,16 +39,11 @@ "license": "Apache-2.0", "devDependencies": { "closure-builder": "^2.3.8", -<<<<<<< HEAD - "firebase": "^7.15.4", - "firebase-tools": "^7.0.2", -======= "firebase": "^7.15.5", "firebase-tools": "^7.16.2", ->>>>>>> master "fs-extra": "^3.0.1", - "google-closure-compiler": "^20200112.0.0", - "google-closure-library": "^20200224.0.0", + "google-closure-compiler": "^20190415.0.0", + "google-closure-library": "^20190415.0.0", "google-closure-templates": "^20150410.0.0", "gulp": "^4.0.2", "gulp-clean-css": "^4.3.0", From 6e2721bf72034a64c0fc361b7832478e450ee10d Mon Sep 17 00:00:00 2001 From: Xin Li Date: Fri, 26 Jun 2020 13:52:39 -0700 Subject: [PATCH 07/11] last change on package-lock.json --- package-lock.json | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index b43ec89d..4134d2c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5740,9 +5740,9 @@ }, "dependencies": { "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", "dev": true, "requires": { "source-map": "~0.6.0" @@ -7794,12 +7794,6 @@ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -9014,24 +9008,6 @@ "is-wsl": "^1.1.0" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - } - } - }, "ora": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", From 02f554333e8ca10320c550602d646d1ec98992c6 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Wed, 8 Jul 2020 15:22:19 -0700 Subject: [PATCH 08/11] update package-lock --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4134d2c7..ea05753f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7607,9 +7607,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "lodash._baseassign": { From 92a9fe2c95acd7a57461f9bb424943329dda8f30 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Mon, 27 Jul 2020 11:45:29 -0700 Subject: [PATCH 09/11] tenant button configs --- CHANGELOG.md | 1 + README.md | 2 +- externs/firebaseui-externs.js | 7 +++ firebaseuihandler/README.md | 10 ++++ javascript/ui/page/emaillinksigninlinking.js | 2 +- .../emaillinksigninlinkingdifferentdevice.js | 2 +- javascript/ui/page/federatedlinking.js | 2 +- javascript/widgets/firebaseuihandler_test.js | 47 +++++++++++++++++-- javascript/widgets/uihandlerconfig.js | 1 + javascript/widgets/uihandlerconfig_test.js | 10 +++- soy/elements.soy | 16 ++++--- soy/elements_test.js | 17 ++++++- soy/pages.soy | 4 +- soy/pages_test.js | 17 ++++++- types/index.d.ts | 1 + 15 files changed, 120 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29b..f641653a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1 @@ +* Allow fullLabel customization for tenant selection buttons in FirebaseUI for IAP. \ No newline at end of file diff --git a/README.md b/README.md index f6f1c795..b50b72d9 100644 --- a/README.md +++ b/README.md @@ -1536,7 +1536,7 @@ You can refer to the example in this [guide](https://cloud.google.com/identity-platform/docs/multi-tenancy-ui). There is also a -[quickstart](https://github.com/firebase/quickstart-js/blob/master/auth/multi-tenant-ui.html) +[quickstart](https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart) app available to demonstrate how to build a single sign-in page with the FirebaseUI for two tenants which have different sets of identity providers enabled. diff --git a/externs/firebaseui-externs.js b/externs/firebaseui-externs.js index f7bf0819..2d9ba5e8 100644 --- a/externs/firebaseui-externs.js +++ b/externs/firebaseui-externs.js @@ -609,6 +609,13 @@ firebaseui.auth.Config.prototype.widgetUrl; */ firebaseui.auth.TenantConfig = function() {}; +/** + * The tenant full label of the tenant selection button for the option first + * flow. + * + * @type {string|undefined} + */ +firebaseui.auth.TenantConfig.prototype.fullLabel; /** * The tenant display name of the tenant selection button for the option first diff --git a/firebaseuihandler/README.md b/firebaseuihandler/README.md index 79928864..4a37d7ef 100644 --- a/firebaseuihandler/README.md +++ b/firebaseuihandler/README.md @@ -116,6 +116,8 @@ const configs = { tenants: { // Tenant configuration for tenant ID tenantId1. tenantId1: { + // To customize the full tenant selection button label: + // fullLabel: 'ACME Portal', // Display name, button color and icon URL of the // tenant selection button. displayName: 'ACME', @@ -147,6 +149,8 @@ const configs = { }, // Tenant configuration for tenant ID tenantId2. tenantId2: { + // To customize the full tenant selection button label: + // fullLabel: 'OCP Portal', displayName: 'OCP', buttonColor: '#2F2F2F', iconUrl: '', @@ -215,6 +219,8 @@ The following is an example of a tenant configured to use options mode: ```javascript tenantId1: { + // To customize the full tenant selection button label: + // fullLabel: 'ACME Portal', displayName: 'ACME', buttonColor: '#2F2F2F', iconUrl: '', @@ -382,6 +388,10 @@ interface Callbacks { // Interface that represents the tenant-level configurations. interface TenantConfig { + // The full label for the tenant in the tenant selection buttion. Only needed + // if you are using the option first mode. + // When not provided, the "Sign in to $displayName" label is used. + fullLabel?: string; // The display name for tenant in the tenant selection button. Only needed if // you are using the option first mode. displayName?: string; diff --git a/javascript/ui/page/emaillinksigninlinking.js b/javascript/ui/page/emaillinksigninlinking.js index 7d3bec4b..f74f7e12 100644 --- a/javascript/ui/page/emaillinksigninlinking.js +++ b/javascript/ui/page/emaillinksigninlinking.js @@ -30,7 +30,7 @@ firebaseui.auth.ui.page.EmailLinkSignInLinking = class extends firebaseui.auth.ui.page.Base { /** * @param {string} email The user's email. - * @param {?Object} providerConfig The provider config of the IdP we should + * @param {?} providerConfig The provider config of the IdP we should * use for sign in. * @param {function()} onSubmitClick Callback to invoke when the submit button * is clicked. diff --git a/javascript/ui/page/emaillinksigninlinkingdifferentdevice.js b/javascript/ui/page/emaillinksigninlinkingdifferentdevice.js index 49dfb0a0..7229ae6d 100644 --- a/javascript/ui/page/emaillinksigninlinkingdifferentdevice.js +++ b/javascript/ui/page/emaillinksigninlinkingdifferentdevice.js @@ -30,7 +30,7 @@ goog.require('firebaseui.auth.ui.page.Base'); firebaseui.auth.ui.page.EmailLinkSignInLinkingDifferentDevice = class extends firebaseui.auth.ui.page.Base { /** - * @param {?Object} providerConfig The provider config of the IdP we should + * @param {?} providerConfig The provider config of the IdP we should * use for sign in. * @param {function()} onContinueClick Callback to invoke when the continue * button is clicked. diff --git a/javascript/ui/page/federatedlinking.js b/javascript/ui/page/federatedlinking.js index af9a8fc0..4135185b 100644 --- a/javascript/ui/page/federatedlinking.js +++ b/javascript/ui/page/federatedlinking.js @@ -31,7 +31,7 @@ firebaseui.auth.ui.page.FederatedLinking = class extends firebaseui.auth.ui.page.Base { /** * @param {string} email The user's email. - * @param {?Object} providerConfig The provider config of the IdP we should + * @param {?} providerConfig The provider config of the IdP we should * use for sign in. * @param {function()} onSubmitClick Callback to invoke when the submit button * is clicked. diff --git a/javascript/widgets/firebaseuihandler_test.js b/javascript/widgets/firebaseuihandler_test.js index 9b9e9d8a..6f81ce6c 100644 --- a/javascript/widgets/firebaseuihandler_test.js +++ b/javascript/widgets/firebaseuihandler_test.js @@ -87,6 +87,25 @@ function assertBlankPageVisible(container) { assertNotNull(dom.getElementByClass('firebaseui-id-page-blank', container)); } +/** + * Asserts the IdP or tenant button has correct labels. + * @param {!Element} button The IdP or tenant button. + * @param {string} expectedShortLabel The expected short label of the button. + * @param {string} expectedLongLabel The expected long label of the button. + */ +function assertIdpButtonLabels(button, expectedShortLabel, expectedLongLabel) { + const idpTextLong = dom.getElementsByClass( + 'firebaseui-idp-text-long', button); + const idpTextShort = dom.getElementsByClass( + 'firebaseui-idp-text-short', button); + + assertEquals( + expectedLongLabel, + dom.getTextContent(idpTextLong[0])); + assertEquals( + expectedShortLabel, + dom.getTextContent(idpTextShort[0])); +} /** * Asserts the busy indicator is after a short delay. @@ -374,6 +393,7 @@ testSuite({ 'tenants': { // The top-level project UI configuration. '_': { + 'fullLabel': 'ACME Login', 'displayName': 'ACME', 'buttonColor': '#FFB6C1', 'iconUrl': '', @@ -393,6 +413,7 @@ testSuite({ 'privacyPolicyUrl': 'http://localhost/privacy_policy', }, 'tenant1': { + 'fullLabel': 'Contractor A Portal', 'displayName': 'Contractor A', 'buttonColor': '#ADF7B2', 'iconUrl': '', @@ -420,6 +441,7 @@ testSuite({ 'privacyPolicyUrl': 'http://localhost/privacy_policy', }, 'tenant2': { + 'fullLabel': 'Contractor B Portal', 'displayName': 'Contractor B', 'buttonColor': '#EAC9A1', 'iconUrl': '', @@ -490,10 +512,20 @@ testSuite({ 'firebaseui-id-tenant-selection-button', container); // Two tenants should be available to be selected from. const expectedTenants = ['tenant1', 'tenant2']; + // Two expected labels on buttons. + const expectedLongLabels = [ + 'Contractor A Portal', + 'Sign in to Contractor B' + ]; + const expectedShortLabels = ['Contractor A', 'Contractor B']; + assertEquals(expectedTenants.length, buttons.length); for (let i = 0; i < buttons.length; i++) { - assertEquals(expectedTenants[i], - dataset.get(buttons[i], 'tenantId')); + assertEquals(expectedTenants[i], dataset.get(buttons[i], 'tenantId')); + assertIdpButtonLabels( + buttons[i], + expectedShortLabels[i], + expectedLongLabels[i]); } // Click the tenant1's button. @@ -587,10 +619,19 @@ testSuite({ 'firebaseui-id-tenant-selection-button', container); // Only two tenants should be available to be selected from. const expectedTenants = ['tenant1', 'tenant2']; + const expectedLongLabels = [ + 'Contractor A Portal', + 'Sign in to Contractor B' + ]; + const expectedShortLabels = ['Contractor A', 'Contractor B']; assertEquals(expectedTenants.length, buttons.length); for (let i = 0; i < buttons.length; i++) { assertEquals(expectedTenants[i], - dataset.get(buttons[i], 'tenantId')); + dataset.get(buttons[i], 'tenantId')); + assertIdpButtonLabels( + buttons[i], + expectedShortLabels[i], + expectedLongLabels[i]); } testingEvents.fireClickSequence(buttons[1]); diff --git a/javascript/widgets/uihandlerconfig.js b/javascript/widgets/uihandlerconfig.js index f14666ac..a05cf6c7 100644 --- a/javascript/widgets/uihandlerconfig.js +++ b/javascript/widgets/uihandlerconfig.js @@ -332,6 +332,7 @@ class UiHandlerConfig { return { tenantId: tenantId !== UiHandlerConfig.ConfigKeys.TOP_LEVEL_CONFIG_KEY ? tenantId : null, + fullLabel: tenantConfig['fullLabel'] || null, displayName: tenantConfig['displayName'], iconUrl: tenantConfig['iconUrl'], buttonColor: tenantConfig['buttonColor'], diff --git a/javascript/widgets/uihandlerconfig_test.js b/javascript/widgets/uihandlerconfig_test.js index 2185f95a..6765b15b 100644 --- a/javascript/widgets/uihandlerconfig_test.js +++ b/javascript/widgets/uihandlerconfig_test.js @@ -39,6 +39,7 @@ testSuite({ displayMode: 'optionsFirst', tenants: { tenantId1: { + fullLabel: 'Contractor A Portal', displayName: 'Contractor A', buttonColor: '#FFB6C1', iconUrl: '', @@ -86,7 +87,7 @@ testSuite({ credentialHelper: 'none', }, _: { - displayName: 'ACME', + displayName: 'ACME.COM', buttonColor: '#53B2BF', iconUrl: '', signInOptions: [ @@ -589,6 +590,7 @@ testSuite({ assertObjectEquals( { tenantId: 'tenantId1', + fullLabel: 'Contractor A Portal', displayName: 'Contractor A', buttonColor: '#FFB6C1', iconUrl: '', @@ -604,7 +606,7 @@ testSuite({ assertObjectEquals( { tenantId: null, - displayName: 'ACME', + displayName: 'ACME.COM', buttonColor: '#53B2BF', iconUrl: '', }, @@ -615,6 +617,7 @@ testSuite({ // Test that the default option first tenant selection related configs are // returned for arbitrary tenant if default configuration is provided. configObject['tenants']['*'] = { + fullLabel: 'Dealership Login', displayName: 'DEALER', buttonColor: '#37D2AC', iconUrl: '', @@ -629,6 +632,7 @@ testSuite({ assertObjectEquals( { tenantId: 'arbitrary_tenant_id', + fullLabel: 'Dealership Login', displayName: 'DEALER', buttonColor: '#37D2AC', iconUrl: '', @@ -641,6 +645,7 @@ testSuite({ // returned for top level project if default configuration is provided. delete configObject['tenants']['_']; configObject['tenants']['*'] = { + fullLabel: 'Dealership Login', displayName: 'DEALER', buttonColor: '#37D2AC', iconUrl: '', @@ -654,6 +659,7 @@ testSuite({ assertObjectEquals( { tenantId: null, + fullLabel: 'Dealership Login', displayName: 'DEALER', buttonColor: '#37D2AC', iconUrl: '', diff --git a/soy/elements.soy b/soy/elements.soy index f6a798d5..3be61225 100644 --- a/soy/elements.soy +++ b/soy/elements.soy @@ -642,9 +642,9 @@ {$providerConfig.providerName} {elseif $ij.defaultProviderNames[$providerConfig.providerId]} {$ij.defaultProviderNames[$providerConfig.providerId]} - {elseif strIndexOf($providerConfig.providerId, 'saml.') == 0} + {elseif $providerConfig.providerId and strIndexOf($providerConfig.providerId, 'saml.') == 0} {strSub($providerConfig.providerId, 5)} - {elseif strIndexOf($providerConfig.providerId, 'oidc.') == 0} + {elseif $providerConfig.providerId and strIndexOf($providerConfig.providerId, 'oidc.') == 0} {strSub($providerConfig.providerId, 5)} {else} {$providerConfig.providerId} @@ -728,7 +728,7 @@ * Renders a tenant selection button. */ {template .tenantSelectionButton} - {@param tenantConfig: [tenantId:string|null, displayName:string, buttonColor:string, + {@param tenantConfig: [tenantId:string|null, fullLabel:string|null, displayName:string, buttonColor:string, iconUrl: string]} /** The tenant selection button config. */ {let $tenantClass kind="text"} {if $tenantConfig.tenantId} @@ -749,9 +749,13 @@ src="{$tenantConfig.iconUrl}"> - {msg desc="Label for a button to sign in to a tenant. The long version"} - Sign in to {$tenantConfig.displayName} - {/msg} + {if $tenantConfig.fullLabel} + {$tenantConfig.fullLabel} + {else} + {msg desc="Label for a button to sign in to a tenant. The long version"} + Sign in to {$tenantConfig.displayName} + {/msg} + {/if} {msg desc="Label for a button to sign in to a tenant. The short version"} diff --git a/soy/elements_test.js b/soy/elements_test.js index f8f9a829..ff119f72 100644 --- a/soy/elements_test.js +++ b/soy/elements_test.js @@ -557,7 +557,22 @@ function testTenantSelectionButton() { displayName: 'ACME', buttonColor: '#53B2BF', iconUrl: 'icon-url', - }]; + }, + { + tenantId: 'TENANT_1', + fullLabel: 'Contractor Login', + displayName: 'OIDC', + buttonColor: '#4666FF', + iconUrl: 'icon-url', + }, + { + tenantId: 'TENANT_2', + fullLabel: null, + displayName: 'Contractor Corp', + buttonColor: '#2F2B2E', + iconUrl: 'icon-url', + } + ]; const root = goog.dom.getElement('tenant-selection-button'); for (let i = 0; i < tenantConfigs.length; i++) { const button = goog.soy.renderAsElement( diff --git a/soy/pages.soy b/soy/pages.soy index 62e3080f..0fcc8089 100644 --- a/soy/pages.soy +++ b/soy/pages.soy @@ -1389,8 +1389,8 @@ * Renders the list of tenants to select. */ {template .selectTenant} - {@param tenantConfigs: list<[tenantId:string|null, displayName:string, buttonColor:string, - iconUrl: string]>} /** List of tenant selection button configs. */ + {@param tenantConfigs: list<[tenantId:string|null, fullLabel:string|null, + displayName:string, buttonColor:string, iconUrl: string]>} /** List of tenant selection button configs. */
diff --git a/soy/pages_test.js b/soy/pages_test.js index 788c70c0..142cea20 100644 --- a/soy/pages_test.js +++ b/soy/pages_test.js @@ -813,7 +813,22 @@ function testTenantSelect() { displayName: 'ACME', buttonColor: '#53B2BF', iconUrl: 'icon-url', - }], + }, + { + tenantId: 'TENANT_1', + fullLabel: 'Contractor Login', + displayName: 'OIDC', + buttonColor: '#4666FF', + iconUrl: 'icon-url', + }, + { + tenantId: 'TENANT_2', + fullLabel: null, + displayName: 'ACME Corp', + buttonColor: '#2F2B2E', + iconUrl: 'icon-url', + }, + ], }, IJ_DATA_); } diff --git a/types/index.d.ts b/types/index.d.ts index f74c68dd..4ec7230d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -126,6 +126,7 @@ declare namespace firebaseui.auth { } interface TenantConfig extends firebaseui.auth.Config { + fullLabel?: string; displayName?: string; buttonColor?: string; iconUrl?: string; From 933958a7d7ae5ccf1dcad03143fded8cdb5c42bd Mon Sep 17 00:00:00 2001 From: Xin Li Date: Tue, 28 Jul 2020 10:36:39 -0700 Subject: [PATCH 10/11] fix1 --- CHANGELOG.md | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60969879..d08c29ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -* Allow fullLabel customization for tenant selection buttons in FirebaseUI for IAP. +* Allow 'fullLabel' customization for tenant selection buttons in FirebaseUI for IAP. diff --git a/README.md b/README.md index b50b72d9..8db7f226 100644 --- a/README.md +++ b/README.md @@ -1509,7 +1509,7 @@ ui.start('#firebaseui-auth-container', { For [GCIP](https://cloud.google.com/identity-platform) customers, you can build a tenant-specific sign-in page with FirebaseUI. Make sure you've enabled multi-tenancy for your project and configured your tenants. See the -[Multi-tenancy quickstart](https://cloud.google.com/identity-platform/docs/quickstart-multi-tenancy) +[Multi-tenancy quickstart](https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart) to learn how. This feature requires [firebase](https://www.npmjs.com/package/firebase) version 6.6.0 or higher. @@ -1536,7 +1536,7 @@ You can refer to the example in this [guide](https://cloud.google.com/identity-platform/docs/multi-tenancy-ui). There is also a -[quickstart](https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart) +[quickstart](https://github.com/firebase/quickstart-js/blob/master/auth/multi-tenant-ui.html) app available to demonstrate how to build a single sign-in page with the FirebaseUI for two tenants which have different sets of identity providers enabled. From d8c7f6220352c35118f8ff7084d356292de480d1 Mon Sep 17 00:00:00 2001 From: Xin Li Date: Tue, 28 Jul 2020 13:28:18 -0700 Subject: [PATCH 11/11] edit changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d08c29ca..8f1feddd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1 @@ -* Allow 'fullLabel' customization for tenant selection buttons in FirebaseUI for IAP. +* Allow `fullLabel` customization for tenant selection buttons in FirebaseUI for IAP.