Skip to content

Commit 3384d04

Browse files
Fixed operation not supported error for password only apps in a Cordova environment. (#113)
As only password providers are supported, the operation not supported error should not be shown when getRedirectResult is called.
1 parent 9cc5e13 commit 3384d04

File tree

5 files changed

+163
-3
lines changed

5 files changed

+163
-3
lines changed

javascript/widgets/handler/callback.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ firebaseui.auth.widget.handler.handleCallback =
9292
firebaseui.auth.widget.handler.handleCallbackFailure_(
9393
app, component, /** @type {!Error} */ (error));
9494
}
95+
} else if (error &&
96+
error['code'] == 'auth/operation-not-supported-in-this-environment' &&
97+
firebaseui.auth.widget.handler.common.isPasswordProviderOnly(app)) {
98+
// Operation is not supported in this environment but only password
99+
// provider is enabled. So allow this to proceed as a no redirect result.
100+
// This will allow developers using password sign-in in Cordova to use
101+
// FirebaseUI.
102+
firebaseui.auth.widget.handler.handleCallbackResult_(
103+
app,
104+
component,
105+
{
106+
'user': null
107+
});
95108
} else {
96109
// Go to the sign-in page with info bar error.
97110
firebaseui.auth.widget.handler.handleCallbackFailure_(

javascript/widgets/handler/callback_test.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,3 +1799,97 @@ function testHandleCallback_nullUser_emailAuthOnly_acUnavailable() {
17991799
});
18001800
}
18011801

1802+
1803+
function testHandleCallback_operationNotSupported_multiProviders() {
1804+
// Test when callback handler is triggered with multiple providers and
1805+
// the operation is not supported in this environment.
1806+
asyncTestCase.waitForSignals(1);
1807+
// Set mutliple providers.
1808+
app.setConfig({
1809+
'signInOptions': [
1810+
firebase.auth.EmailAuthProvider.PROVIDER_ID,
1811+
firebase.auth.GoogleAuthProvider.PROVIDER_ID
1812+
]
1813+
});
1814+
// Callback rendered.
1815+
firebaseui.auth.widget.handler.handleCallback(app, container);
1816+
assertCallbackPage();
1817+
// Attempting to get redirect result. Reject with an operation not supported
1818+
// error.
1819+
testAuth.assertGetRedirectResult([], null, operationNotSupportedError);
1820+
testAuth.process().then(function() {
1821+
// Any pending credential should be cleared from storage.
1822+
assertFalse(firebaseui.auth.storage.hasPendingEmailCredential(
1823+
app.getAppId()));
1824+
// Redirect to the provider's sign-in page.
1825+
assertProviderSignInPage();
1826+
// Show error in info bar.
1827+
assertInfoBarMessage(
1828+
firebaseui.auth.widget.handler.common.getErrorMessage(
1829+
operationNotSupportedError));
1830+
asyncTestCase.signal();
1831+
});
1832+
}
1833+
1834+
1835+
function testHandleCallback_operationNotSupported_passwordOnly_acDisabled() {
1836+
// Test when callback handler is triggered with only a password provider and
1837+
// the operation is not supported in this environment.
1838+
asyncTestCase.waitForSignals(1);
1839+
// Set password only provider.
1840+
// Test with accountchooser.com disabled.
1841+
app.setConfig({
1842+
'credentialHelper': firebaseui.auth.CredentialHelper.NONE,
1843+
'signInOptions': [firebase.auth.EmailAuthProvider.PROVIDER_ID]
1844+
});
1845+
// Callback rendered.
1846+
firebaseui.auth.widget.handler.handleCallback(app, container);
1847+
assertCallbackPage();
1848+
// Attempting to get redirect result. Reject with an operation not supported
1849+
// error.
1850+
testAuth.assertGetRedirectResult([], null, operationNotSupportedError);
1851+
testAuth.process().then(function() {
1852+
// No message should be displayed.
1853+
assertNoInfoBarMessage();
1854+
// Redirect to the sign-in page with no error message.
1855+
assertSignInPage();
1856+
assertFalse(firebaseui.auth.storage.hasPendingEmailCredential(
1857+
app.getAppId()));
1858+
asyncTestCase.signal();
1859+
});
1860+
}
1861+
1862+
1863+
function testHandleCallback_operationNotSupported_passwordOnly_acEnabled() {
1864+
// Test when callback handler is triggered with only a password provider and
1865+
// the operation is not supported in this environment.
1866+
asyncTestCase.waitForSignals(1);
1867+
// Set password only provider.
1868+
// Test with accountchooser.com enabled.
1869+
app.setConfig({
1870+
'credentialHelper': firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM,
1871+
'signInOptions': [firebase.auth.EmailAuthProvider.PROVIDER_ID]
1872+
});
1873+
// Simulate empty response from accountchooser.com click.
1874+
testAc.setSkipSelect(true);
1875+
// Callback rendered.
1876+
firebaseui.auth.widget.handler.handleCallback(app, container);
1877+
assertCallbackPage();
1878+
// Attempting to get redirect result. Reject with an operation not supported
1879+
// error.
1880+
testAuth.assertGetRedirectResult([], null, operationNotSupportedError);
1881+
testAuth.process().then(function() {
1882+
// Try select should be called.
1883+
testAc.assertTrySelectAccount(
1884+
firebaseui.auth.storage.getRememberedAccounts(app.getAppId()),
1885+
'http://localhost/firebaseui-widget?mode=select');
1886+
// Redirect to the sign-in page with no error message.
1887+
assertSignInPage();
1888+
assertFalse(firebaseui.auth.storage.hasPendingEmailCredential(
1889+
app.getAppId()));
1890+
// No message should be displayed.
1891+
assertNoInfoBarMessage();
1892+
asyncTestCase.signal();
1893+
});
1894+
}
1895+

javascript/widgets/handler/common.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,21 @@ firebaseui.auth.widget.handler.common.handleUnrecoverableError = function(
803803
};
804804

805805

806+
/**
807+
* Helper function to check if a FirebaseUI instance only supports password
808+
* providers.
809+
* @param {firebaseui.auth.AuthUI} app The current FirebaseUI instance whose
810+
* configuration is used.
811+
* @return {boolean} Whether only password providers are supported by the app's
812+
* current configuration.
813+
*/
814+
firebaseui.auth.widget.handler.common.isPasswordProviderOnly = function(app) {
815+
var providers = app.getConfig().getProviders();
816+
return providers.length == 1 &&
817+
providers[0] == firebase.auth.EmailAuthProvider.PROVIDER_ID;
818+
};
819+
820+
806821
/**
807822
* Calls the appropriate sign-in start handler depending on display mode.
808823
*
@@ -814,9 +829,7 @@ firebaseui.auth.widget.handler.common.handleUnrecoverableError = function(
814829
*/
815830
firebaseui.auth.widget.handler.common.handleSignInStart = function(
816831
app, container, opt_email, opt_infoBarMessage) {
817-
var providers = app.getConfig().getProviders();
818-
if (providers.length == 1 &&
819-
providers[0] == firebase.auth.EmailAuthProvider.PROVIDER_ID) {
832+
if (firebaseui.auth.widget.handler.common.isPasswordProviderOnly(app)) {
820833
// If info bar message is available, do not go to accountchooser.com since
821834
// this is a result of some error in the flow and the error message must be
822835
// displayed.

javascript/widgets/handler/common_test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,3 +1604,37 @@ function testGetErrorMessage_unknownError_jsonMessage() {
16041604
firebaseui.auth.log.error.getLastCall().getArgument(0));
16051605
assertEquals('An internal error has occurred.', message);
16061606
}
1607+
1608+
1609+
function testIsPasswordProviderOnly_multipleMixedProviders() {
1610+
// Set a password and federated providers in the FirebaseUI instance
1611+
// configuration.
1612+
app.updateConfig(
1613+
'signInOptions',
1614+
[
1615+
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
1616+
firebase.auth.EmailAuthProvider.PROVIDER_ID
1617+
]);
1618+
assertFalse(
1619+
firebaseui.auth.widget.handler.common.isPasswordProviderOnly(app));
1620+
}
1621+
1622+
1623+
function testIsPasswordProviderOnly_singlePasswordProvider() {
1624+
// Set a password only provider in the FirebaseUI instance configuration.
1625+
app.updateConfig(
1626+
'signInOptions',
1627+
[firebase.auth.EmailAuthProvider.PROVIDER_ID]);
1628+
assertTrue(
1629+
firebaseui.auth.widget.handler.common.isPasswordProviderOnly(app));
1630+
}
1631+
1632+
1633+
function testIsPasswordProviderOnly_singleFederatedProvider() {
1634+
// Set a federated only provider in the FirebaseUI instance configuration.
1635+
app.updateConfig(
1636+
'signInOptions',
1637+
[firebase.auth.GoogleAuthProvider.PROVIDER_ID]);
1638+
assertFalse(
1639+
firebaseui.auth.widget.handler.common.isPasswordProviderOnly(app));
1640+
}

javascript/widgets/handler/testhelper.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ var internalError = {
8181
'code': 'auth/internal-error',
8282
'message': 'An internal error occurred.'
8383
};
84+
var operationNotSupportedError = {
85+
'code': 'auth/operation-not-supported-in-this-environment',
86+
'message': 'This operation is not supported in the environment this ' +
87+
'application is running on. "location.protocol" must be http, https ' +
88+
'or chrome-extension and web storage must be enabled.'
89+
};
8490

8591
var container;
8692
var container2;

0 commit comments

Comments
 (0)