Skip to content

Commit 271f012

Browse files
authored
feat: Implement adminRestrictedOperation config to support disabling multiple providers (#857)
* Implement adminRestrictedOpeartion config to support disabling multiple providers.
1 parent 7df4278 commit 271f012

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+8518
-4676
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* Improved UI support for all identity provider sign up operations when they are restricted by site administrators.

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,30 @@ FirebaseUI supports the following configuration parameters.
447447
when Privacy Policy link is clicked.
448448
</td>
449449
</tr>
450+
<tr>
451+
<td>adminRestrictedOperation</td>
452+
<td>No</td>
453+
<td>
454+
The object for configuring `adminRestrictedOperation` options, contains 3
455+
fields:
456+
`status(boolean)`: This flag should mirror the project user actions
457+
("Enable create") settings. When sign-up is disabled in the project settings,
458+
this should be set to `true`. Setting this to `true` without disabling sign-up
459+
in the project settings will not have any effect. For GCIP projects, this is
460+
done by going to the "Settings" page in the "Identity Platform" section in the
461+
Cloud Console. Under the "USERS" tab, go to "User actions". Uncheck "Enable
462+
create (sign-up)" and click "SAVE".
463+
This does not enforce the policy but is rather useful for providing additional
464+
instructions to the end user when a user tries to create a new user account
465+
and the Auth server blocks the operation. This boolean works on all providers
466+
(federated, email/password, email link and phone number).
467+
`adminEmail(string|undefined)`: The optional site administrator email to
468+
contact for access when sign up is disabled, for example: `[email protected]`.
469+
`helpLink(string|undefined)`: The optional help link to provide information
470+
on how to get access to the site when sign up is disabled. For example:
471+
`https://www.example.com/trouble_signing_in`.
472+
</td>
473+
</tr>
450474
</tbody>
451475
</table>
452476

demo/public/app.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ function getUiConfig() {
8686
'privacyPolicyUrl': 'https://www.google.com',
8787
'credentialHelper': CLIENT_ID && CLIENT_ID != 'YOUR_OAUTH_CLIENT_ID' ?
8888
firebaseui.auth.CredentialHelper.GOOGLE_YOLO :
89-
firebaseui.auth.CredentialHelper.NONE
89+
firebaseui.auth.CredentialHelper.NONE,
90+
'adminRestrictedOperation': {
91+
status: getAdminRestrictedOperationStatus()
92+
}
9093
};
9194
}
9295

@@ -101,7 +104,9 @@ ui.disableAutoSignIn();
101104
*/
102105
function getWidgetUrl() {
103106
return '/widget#recaptcha=' + getRecaptchaMode() + '&emailSignInMethod=' +
104-
getEmailSignInMethod();
107+
getEmailSignInMethod() + '&disableEmailSignUpStatus=' +
108+
getDisableSignUpStatus() + '&adminRestrictedOperationStatus=' +
109+
getAdminRestrictedOperationStatus();
105110
}
106111

107112

@@ -196,10 +201,14 @@ function handleConfigChange() {
196201
'input[name="emailSignInMethod"]:checked').value;
197202
var currentDisableSignUpStatus =
198203
document.getElementById("email-disableSignUp-status").checked;
204+
var currentAdminRestrictedOperationStatus =
205+
document.getElementById("admin-restricted-operation-status").checked;
199206
location.replace(
200207
location.pathname + '#recaptcha=' + newRecaptchaValue +
201208
'&emailSignInMethod=' + newEmailSignInMethodValue +
202-
'&disableEmailSignUpStatus=' + currentDisableSignUpStatus);
209+
'&disableEmailSignUpStatus=' + currentDisableSignUpStatus +
210+
'&adminRestrictedOperationStatus=' +
211+
currentAdminRestrictedOperationStatus);
203212
// Reset the inline widget so the config changes are reflected.
204213
ui.reset();
205214
ui.start('#firebaseui-container', getUiConfig());
@@ -243,6 +252,10 @@ var initApp = function() {
243252
'change', handleConfigChange);
244253
document.getElementById("email-disableSignUp-status").checked =
245254
getDisableSignUpStatus();
255+
document.getElementById('admin-restricted-operation-status').addEventListener(
256+
'change', handleConfigChange);
257+
document.getElementById("admin-restricted-operation-status").checked =
258+
getAdminRestrictedOperationStatus();
246259
};
247260

248261
window.addEventListener('load', initApp);

demo/public/common.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ function getDisableSignUpStatus() {
4545
}
4646

4747

48+
/**
49+
* @return {boolean} The admin restricted operation status from the configuration.
50+
*/
51+
function getAdminRestrictedOperationStatus() {
52+
var config = parseQueryString(location.hash);
53+
return config['adminRestrictedOperationStatus'] === 'true';
54+
}
55+
56+
4857
/**
4958
* @param {string} queryString The full query string.
5059
* @return {!Object<string, string>} The parsed query parameters.

demo/public/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ <h4>You are signed out.</h4>
6060
</label><br>
6161
<label for="disableEmailSignUpStatus">Disable email sign up:</label>
6262
<input type="checkbox" id="email-disableSignUp-status" name="disableEmailSignUpStatus">
63+
<label for="adminRestrictedOperationStatus">Admin restricted operation status:</label>
64+
<input type="checkbox" id="admin-restricted-operation-status" name="adminRestrictedOperationStatus">
6365
</fieldset>
6466
<p>
6567
<button id="sign-in-with-redirect">Sign In with Redirect</button>

demo/public/widget.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@
6868
'tosUrl': 'https://www.google.com',
6969
'credentialHelper': CLIENT_ID && CLIENT_ID != 'YOUR_OAUTH_CLIENT_ID' ?
7070
firebaseui.auth.CredentialHelper.GOOGLE_YOLO :
71-
firebaseui.auth.CredentialHelper.NONE
71+
firebaseui.auth.CredentialHelper.NONE,
72+
'adminRestrictedOperation': {
73+
status: getAdminRestrictedOperationStatus()
74+
}
7275
};
7376

7477
// Initialize the FirebaseUI Widget using Firebase.

externs/firebaseui-externs.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,18 @@ firebaseui.auth.Config.prototype.privacyPolicyUrl;
603603
*/
604604
firebaseui.auth.Config.prototype.widgetUrl;
605605

606+
/**
607+
* The configuration mirroring the project user actions ("Enable create")
608+
* settings. When sign-up is disabled in the project settings, this
609+
* configuration should be provided with the status field set to `true`. This
610+
* does not enforce the policy but is rather useful for providing additional
611+
* instructions to the end user when a user tries to create a new user account
612+
* and the Auth server blocks the operation.
613+
*
614+
* @type {firebaseui.auth.DisableSignUpConfig|undefined}
615+
*/
616+
firebaseui.auth.Config.prototype.adminRestrictedOperation;
617+
606618

607619
/**
608620
* The tenant level CIAP configuration settings.
@@ -931,15 +943,16 @@ firebaseui.auth.OidcSignInOption.prototype.customParameters;
931943

932944

933945
/**
934-
* Defines configurations for disabling email sign up.
946+
* Defines the configuration for how to handle errors associated with disabling
947+
* users from signing up using FirebaseUI.
935948
*
936949
* @interface
937950
*/
938951
firebaseui.auth.DisableSignUpConfig = function() {};
939952

940953
/**
941-
* Whether new user sign up with email/password or email link is disabled.
942-
* The default is false.
954+
* Whether a new user is unable to sign up in FirebaseUI. This is true when a
955+
* new user cannot sign up, false otherwise.
943956
*
944957
* @type {boolean}
945958
*/

javascript/data/country_test.js

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ goog.setTestOnly('firebaseui.auth.data.countryTest');
2020

2121
goog.require('firebaseui.auth.data.country');
2222
goog.require('firebaseui.auth.data.country.LookupTree');
23-
goog.require('goog.array');
2423
goog.require('goog.testing.jsunit');
2524
goog.require('goog.userAgent');
2625
goog.require('goog.userAgent.product');
@@ -33,16 +32,11 @@ goog.require('goog.userAgent.product');
3332
* @param {string} locale
3433
*/
3534
function assertSortCountryListForLocale(sortedNames, inputNames, locale) {
36-
var countryList = goog.array.map(inputNames, function(name) {
37-
return {
38-
name: name,
39-
e164_key: '',
40-
e164_cc: '',
41-
iso2_cc: ''
42-
};
35+
var countryList = inputNames.map(function(name) {
36+
return {name: name, e164_key: '', e164_cc: '', iso2_cc: ''};
4337
});
4438
firebaseui.auth.data.country.sortCountryListForLocale(countryList, locale);
45-
var actualSortedNames = goog.array.map(countryList, function(country) {
39+
var actualSortedNames = countryList.map(function(country) {
4640
return country.name;
4741
});
4842
assertArrayEquals(sortedNames, actualSortedNames);
@@ -55,7 +49,7 @@ function assertSortCountryListForLocale(sortedNames, inputNames, locale) {
5549
* @return {!Array<string>} List of country iso2_cc names.
5650
*/
5751
function getCountryCodesForList(countries) {
58-
return goog.array.map(countries, function(country) {
52+
return countries.map(function(country) {
5953
return country.iso2_cc;
6054
});
6155
}
@@ -158,7 +152,7 @@ function testGetCountriesByIso2() {
158152
*/
159153
function testGetCountriesByIso2_multipleMatches() {
160154
var countries = firebaseui.auth.data.country.getCountriesByIso2('xk');
161-
var actualCodes = goog.array.map(countries, function(country) {
155+
var actualCodes = countries.map(function(country) {
162156
return country.e164_cc;
163157
});
164158
assertSameElements(['377', '381', '386'], actualCodes);
@@ -185,7 +179,7 @@ function testGetCountriesByE164Code() {
185179
*/
186180
function testGetCountriesByE164Code_multipleMatches() {
187181
var countries = firebaseui.auth.data.country.getCountriesByE164Code('44');
188-
var actualKeys = goog.array.map(countries, function(country) {
182+
var actualKeys = countries.map(function(country) {
189183
return country.e164_key;
190184
});
191185
assertSameElements(['44-GG-0', '44-IM-0', '44-JE-0', '44-GB-0'], actualKeys);
@@ -219,7 +213,7 @@ function testGetCountriesByE164eOrIsoCode_iso() {
219213
function testGetCountriesByE164OrIsoCode_e164_multipleMatches() {
220214
var countries =
221215
firebaseui.auth.data.country.getCountriesByE164OrIsoCode('+44');
222-
var actualKeys = goog.array.map(countries, function(country) {
216+
var actualKeys = countries.map(function(country) {
223217
return country.e164_key;
224218
});
225219
assertSameElements(['44-GG-0', '44-IM-0', '44-JE-0', '44-GB-0'], actualKeys);
@@ -229,7 +223,7 @@ function testGetCountriesByE164OrIsoCode_e164_multipleMatches() {
229223
function testGetCountriesByE164OrIsoCode_iso_multipleMatches() {
230224
var countries =
231225
firebaseui.auth.data.country.getCountriesByE164OrIsoCode('xk');
232-
var actualKeys = goog.array.map(countries, function(country) {
226+
var actualKeys = countries.map(function(country) {
233227
return country.e164_key;
234228
});
235229
assertSameElements(['377-XK-0', '381-XK-0', '386-XK-0'], actualKeys);

javascript/ui/element/phoneconfirmationcodetesthelper.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ goog.setTestOnly('firebaseui.auth.ui.element.PhoneConfirmationCodeTestHelper');
2424
goog.require('firebaseui.auth.ui.element');
2525
/** @suppress {extraRequire} Required for test helpers. */
2626
goog.require('firebaseui.auth.ui.element.ElementTestHelper');
27-
goog.require('goog.array');
2827
goog.require('goog.dom.forms');
2928
goog.require('goog.events.KeyCodes');
3029

@@ -75,7 +74,7 @@ element.PhoneConfirmationCodeTestHelper.prototype
7574
'1234567', // too long
7675
'a12356', // char
7776
];
78-
goog.array.forEach(invalidCodes, function(code) {
77+
invalidCodes.forEach(function(code) {
7978
goog.dom.forms.setValue(e, code);
8079
assertNull(this.component.checkAndGetPhoneConfirmationCode());
8180
}, this);
@@ -84,7 +83,7 @@ element.PhoneConfirmationCodeTestHelper.prototype
8483
'123456',
8584
'000123', // leading zeroes
8685
];
87-
goog.array.forEach(validCodes, function(code) {
86+
validCodes.forEach(function(code) {
8887
goog.dom.forms.setValue(e, code);
8988
assertNotNull(this.component.checkAndGetPhoneConfirmationCode());
9089
}, this);

javascript/ui/element/phonenumber.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -228,16 +228,15 @@ element.phoneNumber.isCountryAvailable_ = function(countryId,
228228
* @private
229229
*/
230230
element.phoneNumber.createListBoxItemList_ = function(availableCountries) {
231-
return goog.array.map(availableCountries,
232-
function(country) {
233-
return {
234-
id: country.e164_key,
235-
iconClass: 'firebaseui-flag ' +
236-
element.phoneNumber.getFlagClass_(country),
237-
label: country.name + ' ' +
238-
element.phoneNumber.makeDisplayableCountryCode_(country.e164_cc)
239-
};
240-
});
231+
return availableCountries.map(function(country) {
232+
return {
233+
id: country.e164_key,
234+
iconClass:
235+
'firebaseui-flag ' + element.phoneNumber.getFlagClass_(country),
236+
label: country.name + ' ' +
237+
element.phoneNumber.makeDisplayableCountryCode_(country.e164_cc)
238+
};
239+
});
241240
};
242241

243242

javascript/ui/element/tospptesthelper.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ goog.provide('firebaseui.auth.ui.element.TosPpTestHelper');
2121
goog.setTestOnly('firebaseui.auth.ui.element.TosPpTestHelper');
2222

2323
goog.require('firebaseui.auth.ui.element');
24+
/** @suppress {extraRequire} */
25+
goog.require('firebaseui.auth.ui.element.ElementTestHelper');
2426
goog.require('goog.testing.events');
2527

2628

javascript/ui/mdl.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,10 @@ firebaseui.auth.ui.mdl.performOnMdlComponents_ = function(element, operation) {
6767
!window['componentHandler'][operation]) {
6868
return;
6969
}
70-
goog.array.forEach(firebaseui.auth.ui.mdl.MDL_COMPONENT_CLASSES_,
71-
function(className) {
70+
firebaseui.auth.ui.mdl.MDL_COMPONENT_CLASSES_.forEach(function(className) {
7271
if (goog.dom.classlist.contains(element, className)) {
7372
window['componentHandler'][operation](element);
7473
}
75-
7674
var matchingElements = goog.dom.getElementsByClass(className, element);
7775
goog.array.forEach(matchingElements, function(mdlElement) {
7876
window['componentHandler'][operation](mdlElement);

javascript/ui/page/selecttenant_test.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
goog.module('firebaseui.auth.ui.page.SelectTenantTest');
2020
goog.setTestOnly();
2121

22-
const InfoBarTestHelper =
23-
goog.require('firebaseui.auth.ui.element.InfoBarTestHelper');
22+
2423
const KeyCodes = goog.require('goog.events.KeyCodes');
2524
const MockClock = goog.require('goog.testing.MockClock');
2625
const PageTestHelper = goog.require('firebaseui.auth.ui.page.PageTestHelper');
@@ -35,8 +34,6 @@ const testSuite = goog.require('goog.testing.testSuite');
3534
let mockClock;
3635
let root;
3736
let component;
38-
const infoBarTestHelper =
39-
new InfoBarTestHelper().registerTests();
4037
const tosPpTestHelper = new TosPpTestHelper().registerTests();
4138
const pageTestHelper = new PageTestHelper().registerTests();
4239

@@ -78,7 +75,6 @@ testSuite({
7875
TosPpTestHelper.prototype.onPpLinkClick,
7976
tosPpTestHelper));
8077
component.render(root);
81-
infoBarTestHelper.setComponent(component);
8278
tosPpTestHelper.setComponent(component);
8379
// Reset previous state of tosPp helper.
8480
tosPpTestHelper.resetState();

javascript/ui/page/unauthorizeduser.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ const page = goog.require('firebaseui.auth.soy2.page');
3030
*/
3131
class UnauthorizedUser extends Base {
3232
/**
33-
* @param {?string} email The user's email.
33+
* @param {?string} userIdentifier The user identifier of the account, can be
34+
* email address or phone number.
3435
* @param {function()} onCancelClick Callback to invoke when the back button
3536
* is clicked.
3637
* @param {?string=} adminEmail The admin email to contact with.
@@ -43,12 +44,12 @@ class UnauthorizedUser extends Base {
4344
* @param {?DomHelper=} domHelper Optional DOM helper.
4445
*/
4546
constructor(
46-
email, onCancelClick, adminEmail, emailHelperCallback, tosCallback,
47-
privacyPolicyCallback, domHelper) {
47+
userIdentifier, onCancelClick, adminEmail, emailHelperCallback,
48+
tosCallback, privacyPolicyCallback, domHelper) {
4849
super(
4950
page.unauthorizedUser,
5051
{
51-
email: email,
52+
userIdentifier: userIdentifier,
5253
adminEmail: adminEmail,
5354
displayHelpLink: !!emailHelperCallback
5455
},

0 commit comments

Comments
 (0)