From 0891a8ec4c2420890f5b900792cbefb8a7e9b0d8 Mon Sep 17 00:00:00 2001 From: "ankitatripathi.mp@gmail.com" Date: Tue, 21 Jul 2026 22:52:36 +0530 Subject: [PATCH 1/2] fix(enterprise): guard against null domains and trim whitespace in HRD --- .../__snapshots__/hrd_screen.test.js.snap | 58 +++++++++++++++++++ .../connection/enterprise/hrd_screen.test.js | 12 ++++ .../enterprise/matchConnection.test.js | 39 +++++++++++++ src/connection/enterprise.js | 4 +- src/connection/enterprise/hrd_screen.jsx | 2 +- 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/__tests__/connection/enterprise/matchConnection.test.js diff --git a/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap b/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap index 1bee2f3b4..8570ab511 100644 --- a/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap +++ b/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap @@ -1,5 +1,63 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`HRDScreen Component renders correctly when enterprise domain is a whitespace string 1`] = ` +
+ Login with your corporate credentials. [] +

+ } + data-i18n={ + { + "str": [Function], + } + } + data-model={ + Immutable.Map { + "id": "__lock-id__", + "i18n": Immutable.Map { + "strings": Immutable.Map { + "enterpriseLoginIntructions": "Login with your corporate credentials.", + "enterpriseActiveLoginInstructions": "Please enter your corporate credentials at %s.", + }, + }, + } + } + data-passwordInputPlaceholder=" []" + data-usernameInputPlaceholder=" []" +/> +`; + +exports[`HRDScreen Component renders correctly when enterprise domain is an empty string 1`] = ` +
+ Login with your corporate credentials. [] +

+ } + data-i18n={ + { + "str": [Function], + } + } + data-model={ + Immutable.Map { + "id": "__lock-id__", + "i18n": Immutable.Map { + "strings": Immutable.Map { + "enterpriseLoginIntructions": "Login with your corporate credentials.", + "enterpriseActiveLoginInstructions": "Please enter your corporate credentials at %s.", + }, + }, + } + } + data-passwordInputPlaceholder=" []" + data-usernameInputPlaceholder=" []" +/> +`; + exports[`HRDScreen Component renders correctly when there is an enterprise domain 1`] = `
{ const Component = getComponent(); expectComponent().toMatchSnapshot(); }); + + it('renders correctly when enterprise domain is an empty string', () => { + require('connection/enterprise').enterpriseDomain.mockImplementation(() => ''); + const Component = getComponent(); + expectComponent().toMatchSnapshot(); + }); + + it('renders correctly when enterprise domain is a whitespace string', () => { + require('connection/enterprise').enterpriseDomain.mockImplementation(() => ' '); + const Component = getComponent(); + expectComponent().toMatchSnapshot(); + }); }); diff --git a/src/__tests__/connection/enterprise/matchConnection.test.js b/src/__tests__/connection/enterprise/matchConnection.test.js new file mode 100644 index 000000000..9683397ee --- /dev/null +++ b/src/__tests__/connection/enterprise/matchConnection.test.js @@ -0,0 +1,39 @@ +import I from 'immutable'; +import { matchConnection } from '../../../connection/enterprise'; + +// Build a minimal lock model with enterprise connections at the path +// l.connections() calls tget(m, ['connections', type]) where tget uses +// dataFns(['core']).tget, which reads m.getIn(['core', 'transient', 'connections', type]) +const buildModel = (connections) => + I.fromJS({ core: { transient: { connections: { enterprise: connections } } } }); + +describe('matchConnection', () => { + it('returns the matching connection when domains contains the email domain', () => { + const model = buildModel([ + { name: 'my-connection', strategy: 'waad', domains: ['example.com'] } + ]); + const result = matchConnection(model, 'user@example.com'); + expect(result).toBeDefined(); + expect(result.get('name')).toBe('my-connection'); + }); + + it('returns undefined when no connection matches the email domain', () => { + const model = buildModel([ + { name: 'my-connection', strategy: 'waad', domains: ['other.com'] } + ]); + expect(matchConnection(model, 'user@example.com')).toBeUndefined(); + }); + + it('does not throw when a connection has null domains', () => { + const model = buildModel([{ name: 'no-domains', strategy: 'waad', domains: null }]); + expect(() => matchConnection(model, 'user@example.com')).not.toThrow(); + expect(matchConnection(model, 'user@example.com')).toBeUndefined(); + }); + + it('returns false when email has no domain part', () => { + const model = buildModel([ + { name: 'my-connection', strategy: 'waad', domains: ['example.com'] } + ]); + expect(matchConnection(model, 'notanemail')).toBe(false); + }); +}); diff --git a/src/connection/enterprise.js b/src/connection/enterprise.js index be15a3b76..16629b0d9 100644 --- a/src/connection/enterprise.js +++ b/src/connection/enterprise.js @@ -79,7 +79,7 @@ export function matchConnection(m, email, strategies = []) { const target = emailDomain(email); if (!target) return false; return l.connections(m, 'enterprise', ...strategies).find(x => { - return x.get('domains').contains(target); + return x.get('domains') && x.get('domains').contains(target); }); } @@ -108,7 +108,7 @@ export function isADEnabled(m) { export function findADConnectionWithoutDomain(m, name = undefined) { return l.connections(m, 'enterprise', 'ad', 'auth0-adldap').find(x => { - return x.get('domains').isEmpty() && (!name || x.get('name') === name); + return x.get('domains') && x.get('domains').isEmpty() && (!name || x.get('name') === name); }); } diff --git a/src/connection/enterprise/hrd_screen.jsx b/src/connection/enterprise/hrd_screen.jsx index 2eeb09b32..2a6df2ab2 100644 --- a/src/connection/enterprise/hrd_screen.jsx +++ b/src/connection/enterprise/hrd_screen.jsx @@ -11,7 +11,7 @@ const Component = ({ i18n, model }) => { var headerText; - if (domain !== null) { + if (domain && domain.trim()) { headerText = i18n.str('enterpriseActiveLoginInstructions', domain); } else { headerText = i18n.str('enterpriseLoginIntructions'); From 85c7639aad2bfd8d8423ebd487c62f1eecbde1a3 Mon Sep 17 00:00:00 2001 From: "ankitatripathi.mp@gmail.com" Date: Wed, 22 Jul 2026 00:08:38 +0530 Subject: [PATCH 2/2] test(enterprise): add missing hrd_screen test cases for undefined/null domain --- .../__snapshots__/hrd_screen.test.js.snap | 29 +++++++++++++++++++ .../connection/enterprise/hrd_screen.test.js | 24 ++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap b/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap index 8570ab511..9a6cca6c9 100644 --- a/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap +++ b/src/__tests__/connection/enterprise/__snapshots__/hrd_screen.test.js.snap @@ -58,6 +58,35 @@ exports[`HRDScreen Component renders correctly when enterprise domain is an empt /> `; +exports[`HRDScreen Component renders correctly when enterprise domain is undefined 1`] = ` +
+ Login with your corporate credentials. [] +

+ } + data-i18n={ + { + "str": [Function], + } + } + data-model={ + Immutable.Map { + "id": "__lock-id__", + "i18n": Immutable.Map { + "strings": Immutable.Map { + "enterpriseLoginIntructions": "Login with your corporate credentials.", + "enterpriseActiveLoginInstructions": "Please enter your corporate credentials at %s.", + }, + }, + } + } + data-passwordInputPlaceholder=" []" + data-usernameInputPlaceholder=" []" +/> +`; + exports[`HRDScreen Component renders correctly when there is an enterprise domain 1`] = `
{ const Component = getComponent(); expectComponent().toMatchSnapshot(); }); + + it('renders correctly when enterprise domain is undefined', () => { + require('connection/enterprise').enterpriseDomain.mockImplementation(() => undefined); + const Component = getComponent(); + expectComponent().toMatchSnapshot(); + }); + + it('does not show "undefined" in message when enterprise domain is undefined', () => { + require('connection/enterprise').enterpriseDomain.mockImplementation(() => undefined); + const Component = getComponent(); + const rendered = renderShallowComponent(); + const headerText = rendered.props.header && rendered.props.header.props.children; + expect(String(headerText)).not.toContain('undefined'); + }); + + it('does not show "undefined" in message when enterprise domain is null', () => { + require('connection/enterprise').enterpriseDomain.mockImplementation(() => null); + const Component = getComponent(); + const rendered = renderShallowComponent(); + const headerText = rendered.props.header && rendered.props.header.props.children; + expect(String(headerText)).not.toContain('undefined'); + }); });