Skip to content

Commit 481fc2c

Browse files
authored
Release updates on accountchooser.com warnings & fix RTL spinner (#724)
* release updates on accountchooser.com warnings & fix RTL spinner.
1 parent 18b5dd2 commit 481fc2c

File tree

15 files changed

+153
-36
lines changed

15 files changed

+153
-36
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* Fixes FirebaseUI-web spinner for RTL languages.
2+
* Log warning on accountchooser.com being deprecated and switching to universal opt-out mode starting in July 31st, 2020.

README.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,10 @@ FirebaseUI includes the following flows:
139139
*"One account per email address"* setting is enabled in the
140140
[Firebase console](https://console.firebase.google.com). This setting is enabled
141141
by default.)
142-
6. [Account Chooser](https://www.accountchooser.com/learnmore.html?lang=en) for
143-
remembering emails
144-
7. Integration with
142+
6. Integration with
145143
[one-tap sign-up](https://developers.google.com/identity/one-tap/web/)
146-
8. Ability to upgrade anonymous users through sign-in/sign-up.
147-
9. Sign-in as a guest
144+
7. Ability to upgrade anonymous users through sign-in/sign-up.
145+
8. Sign-in as a guest
148146

149147
### Configuring sign-in providers
150148

@@ -364,8 +362,11 @@ FirebaseUI supports the following configuration parameters.
364362
The Credential Helper to use.
365363
See <a href="#credential-helper">Credential Helper</a>.
366364
<br/>
367-
<em>Default:</em>
365+
<em>Default (before July 31st, 2020):</em>
368366
<code>firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM</code>
367+
<br/>
368+
<em>Default (after July 31st, 2020):</em>
369+
<code>firebaseui.auth.CredentialHelper.NONE</code>
369370
</td>
370371
</tr>
371372
<tr>
@@ -458,6 +459,9 @@ FirebaseUI supports the following credential helpers:
458459
- [accountchooser.com](https://www.accountchooser.com/learnmore.html)
459460

460461
#### accountchooser.com
462+
(`accountchooser.com` will be operating in "universal opt-out" mode
463+
starting July 31st, 2020, it should no longer be used as a `CredentialHelper`.
464+
Learn more at https://accountchooser.net/developers.)
461465

462466
When [accountchooser.com](https://www.accountchooser.com/learnmore.html) is
463467
enabled (enabled by default), upon signing in or
@@ -526,11 +530,11 @@ being rendered after the user signs out.
526530
To see FirebaseUI in action with one-tap sign-up, check out the FirebaseUI
527531
[demo app](https://fir-ui-demo-84a6c.firebaseapp.com/).
528532

529-
|Credential Helper |Value |
530-
|------------------|------------------------------------------------------|
531-
|accountchooser.com|`firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM`|
532-
|One-tap sign-up |`firebaseui.auth.CredentialHelper.GOOGLE_YOLO` |
533-
|None (disable) |`firebaseui.auth.CredentialHelper.NONE` |
533+
|Credential Helper |Value |
534+
|----------------------------------|------------------------------------------------------|
535+
|accountchooser.com (deprecated) |`firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM`|
536+
|One-tap sign-up |`firebaseui.auth.CredentialHelper.GOOGLE_YOLO` |
537+
|None (disable) |`firebaseui.auth.CredentialHelper.NONE` |
534538

535539
### Available providers
536540

@@ -1274,7 +1278,7 @@ FirebaseUI is displayed.
12741278
document.getElementById('loader').style.display = 'none';
12751279
}
12761280
},
1277-
credentialHelper: firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM,
1281+
credentialHelper: firebaseui.auth.CredentialHelper.NONE,
12781282
// Query parameter name for mode.
12791283
queryParameterForWidgetMode: 'mode',
12801284
// Query parameter name for sign in success url.

demo/public/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ function getUiConfig() {
8383
'privacyPolicyUrl': 'https://www.google.com',
8484
'credentialHelper': CLIENT_ID && CLIENT_ID != 'YOUR_OAUTH_CLIENT_ID' ?
8585
firebaseui.auth.CredentialHelper.GOOGLE_YOLO :
86-
firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM
86+
firebaseui.auth.CredentialHelper.NONE
8787
};
8888
}
8989

demo/public/widget.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
'tosUrl': 'https://www.google.com',
6666
'credentialHelper': CLIENT_ID && CLIENT_ID != 'YOUR_OAUTH_CLIENT_ID' ?
6767
firebaseui.auth.CredentialHelper.GOOGLE_YOLO :
68-
firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM
68+
firebaseui.auth.CredentialHelper.NONE
6969
};
7070

7171
// Initialize the FirebaseUI Widget using Firebase.

javascript/testing/auth.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class FakeAuthClient extends MockHelper {
115115
*/
116116
onAuthStateChanged(nextOrObserver, opt_error, opt_completed) {
117117
// Simplified version of the observer for testing purpose only.
118-
var observer = (goog.isFunction(nextOrObserver) && nextOrObserver) ||
118+
var observer = (typeof nextOrObserver === 'function' && nextOrObserver) ||
119119
nextOrObserver['next'];
120120
if (!observer) {
121121
throw 'onAuthStateChanged must be called with an Observer or up to three ' +
@@ -154,7 +154,7 @@ class FakeAuthClient extends MockHelper {
154154
*/
155155
onIdTokenChanged(nextOrObserver, opt_error, opt_completed) {
156156
// Simplified version of the observer for testing purpose only.
157-
var observer = (goog.isFunction(nextOrObserver) && nextOrObserver) ||
157+
var observer = (typeof nextOrObserver === 'function' && nextOrObserver) ||
158158
nextOrObserver['next'];
159159
if (!observer) {
160160
throw 'onIdTokenChanged must be called with an Observer or up to three ' +

javascript/testing/mockhelper.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,13 @@ class MockHelper extends Disposable {
196196
// Resolve API promise if not already resolved.
197197
resolveAssert();
198198
if (error) {
199-
if (goog.isFunction(error)) {
199+
if (typeof error === 'function') {
200200
req['reject'](error());
201201
} else {
202202
req['reject'](error);
203203
}
204204
} else {
205-
if (goog.isFunction(resp)) {
205+
if (typeof resp === 'function') {
206206
req['resolve'](resp());
207207
} else {
208208
req['resolve'](resp);

javascript/utils/acclient.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ firebaseui.auth.acClient.DummyApi = class {
231231
* Triggers the onEmpty callback.
232232
*/
233233
fireOnEmpty() {
234-
if (goog.isFunction(this.config_['callbacks']['empty'])) {
234+
if (typeof this.config_['callbacks']['empty'] === 'function') {
235235
this.config_['callbacks']['empty']();
236236
}
237237
}
@@ -245,7 +245,7 @@ firebaseui.auth.acClient.DummyApi = class {
245245
* @param {Object=} opt_config The optional client configuration.
246246
*/
247247
store(accounts, opt_config) {
248-
if (goog.isFunction(this.config_['callbacks']['store'])) {
248+
if (typeof this.config_['callbacks']['store'] === 'function') {
249249
this.config_['callbacks']['store'](
250250
undefined, firebaseui.auth.acClient.DummyApi.UNAVAILABLE_ERROR_);
251251
}
@@ -260,7 +260,7 @@ firebaseui.auth.acClient.DummyApi = class {
260260
* @param {Object=} opt_config The optional client configuration.
261261
*/
262262
select(accounts, opt_config) {
263-
if (goog.isFunction(this.config_['callbacks']['select'])) {
263+
if (typeof this.config_['callbacks']['select'] === 'function') {
264264
this.config_['callbacks']['select'](
265265
undefined, firebaseui.auth.acClient.DummyApi.UNAVAILABLE_ERROR_);
266266
}
@@ -275,7 +275,7 @@ firebaseui.auth.acClient.DummyApi = class {
275275
* @param {Object=} opt_config The optional client configuration.
276276
*/
277277
update(account, opt_config) {
278-
if (goog.isFunction(this.config_['callbacks']['update'])) {
278+
if (typeof this.config_['callbacks']['update'] === 'function') {
279279
this.config_['callbacks']['update'](
280280
undefined, firebaseui.auth.acClient.DummyApi.UNAVAILABLE_ERROR_);
281281
}

javascript/widgets/config.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ class Config {
528528
'Privacy Policy URL is missing, the link will not be displayed.');
529529
}
530530
if (tosUrl && privacyPolicyUrl) {
531-
if (goog.isFunction(tosUrl)) {
531+
if (typeof tosUrl === 'function') {
532532
return /** @type {function()} */ (tosUrl);
533533
} else if (typeof tosUrl === 'string') {
534534
return () => {
@@ -554,7 +554,7 @@ class Config {
554554
'Term of Service URL is missing, the link will not be displayed.');
555555
}
556556
if (tosUrl && privacyPolicyUrl) {
557-
if (goog.isFunction(privacyPolicyUrl)) {
557+
if (typeof privacyPolicyUrl === 'function') {
558558
return /** @type {function()} */ (privacyPolicyUrl);
559559
} else if (typeof privacyPolicyUrl === 'string') {
560560
return () => {
@@ -769,10 +769,7 @@ class Config {
769769
}
770770

771771
/**
772-
* TODO: for now, only accountchooser.com is available and all logic related
773-
* to credential helper relies on it, so this method is provided for ease of
774-
* use. It should be removed in the future when FirebaseUI supports several
775-
* credential helpers.
772+
* TODO: Remove during accountchooser.com opt-out period.
776773
* @return {boolean} Whether accountchooser.com is enabled.
777774
*/
778775
isAccountChooserEnabled() {
@@ -792,10 +789,16 @@ class Config {
792789
return Config.CredentialHelper.NONE;
793790
}
794791
const credentialHelper = this.config_.get('credentialHelper');
792+
if (credentialHelper === Config.CredentialHelper.ACCOUNT_CHOOSER_COM) {
793+
log.warning(
794+
'AccountChooser.com will be operating in "universal opt-out" mode ' +
795+
'starting July 31st, 2020, ' +
796+
'it should no longer be used as a CredentialHelper.' +
797+
' Learn more at https://accountchooser.net/developers');
798+
}
795799
// Make sure the credential helper is valid.
796800
for (let key in Config.CredentialHelper) {
797-
if (Config.CredentialHelper[key] ==
798-
credentialHelper) {
801+
if (Config.CredentialHelper[key] === credentialHelper) {
799802
// Return valid flow.
800803
return Config.CredentialHelper[key];
801804
}

javascript/widgets/config_test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,34 @@ testSuite({
14881488
assertArrayEquals([], warningLogMessages);
14891489
},
14901490

1491+
testAccountChooserWarningMessage() {
1492+
const expectedWarningMessage = 'AccountChooser.com will be operating ' +
1493+
'in "universal opt-out" mode starting July 31st, 2020, ' +
1494+
'it should no longer be used as a CredentialHelper. ' +
1495+
'Learn more at https://accountchooser.net/developers';
1496+
config.update(
1497+
'credentialHelper', Config.CredentialHelper.ACCOUNT_CHOOSER_COM);
1498+
assertEquals(
1499+
Config.CredentialHelper.ACCOUNT_CHOOSER_COM,
1500+
config.getCredentialHelper());
1501+
assertArrayEquals([expectedWarningMessage], warningLogMessages);
1502+
1503+
// Reset warnings.
1504+
warningLogMessages = [];
1505+
config.update(
1506+
'credentialHelper', Config.CredentialHelper.GOOGLE_YOLO);
1507+
assertEquals(
1508+
Config.CredentialHelper.GOOGLE_YOLO,
1509+
config.getCredentialHelper());
1510+
assertArrayEquals([], warningLogMessages);
1511+
1512+
// Reset warnings.
1513+
warningLogMessages = [];
1514+
config.update('credentialHelper', Config.CredentialHelper.NONE);
1515+
assertEquals(Config.CredentialHelper.NONE, config.getCredentialHelper());
1516+
assertArrayEquals([], warningLogMessages);
1517+
},
1518+
14911519
testGetCredentialHelper_httpOrHttps() {
14921520
// Test credential helper configuration setting, as well as the
14931521
// accountchooser.com enabled helper method, in a HTTP or HTTPS environment.

javascript/widgets/firebaseuihandler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ class FirebaseUiHandler {
544544
const message = getLocalizedErrorMessage(error['code']) || error['message'];
545545
this.disposeCurrentComponent_();
546546
let onRetryClick;
547-
if (error['retry'] && goog.isFunction(error['retry'])) {
547+
if (error['retry'] && typeof error['retry'] === 'function') {
548548
onRetryClick = () => {
549549
this.reset();
550550
error['retry']();

javascript/widgets/handler/common.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,14 @@ firebaseui.auth.widget.handler.common.acForceUiShown_ = false;
7777
*/
7878
firebaseui.auth.widget.handler.common.acLoader_ = null;
7979

80+
/**
81+
* Resets accountchooser.com loader and removes global accountchooser namespace.
82+
* This is useful for testing.
83+
*/
84+
firebaseui.auth.widget.handler.common.resetAcLoader = function() {
85+
firebaseui.auth.widget.handler.common.acLoader_ = null;
86+
goog.global['accountchooser'] = undefined;
87+
};
8088

8189
/**
8290
* Loads the accountchooser.com client library if it is not loaded before and

javascript/widgets/handler/common_test.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ goog.require('firebaseui.auth.widget.handler.handleSignIn');
4848
goog.require('firebaseui.auth.widget.handler.testHelper');
4949
goog.require('goog.Promise');
5050
goog.require('goog.dom.forms');
51+
goog.require('goog.net.jsloader');
5152
goog.require('goog.testing.AsyncTestCase');
5253
goog.require('goog.testing.recordFunction');
5354

@@ -1893,6 +1894,61 @@ function testHandleSignInWithEmail_acNotEnabled() {
18931894
}
18941895

18951896

1897+
function testHandleSignInWithEmail_accountChooserNotFound() {
1898+
// This tests when accountchooser.com JS dependency fails to load
1899+
// that the flow continues to work as expected. This test is needed
1900+
// to confirm that after accountchooser.com is shutdown, the library
1901+
// continues to work.
1902+
1903+
// This is the actual error that gets thrown when jsloader fails to load.
1904+
const expectedError = new Error(
1905+
'Jsloader error (code #0): Error while loading script ' +
1906+
'//www.gstatic.com/accountchooser/client.js');
1907+
// Uninstall mock acClient. It is better to test the real thing to ensure
1908+
// that when the dependency fails to load, the flow will continue to work.
1909+
testAc.uninstall();
1910+
firebaseui.auth.widget.handler.common.resetAcLoader();
1911+
// Track that loading error is triggered.
1912+
let errorTriggered = false;
1913+
// Simulate accountchooser.com dependency not found and jsloader failing.
1914+
testStubs.reset();
1915+
// Assume widget already rendered and AuthUI global reference set.
1916+
testStubs.replace(firebaseui.auth.AuthUI, 'getAuthUi', function() {
1917+
return app;
1918+
});
1919+
testStubs.set(firebaseui.auth.util, 'supportsCors', function() {
1920+
return true;
1921+
});
1922+
// Simulate the loading error.
1923+
testStubs.replace(
1924+
goog.net.jsloader, 'safeLoad', function() {
1925+
errorTriggered = true;
1926+
return goog.Promise.reject(expectedError);
1927+
});
1928+
1929+
// Start sign-in with email handler.
1930+
// signIn page should be rendered despite accountchooser.com JS dependencies
1931+
// failing to load.
1932+
app.setConfig({
1933+
'credentialHelper':
1934+
firebaseui.auth.widget.Config.CredentialHelper.ACCOUNT_CHOOSER_COM,
1935+
});
1936+
firebaseui.auth.widget.handler.common.handleSignInWithEmail(app, container);
1937+
asyncTestCase.waitForSignals(1);
1938+
1939+
// Wait 2 cycles to give enough time for logic to run.
1940+
return goog.Promise.resolve().then(() => {
1941+
return goog.Promise.resolve();
1942+
}).then(() => {
1943+
// Confirm error triggered.
1944+
assertTrue(errorTriggered);
1945+
// signIn page should be rendered.
1946+
assertSignInPage();
1947+
asyncTestCase.signal();
1948+
});
1949+
}
1950+
1951+
18961952
function testHandleSignInWithEmail_prefillEmail() {
18971953
const prefilledEmail = 'user@example';
18981954
testStubs.replace(

javascript/widgets/handler/testhelper.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -889,15 +889,15 @@ function assertTosPpLinkClicked_(tosUrl, privacyPolicyUrl) {
889889
'firebaseui-tos-link', container);
890890
var ppLinkElement = goog.dom.getElementByClass(
891891
'firebaseui-pp-link', container);
892-
if (goog.isFunction(tosUrl)) {
892+
if (typeof tosUrl === 'function') {
893893
assertEquals(0, tosUrl.getCallCount());
894894
goog.testing.events.fireClickSequence(tosLinkElement);
895895
assertEquals(1, tosUrl.getCallCount());
896896
} else {
897897
goog.testing.events.fireClickSequence(tosLinkElement);
898898
testUtil.assertOpen(tosUrl, '_blank');
899899
}
900-
if (goog.isFunction(privacyPolicyUrl)) {
900+
if (typeof privacyPolicyUrl === 'function') {
901901
assertEquals(0, privacyPolicyUrl.getCallCount());
902902
goog.testing.events.fireClickSequence(ppLinkElement);
903903
assertEquals(1, privacyPolicyUrl.getCallCount());

package-lock.json

Lines changed: 18 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

stylesheet/firebase-ui.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ input.firebaseui-input-invalid{
499499
}
500500

501501
.mdl-spinner.firebaseui-busy-indicator {
502+
direction: initial;
502503
height: 56px;
503504
left: 0px;
504505
margin: auto;

0 commit comments

Comments
 (0)