Skip to content

Commit 6787dbb

Browse files
authored
tenant button config (#737)
* release updates on accountchooser.com warnings & fix some issues
1 parent 363dfd3 commit 6787dbb

15 files changed

+120
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* Allow `fullLabel` customization for tenant selection buttons in FirebaseUI for IAP.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ ui.start('#firebaseui-auth-container', {
15091509
For [GCIP](https://cloud.google.com/identity-platform) customers, you can build a
15101510
tenant-specific sign-in page with FirebaseUI. Make sure you've enabled
15111511
multi-tenancy for your project and configured your tenants. See the
1512-
[Multi-tenancy quickstart](https://cloud.google.com/identity-platform/docs/quickstart-multi-tenancy)
1512+
[Multi-tenancy quickstart](https://cloud.google.com/identity-platform/docs/multi-tenancy-quickstart)
15131513
to learn how.
15141514
15151515
This feature requires [firebase](https://www.npmjs.com/package/firebase) version 6.6.0 or higher.

externs/firebaseui-externs.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,13 @@ firebaseui.auth.Config.prototype.widgetUrl;
609609
*/
610610
firebaseui.auth.TenantConfig = function() {};
611611

612+
/**
613+
* The tenant full label of the tenant selection button for the option first
614+
* flow.
615+
*
616+
* @type {string|undefined}
617+
*/
618+
firebaseui.auth.TenantConfig.prototype.fullLabel;
612619

613620
/**
614621
* The tenant display name of the tenant selection button for the option first

firebaseuihandler/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ const configs = {
116116
tenants: {
117117
// Tenant configuration for tenant ID tenantId1.
118118
tenantId1: {
119+
// To customize the full tenant selection button label:
120+
// fullLabel: 'ACME Portal',
119121
// Display name, button color and icon URL of the
120122
// tenant selection button.
121123
displayName: 'ACME',
@@ -147,6 +149,8 @@ const configs = {
147149
},
148150
// Tenant configuration for tenant ID tenantId2.
149151
tenantId2: {
152+
// To customize the full tenant selection button label:
153+
// fullLabel: 'OCP Portal',
150154
displayName: 'OCP',
151155
buttonColor: '#2F2F2F',
152156
iconUrl: '<icon-url-of-sign-in-button>',
@@ -215,6 +219,8 @@ The following is an example of a tenant configured to use options mode:
215219

216220
```javascript
217221
tenantId1: {
222+
// To customize the full tenant selection button label:
223+
// fullLabel: 'ACME Portal',
218224
displayName: 'ACME',
219225
buttonColor: '#2F2F2F',
220226
iconUrl: '<icon-url-of-sign-in-button>',
@@ -382,6 +388,10 @@ interface Callbacks {
382388

383389
// Interface that represents the tenant-level configurations.
384390
interface TenantConfig {
391+
// The full label for the tenant in the tenant selection buttion. Only needed
392+
// if you are using the option first mode.
393+
// When not provided, the "Sign in to $displayName" label is used.
394+
fullLabel?: string;
385395
// The display name for tenant in the tenant selection button. Only needed if
386396
// you are using the option first mode.
387397
displayName?: string;

javascript/ui/page/emaillinksigninlinking.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ firebaseui.auth.ui.page.EmailLinkSignInLinking =
3030
class extends firebaseui.auth.ui.page.Base {
3131
/**
3232
* @param {string} email The user's email.
33-
* @param {?Object} providerConfig The provider config of the IdP we should
33+
* @param {?} providerConfig The provider config of the IdP we should
3434
* use for sign in.
3535
* @param {function()} onSubmitClick Callback to invoke when the submit button
3636
* is clicked.

javascript/ui/page/emaillinksigninlinkingdifferentdevice.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ goog.require('firebaseui.auth.ui.page.Base');
3030
firebaseui.auth.ui.page.EmailLinkSignInLinkingDifferentDevice =
3131
class extends firebaseui.auth.ui.page.Base {
3232
/**
33-
* @param {?Object} providerConfig The provider config of the IdP we should
33+
* @param {?} providerConfig The provider config of the IdP we should
3434
* use for sign in.
3535
* @param {function()} onContinueClick Callback to invoke when the continue
3636
* button is clicked.

javascript/ui/page/federatedlinking.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ firebaseui.auth.ui.page.FederatedLinking =
3131
class extends firebaseui.auth.ui.page.Base {
3232
/**
3333
* @param {string} email The user's email.
34-
* @param {?Object} providerConfig The provider config of the IdP we should
34+
* @param {?} providerConfig The provider config of the IdP we should
3535
* use for sign in.
3636
* @param {function()} onSubmitClick Callback to invoke when the submit button
3737
* is clicked.

javascript/widgets/firebaseuihandler_test.js

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,25 @@ function assertBlankPageVisible(container) {
8787
assertNotNull(dom.getElementByClass('firebaseui-id-page-blank', container));
8888
}
8989

90+
/**
91+
* Asserts the IdP or tenant button has correct labels.
92+
* @param {!Element} button The IdP or tenant button.
93+
* @param {string} expectedShortLabel The expected short label of the button.
94+
* @param {string} expectedLongLabel The expected long label of the button.
95+
*/
96+
function assertIdpButtonLabels(button, expectedShortLabel, expectedLongLabel) {
97+
const idpTextLong = dom.getElementsByClass(
98+
'firebaseui-idp-text-long', button);
99+
const idpTextShort = dom.getElementsByClass(
100+
'firebaseui-idp-text-short', button);
101+
102+
assertEquals(
103+
expectedLongLabel,
104+
dom.getTextContent(idpTextLong[0]));
105+
assertEquals(
106+
expectedShortLabel,
107+
dom.getTextContent(idpTextShort[0]));
108+
}
90109

91110
/**
92111
* Asserts the busy indicator is after a short delay.
@@ -374,6 +393,7 @@ testSuite({
374393
'tenants': {
375394
// The top-level project UI configuration.
376395
'_': {
396+
'fullLabel': 'ACME Login',
377397
'displayName': 'ACME',
378398
'buttonColor': '#FFB6C1',
379399
'iconUrl': '<icon-url-of-sign-in-button>',
@@ -393,6 +413,7 @@ testSuite({
393413
'privacyPolicyUrl': 'http://localhost/privacy_policy',
394414
},
395415
'tenant1': {
416+
'fullLabel': 'Contractor A Portal',
396417
'displayName': 'Contractor A',
397418
'buttonColor': '#ADF7B2',
398419
'iconUrl': '<icon-url-of-sign-in-button>',
@@ -420,6 +441,7 @@ testSuite({
420441
'privacyPolicyUrl': 'http://localhost/privacy_policy',
421442
},
422443
'tenant2': {
444+
'fullLabel': 'Contractor B Portal',
423445
'displayName': 'Contractor B',
424446
'buttonColor': '#EAC9A1',
425447
'iconUrl': '<icon-url-of-sign-in-button>',
@@ -490,10 +512,20 @@ testSuite({
490512
'firebaseui-id-tenant-selection-button', container);
491513
// Two tenants should be available to be selected from.
492514
const expectedTenants = ['tenant1', 'tenant2'];
515+
// Two expected labels on buttons.
516+
const expectedLongLabels = [
517+
'Contractor A Portal',
518+
'Sign in to Contractor B'
519+
];
520+
const expectedShortLabels = ['Contractor A', 'Contractor B'];
521+
493522
assertEquals(expectedTenants.length, buttons.length);
494523
for (let i = 0; i < buttons.length; i++) {
495-
assertEquals(expectedTenants[i],
496-
dataset.get(buttons[i], 'tenantId'));
524+
assertEquals(expectedTenants[i], dataset.get(buttons[i], 'tenantId'));
525+
assertIdpButtonLabels(
526+
buttons[i],
527+
expectedShortLabels[i],
528+
expectedLongLabels[i]);
497529
}
498530

499531
// Click the tenant1's button.
@@ -587,10 +619,19 @@ testSuite({
587619
'firebaseui-id-tenant-selection-button', container);
588620
// Only two tenants should be available to be selected from.
589621
const expectedTenants = ['tenant1', 'tenant2'];
622+
const expectedLongLabels = [
623+
'Contractor A Portal',
624+
'Sign in to Contractor B'
625+
];
626+
const expectedShortLabels = ['Contractor A', 'Contractor B'];
590627
assertEquals(expectedTenants.length, buttons.length);
591628
for (let i = 0; i < buttons.length; i++) {
592629
assertEquals(expectedTenants[i],
593-
dataset.get(buttons[i], 'tenantId'));
630+
dataset.get(buttons[i], 'tenantId'));
631+
assertIdpButtonLabels(
632+
buttons[i],
633+
expectedShortLabels[i],
634+
expectedLongLabels[i]);
594635
}
595636

596637
testingEvents.fireClickSequence(buttons[1]);

javascript/widgets/uihandlerconfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ class UiHandlerConfig {
332332
return {
333333
tenantId: tenantId !== UiHandlerConfig.ConfigKeys.TOP_LEVEL_CONFIG_KEY ?
334334
tenantId : null,
335+
fullLabel: tenantConfig['fullLabel'] || null,
335336
displayName: tenantConfig['displayName'],
336337
iconUrl: tenantConfig['iconUrl'],
337338
buttonColor: tenantConfig['buttonColor'],

javascript/widgets/uihandlerconfig_test.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ testSuite({
3939
displayMode: 'optionsFirst',
4040
tenants: {
4141
tenantId1: {
42+
fullLabel: 'Contractor A Portal',
4243
displayName: 'Contractor A',
4344
buttonColor: '#FFB6C1',
4445
iconUrl: '<icon-url-of-sign-in-button>',
@@ -86,7 +87,7 @@ testSuite({
8687
credentialHelper: 'none',
8788
},
8889
_: {
89-
displayName: 'ACME',
90+
displayName: 'ACME.COM',
9091
buttonColor: '#53B2BF',
9192
iconUrl: '<icon-url-of-sign-in-button>',
9293
signInOptions: [
@@ -589,6 +590,7 @@ testSuite({
589590
assertObjectEquals(
590591
{
591592
tenantId: 'tenantId1',
593+
fullLabel: 'Contractor A Portal',
592594
displayName: 'Contractor A',
593595
buttonColor: '#FFB6C1',
594596
iconUrl: '<icon-url-of-sign-in-button>',
@@ -604,7 +606,7 @@ testSuite({
604606
assertObjectEquals(
605607
{
606608
tenantId: null,
607-
displayName: 'ACME',
609+
displayName: 'ACME.COM',
608610
buttonColor: '#53B2BF',
609611
iconUrl: '<icon-url-of-sign-in-button>',
610612
},
@@ -615,6 +617,7 @@ testSuite({
615617
// Test that the default option first tenant selection related configs are
616618
// returned for arbitrary tenant if default configuration is provided.
617619
configObject['tenants']['*'] = {
620+
fullLabel: 'Dealership Login',
618621
displayName: 'DEALER',
619622
buttonColor: '#37D2AC',
620623
iconUrl: '<icon-url-of-sign-in-button>',
@@ -629,6 +632,7 @@ testSuite({
629632
assertObjectEquals(
630633
{
631634
tenantId: 'arbitrary_tenant_id',
635+
fullLabel: 'Dealership Login',
632636
displayName: 'DEALER',
633637
buttonColor: '#37D2AC',
634638
iconUrl: '<icon-url-of-sign-in-button>',
@@ -641,6 +645,7 @@ testSuite({
641645
// returned for top level project if default configuration is provided.
642646
delete configObject['tenants']['_'];
643647
configObject['tenants']['*'] = {
648+
fullLabel: 'Dealership Login',
644649
displayName: 'DEALER',
645650
buttonColor: '#37D2AC',
646651
iconUrl: '<icon-url-of-sign-in-button>',
@@ -654,6 +659,7 @@ testSuite({
654659
assertObjectEquals(
655660
{
656661
tenantId: null,
662+
fullLabel: 'Dealership Login',
657663
displayName: 'DEALER',
658664
buttonColor: '#37D2AC',
659665
iconUrl: '<icon-url-of-sign-in-button>',

soy/elements.soy

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -642,9 +642,9 @@
642642
{$providerConfig.providerName}
643643
{elseif $ij.defaultProviderNames[$providerConfig.providerId]}
644644
{$ij.defaultProviderNames[$providerConfig.providerId]}
645-
{elseif strIndexOf($providerConfig.providerId, 'saml.') == 0}
645+
{elseif $providerConfig.providerId and strIndexOf($providerConfig.providerId, 'saml.') == 0}
646646
{strSub($providerConfig.providerId, 5)}
647-
{elseif strIndexOf($providerConfig.providerId, 'oidc.') == 0}
647+
{elseif $providerConfig.providerId and strIndexOf($providerConfig.providerId, 'oidc.') == 0}
648648
{strSub($providerConfig.providerId, 5)}
649649
{else}
650650
{$providerConfig.providerId}
@@ -728,7 +728,7 @@
728728
* Renders a tenant selection button.
729729
*/
730730
{template .tenantSelectionButton}
731-
{@param tenantConfig: [tenantId:string|null, displayName:string, buttonColor:string,
731+
{@param tenantConfig: [tenantId:string|null, fullLabel:string|null, displayName:string, buttonColor:string,
732732
iconUrl: string]} /** The tenant selection button config. */
733733
{let $tenantClass kind="text"}
734734
{if $tenantConfig.tenantId}
@@ -749,9 +749,13 @@
749749
src="{$tenantConfig.iconUrl}">
750750
</span>
751751
<span class="firebaseui-idp-text firebaseui-idp-text-long">
752-
{msg desc="Label for a button to sign in to a tenant. The long version"}
753-
Sign in to {$tenantConfig.displayName}
754-
{/msg}
752+
{if $tenantConfig.fullLabel}
753+
{$tenantConfig.fullLabel}
754+
{else}
755+
{msg desc="Label for a button to sign in to a tenant. The long version"}
756+
Sign in to {$tenantConfig.displayName}
757+
{/msg}
758+
{/if}
755759
</span>
756760
<span class="firebaseui-idp-text firebaseui-idp-text-short">
757761
{msg desc="Label for a button to sign in to a tenant. The short version"}

soy/elements_test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,22 @@ function testTenantSelectionButton() {
557557
displayName: 'ACME',
558558
buttonColor: '#53B2BF',
559559
iconUrl: 'icon-url',
560-
}];
560+
},
561+
{
562+
tenantId: 'TENANT_1',
563+
fullLabel: 'Contractor Login',
564+
displayName: 'OIDC',
565+
buttonColor: '#4666FF',
566+
iconUrl: 'icon-url',
567+
},
568+
{
569+
tenantId: 'TENANT_2',
570+
fullLabel: null,
571+
displayName: 'Contractor Corp',
572+
buttonColor: '#2F2B2E',
573+
iconUrl: 'icon-url',
574+
}
575+
];
561576
const root = goog.dom.getElement('tenant-selection-button');
562577
for (let i = 0; i < tenantConfigs.length; i++) {
563578
const button = goog.soy.renderAsElement(

soy/pages.soy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,8 +1389,8 @@
13891389
* Renders the list of tenants to select.
13901390
*/
13911391
{template .selectTenant}
1392-
{@param tenantConfigs: list<[tenantId:string|null, displayName:string, buttonColor:string,
1393-
iconUrl: string]>} /** List of tenant selection button configs. */
1392+
{@param tenantConfigs: list<[tenantId:string|null, fullLabel:string|null,
1393+
displayName:string, buttonColor:string, iconUrl: string]>} /** List of tenant selection button configs. */
13941394
<div class="firebaseui-container firebaseui-page-select-tenant firebaseui-id-page-select-tenant">
13951395
<div class="firebaseui-card-content">
13961396
<form onsubmit="return false;">

soy/pages_test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,22 @@ function testTenantSelect() {
813813
displayName: 'ACME',
814814
buttonColor: '#53B2BF',
815815
iconUrl: 'icon-url',
816-
}],
816+
},
817+
{
818+
tenantId: 'TENANT_1',
819+
fullLabel: 'Contractor Login',
820+
displayName: 'OIDC',
821+
buttonColor: '#4666FF',
822+
iconUrl: 'icon-url',
823+
},
824+
{
825+
tenantId: 'TENANT_2',
826+
fullLabel: null,
827+
displayName: 'ACME Corp',
828+
buttonColor: '#2F2B2E',
829+
iconUrl: 'icon-url',
830+
},
831+
],
817832
},
818833
IJ_DATA_);
819834
}

types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ declare namespace firebaseui.auth {
126126
}
127127

128128
interface TenantConfig extends firebaseui.auth.Config {
129+
fullLabel?: string;
129130
displayName?: string;
130131
buttonColor?: string;
131132
iconUrl?: string;

0 commit comments

Comments
 (0)