diff --git a/src/common-components/Logistration.jsx b/src/common-components/Logistration.jsx
index 9a31373f..cc8c1101 100644
--- a/src/common-components/Logistration.jsx
+++ b/src/common-components/Logistration.jsx
@@ -20,6 +20,7 @@ import { getTpaHint, getTpaProvider, updatePathWithQueryParams } from '../data/u
import { LoginPage } from '../login';
import { RegistrationPage } from '../register';
import { backupRegistrationForm } from '../register/data/actions';
+import { clearThirdPartyAuthContextErrorMessage } from './data/actions';
import {
tpaProvidersSelector,
} from './data/selectors';
@@ -56,6 +57,7 @@ const Logistration = (props) => {
const handleOnSelect = (tabKey) => {
sendTrackEvent(`edx.bi.${tabKey.replace('/', '')}_form.toggled`, { category: 'user-engagement' });
+ props.clearThirdPartyAuthContextErrorMessage();
if (tabKey === LOGIN_PAGE) {
props.backupRegistrationForm();
}
@@ -135,6 +137,7 @@ const Logistration = (props) => {
Logistration.propTypes = {
selectedPage: PropTypes.string,
backupRegistrationForm: PropTypes.func.isRequired,
+ clearThirdPartyAuthContextErrorMessage: PropTypes.func.isRequired,
tpaProviders: PropTypes.shape({
providers: PropTypes.arrayOf(PropTypes.shape({})),
secondaryProviders: PropTypes.arrayOf(PropTypes.shape({})),
@@ -160,5 +163,6 @@ export default connect(
mapStateToProps,
{
backupRegistrationForm,
+ clearThirdPartyAuthContextErrorMessage,
},
)(Logistration);
diff --git a/src/common-components/RedirectLogistration.jsx b/src/common-components/RedirectLogistration.jsx
index c9bc1e21..862845ca 100644
--- a/src/common-components/RedirectLogistration.jsx
+++ b/src/common-components/RedirectLogistration.jsx
@@ -21,9 +21,6 @@ const RedirectLogistration = (props) => {
let finalRedirectUrl = '';
if (success) {
- // After successful registeration remove the tpaHintedAuthentication flag from local storage if set
- localStorage.removeItem('tpaHintedAuthentication');
-
// If we're in a third party auth pipeline, we must complete the pipeline
// once user has successfully logged in. Otherwise, redirect to the specified redirect url.
// Note: For multiple enterprise use case, we need to make sure that user first visits the
diff --git a/src/common-components/SocialAuthProviders.jsx b/src/common-components/SocialAuthProviders.jsx
index c5cea3fc..9d80ea3d 100644
--- a/src/common-components/SocialAuthProviders.jsx
+++ b/src/common-components/SocialAuthProviders.jsx
@@ -13,13 +13,9 @@ const SocialAuthProviders = (props) => {
const { formatMessage } = useIntl();
const { referrer, socialAuthProviders } = props;
- function handleSubmit(e, skipRegistrationForm) {
+ function handleSubmit(e) {
e.preventDefault();
- if (skipRegistrationForm) {
- localStorage.setItem('tpaHintedAuthentication', 'true');
- }
-
const url = e.currentTarget.dataset.providerUrl;
window.location.href = getConfig().LMS_BASE_URL + url;
}
@@ -31,7 +27,7 @@ const SocialAuthProviders = (props) => {
type="button"
className={`btn-social btn-${provider.id} ${index % 2 === 0 ? 'mr-3' : ''}`}
data-provider-url={referrer === LOGIN_PAGE ? provider.loginUrl : provider.registerUrl}
- onClick={(e) => handleSubmit(e, provider.skipRegistrationForm)}
+ onClick={handleSubmit}
>
{provider.iconImage ? (
diff --git a/src/common-components/data/actions.js b/src/common-components/data/actions.js
index c69d2559..f86ddd08 100644
--- a/src/common-components/data/actions.js
+++ b/src/common-components/data/actions.js
@@ -1,6 +1,7 @@
import { AsyncActionType } from '../../data/utils';
export const THIRD_PARTY_AUTH_CONTEXT = new AsyncActionType('THIRD_PARTY_AUTH', 'GET_THIRD_PARTY_AUTH_CONTEXT');
+export const THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG = 'THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG';
// Third party auth context
export const getThirdPartyAuthContext = (urlParams) => ({
@@ -20,3 +21,7 @@ export const getThirdPartyAuthContextSuccess = (fieldDescriptions, optionalField
export const getThirdPartyAuthContextFailure = () => ({
type: THIRD_PARTY_AUTH_CONTEXT.FAILURE,
});
+
+export const clearThirdPartyAuthContextErrorMessage = () => ({
+ type: THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG,
+});
diff --git a/src/common-components/data/reducers.js b/src/common-components/data/reducers.js
index 66b3653a..fdb4675f 100644
--- a/src/common-components/data/reducers.js
+++ b/src/common-components/data/reducers.js
@@ -1,5 +1,5 @@
import { COMPLETE_STATE, PENDING_STATE } from '../../data/constants';
-import { THIRD_PARTY_AUTH_CONTEXT } from './actions';
+import { THIRD_PARTY_AUTH_CONTEXT, THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG } from './actions';
export const defaultState = {
fieldDescriptions: {},
@@ -12,6 +12,7 @@ export const defaultState = {
providers: [],
secondaryProviders: [],
pipelineUserDetails: null,
+ errorMessage: null,
},
};
@@ -36,6 +37,15 @@ const reducer = (state = defaultState, action = {}) => {
...state,
thirdPartyAuthApiStatus: COMPLETE_STATE,
};
+ case THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG:
+ return {
+ ...state,
+ thirdPartyAuthApiStatus: PENDING_STATE,
+ thirdPartyAuthContext: {
+ ...state.thirdPartyAuthContext,
+ errorMessage: null,
+ },
+ };
default:
return state;
}
diff --git a/src/common-components/data/tests/reducer.test.js b/src/common-components/data/tests/reducer.test.js
index 986c83f8..84a66e67 100644
--- a/src/common-components/data/tests/reducer.test.js
+++ b/src/common-components/data/tests/reducer.test.js
@@ -1,4 +1,5 @@
-import { THIRD_PARTY_AUTH_CONTEXT } from '../actions';
+import { PENDING_STATE } from '../../../data/constants';
+import { THIRD_PARTY_AUTH_CONTEXT, THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG } from '../actions';
import reducer from '../reducers';
describe('common components reducer', () => {
@@ -14,6 +15,7 @@ describe('common components reducer', () => {
providers: [],
secondaryProviders: [],
pipelineUserDetails: null,
+ errorMessage: null,
},
};
const fieldDescriptions = {
@@ -43,4 +45,38 @@ describe('common components reducer', () => {
},
);
});
+
+ it('should clear tpa context error message', () => {
+ const state = {
+ fieldDescriptions: {},
+ optionalFields: {},
+ thirdPartyAuthApiStatus: null,
+ thirdPartyAuthContext: {
+ currentProvider: null,
+ finishAuthUrl: null,
+ countryCode: null,
+ providers: [],
+ secondaryProviders: [],
+ pipelineUserDetails: null,
+ errorMessage: 'An error occured',
+ },
+ };
+
+ const action = {
+ type: THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG,
+ };
+
+ expect(
+ reducer(state, action),
+ ).toEqual(
+ {
+ ...state,
+ thirdPartyAuthApiStatus: PENDING_STATE,
+ thirdPartyAuthContext: {
+ ...state.thirdPartyAuthContext,
+ errorMessage: null,
+ },
+ },
+ );
+ });
});
diff --git a/src/common-components/tests/Logistration.test.jsx b/src/common-components/tests/Logistration.test.jsx
index 1f2da0b2..c7f367c0 100644
--- a/src/common-components/tests/Logistration.test.jsx
+++ b/src/common-components/tests/Logistration.test.jsx
@@ -11,6 +11,7 @@ import configureStore from 'redux-mock-store';
import { COMPLETE_STATE, LOGIN_PAGE } from '../../data/constants';
import { backupRegistrationForm } from '../../register/data/actions';
+import { clearThirdPartyAuthContextErrorMessage } from '../data/actions';
import { RenderInstitutionButton } from '../InstitutionLogistration';
import Logistration from '../Logistration';
@@ -245,14 +246,13 @@ describe('Logistration', () => {
expect(store.dispatch).toHaveBeenCalledWith(backupRegistrationForm());
});
- it('should remove tpaHintedAuthentication from localStorage on registeration success', () => {
- localStorage.setItem('tpaHintedAuthentication', 'true');
- mergeConfig({
- ALLOW_PUBLIC_ACCOUNT_CREATION: true,
- });
+ it('should clear tpa context errorMessage tab click', () => {
store = mockStore({
+ login: {
+ loginResult: { success: false, redirectUrl: '' },
+ },
register: {
- registrationResult: { success: true, redirectUrl: '' },
+ registrationResult: { success: false, redirectUrl: '' },
registrationError: {},
},
commonComponents: {
@@ -262,8 +262,10 @@ describe('Logistration', () => {
},
},
});
- mount(reduxWrapper(
));
- expect(localStorage.getItem('tpaHintedAuthentication')).toEqual(null);
+ store.dispatch = jest.fn(store.dispatch);
+ const logistration = mount(reduxWrapper(
));
+ logistration.find('a[data-rb-event-key="/login"]').simulate('click');
+ expect(store.dispatch).toHaveBeenCalledWith(clearThirdPartyAuthContextErrorMessage());
});
});
diff --git a/src/common-components/tests/SocialAuthProviders.test.jsx b/src/common-components/tests/SocialAuthProviders.test.jsx
index 2284a55d..850708ec 100644
--- a/src/common-components/tests/SocialAuthProviders.test.jsx
+++ b/src/common-components/tests/SocialAuthProviders.test.jsx
@@ -1,7 +1,6 @@
import React from 'react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
-import { mount } from 'enzyme';
import renderer from 'react-test-renderer';
import registerIcons from '../RegisterFaIcons';
@@ -75,46 +74,4 @@ describe('SocialAuthProviders', () => {
expect(tree).toMatchSnapshot();
});
-
- it('should set tpaHintedAuthentication in localStorage if skipRegistrationForm is true in provider', () => {
- localStorage.clear();
- props = {
- socialAuthProviders: [{
- ...appleProvider,
- iconClass: 'default',
- iconImage: null,
- skipRegistrationForm: true,
- }],
- };
-
- const tree = mount(
-
-
- ,
- );
-
- tree.find(`button#${appleProvider.id}`).simulate('click');
- expect(localStorage.getItem('tpaHintedAuthentication')).toEqual('true');
- });
-
- it('should not set tpaHintedAuthentication in localStorage if skipRegistrationForm is false in provider', () => {
- localStorage.clear();
- props = {
- socialAuthProviders: [{
- ...appleProvider,
- iconClass: 'default',
- iconImage: null,
- skipRegistrationForm: false,
- }],
- };
-
- const tree = mount(
-
-
- ,
- );
-
- tree.find(`button#${appleProvider.id}`).simulate('click');
- expect(localStorage.getItem('tpaHintedAuthentication')).toEqual(null);
- });
});
diff --git a/src/login/LoginFailure.jsx b/src/login/LoginFailure.jsx
index 20ff0b1a..4e630b5f 100644
--- a/src/login/LoginFailure.jsx
+++ b/src/login/LoginFailure.jsx
@@ -20,12 +20,14 @@ import {
NON_COMPLIANT_PASSWORD_EXCEPTION,
NUDGE_PASSWORD_CHANGE,
REQUIRE_PASSWORD_CHANGE,
+ TPA_AUTHENTICATION_FAILURE,
} from './data/constants';
import messages from './messages';
const LoginFailureMessage = (props) => {
const { formatMessage } = useIntl();
const { context, errorCode } = props.loginError;
+
const authService = getAuthService();
let errorList;
let resetLink = (
@@ -165,6 +167,16 @@ const LoginFailureMessage = (props) => {
);
case REQUIRE_PASSWORD_CHANGE:
return
;
+ case TPA_AUTHENTICATION_FAILURE:
+ errorList = (
+
{formatMessage(messages['login.tpa.authentication.failure'], {
+ platform_name: getConfig().SITE_NAME,
+ lineBreak:
,
+ errorMessage: context.errorMessage,
+ })}
+
+ );
+ break;
case INTERNAL_SERVER_ERROR:
default:
errorList =
{formatMessage(messages['internal.server.error.message'])}
;
@@ -183,6 +195,7 @@ LoginFailureMessage.defaultProps = {
loginError: {
redirectUrl: null,
errorCode: null,
+ errorMessage: null,
},
};
@@ -196,6 +209,7 @@ LoginFailureMessage.propTypes = {
allowedDomain: PropTypes.string,
remainingAttempts: PropTypes.number,
failureCount: PropTypes.number,
+ errorMessage: PropTypes.string,
}),
email: PropTypes.string,
errorCode: PropTypes.string,
diff --git a/src/login/LoginPage.jsx b/src/login/LoginPage.jsx
index 06b624c5..b522f217 100644
--- a/src/login/LoginPage.jsx
+++ b/src/login/LoginPage.jsx
@@ -37,7 +37,7 @@ import AccountActivationMessage from './AccountActivationMessage';
import {
loginRemovePasswordResetBanner, loginRequest, loginRequestFailure, loginRequestReset, setLoginFormData,
} from './data/actions';
-import { INVALID_FORM } from './data/constants';
+import { INVALID_FORM, TPA_AUTHENTICATION_FAILURE } from './data/constants';
import { loginErrorSelector, loginFormDataSelector, loginRequestSelector } from './data/selectors';
import LoginFailureMessage from './LoginFailure';
import messages from './messages';
@@ -223,7 +223,13 @@ class LoginPage extends React.Component {
/>
);
}
-
+ const tpaAuthenticationError = {};
+ if (thirdPartyAuthContext.errorMessage) {
+ tpaAuthenticationError.context = {
+ errorMessage: thirdPartyAuthContext.errorMessage,
+ };
+ tpaAuthenticationError.errorCode = TPA_AUTHENTICATION_FAILURE;
+ }
if (this.props.loginResult.success) {
setSurveyCookie('login');
@@ -253,6 +259,7 @@ class LoginPage extends React.Component {
platformName={thirdPartyAuthContext.platformName}
/>
{this.props.loginError ?
: null}
+ {thirdPartyAuthContext.errorMessage ?
: null}
{submitState === DEFAULT_STATE && this.state.isSubmitted ? windowScrollTo({ left: 0, top: 0, behavior: 'smooth' }) : null}
{activationMsgType &&
}
{this.props.resetPassword && !this.props.loginError ?
: null}
@@ -361,6 +368,7 @@ LoginPage.defaultProps = {
thirdPartyAuthApiStatus: 'pending',
thirdPartyAuthContext: {
currentProvider: null,
+ errorMessage: null,
finishAuthUrl: null,
providers: [],
secondaryProviders: [],
@@ -395,6 +403,7 @@ LoginPage.propTypes = {
thirdPartyAuthApiStatus: PropTypes.string,
thirdPartyAuthContext: PropTypes.shape({
currentProvider: PropTypes.string,
+ errorMessage: PropTypes.string,
platformName: PropTypes.string,
providers: PropTypes.arrayOf(PropTypes.shape({})),
secondaryProviders: PropTypes.arrayOf(PropTypes.shape({})),
diff --git a/src/login/data/constants.js b/src/login/data/constants.js
index 219e614b..cee72b86 100644
--- a/src/login/data/constants.js
+++ b/src/login/data/constants.js
@@ -10,6 +10,7 @@ export const INCORRECT_EMAIL_PASSWORD = 'incorrect-email-or-password';
export const NUDGE_PASSWORD_CHANGE = 'nudge-password-change';
export const REQUIRE_PASSWORD_CHANGE = 'require-password-change';
export const ALLOWED_DOMAIN_LOGIN_ERROR = 'allowed-domain-login-error';
+export const TPA_AUTHENTICATION_FAILURE = 'tpa-authentication-failure';
// Account Activation Message
export const ACCOUNT_ACTIVATION_MESSAGE = {
diff --git a/src/login/messages.jsx b/src/login/messages.jsx
index 03e0cf26..5d658103 100644
--- a/src/login/messages.jsx
+++ b/src/login/messages.jsx
@@ -209,6 +209,13 @@ const messages = defineMessages({
defaultMessage: 'Reset your password',
description: 'Button to redirect users to Reset Password page',
},
+ 'login.tpa.authentication.failure': {
+ id: 'login.tpa.authentication.failure',
+ defaultMessage: 'We are sorry, you are not authorized to access {platform_name} via this channel. '
+ + 'Please contact your learning administrator or manager in order to access {platform_name}.'
+ + '{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}',
+ description: 'Error message third party authentication pipeline fails',
+ },
});
export default messages;
diff --git a/src/login/tests/LoginFailure.test.jsx b/src/login/tests/LoginFailure.test.jsx
index 71ad3a01..d5f2eccb 100644
--- a/src/login/tests/LoginFailure.test.jsx
+++ b/src/login/tests/LoginFailure.test.jsx
@@ -16,6 +16,7 @@ import {
NON_COMPLIANT_PASSWORD_EXCEPTION,
NUDGE_PASSWORD_CHANGE,
REQUIRE_PASSWORD_CHANGE,
+ TPA_AUTHENTICATION_FAILURE,
} from '../data/constants';
import LoginFailureMessage from '../LoginFailure';
@@ -219,6 +220,28 @@ describe('LoginFailureMessage', () => {
expect(loginFailureMessage.find('#login-failure-alert').first().text()).toEqual(expectedMessage);
});
+ it('should match tpa authentication failed error message', () => {
+ props = {
+ loginError: {
+ errorCode: TPA_AUTHENTICATION_FAILURE,
+ context: {
+ errorMessage: 'An error occured',
+ },
+ },
+ };
+
+ const loginFailureMessage = mount(
+
+
+ ,
+ );
+
+ const expectedMessageSubstring = 'We are sorry, you are not authorized to access';
+
+ expect(loginFailureMessage.find('#login-failure-alert').first().text()).toContain(expectedMessageSubstring);
+ expect(loginFailureMessage.find('#login-failure-alert').first().text()).toContain('An error occured');
+ });
+
it('should show modal that nudges users to change password', () => {
props = {
loginError: {
diff --git a/src/login/tests/LoginPage.test.jsx b/src/login/tests/LoginPage.test.jsx
index e2398662..4a1acdef 100644
--- a/src/login/tests/LoginPage.test.jsx
+++ b/src/login/tests/LoginPage.test.jsx
@@ -441,6 +441,23 @@ describe('LoginPage', () => {
expect(loginPage.find('#tpa-alert').find('p').text()).toEqual(expectedMessage);
});
+ it('should show tpa authentication fails error message', () => {
+ store = mockStore({
+ ...initialState,
+ commonComponents: {
+ ...initialState.commonComponents,
+ thirdPartyAuthContext: {
+ ...initialState.commonComponents.thirdPartyAuthContext,
+ currentProvider: null,
+ errorMessage: 'An error occured',
+ },
+ },
+ });
+
+ const loginPage = mount(reduxWrapper(
));
+ expect(loginPage.find('#login-failure-alert').find('p').text()).toContain('An error occured');
+ });
+
it('should match invalid login form error message', () => {
const errorMessage = 'Please fill in the fields below.';
store = mockStore({
diff --git a/src/register/RegistrationFailure.jsx b/src/register/RegistrationFailure.jsx
index 5f994eb6..21df5ef4 100644
--- a/src/register/RegistrationFailure.jsx
+++ b/src/register/RegistrationFailure.jsx
@@ -1,12 +1,18 @@
import React, { useEffect } from 'react';
+import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import { Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
import { windowScrollTo } from '../data/utils';
-import { FORBIDDEN_REQUEST, INTERNAL_SERVER_ERROR, TPA_SESSION_EXPIRED } from './data/constants';
+import {
+ FORBIDDEN_REQUEST,
+ INTERNAL_SERVER_ERROR,
+ TPA_AUTHENTICATION_FAILURE,
+ TPA_SESSION_EXPIRED,
+} from './data/constants';
import messages from './messages';
const RegistrationFailureMessage = (props) => {
@@ -31,6 +37,14 @@ const RegistrationFailureMessage = (props) => {
case FORBIDDEN_REQUEST:
errorMessage = formatMessage(messages['registration.rate.limit.error']);
break;
+ case TPA_AUTHENTICATION_FAILURE:
+ errorMessage = formatMessage(messages['registration.tpa.authentication.failure'],
+ {
+ platform_name: getConfig().SITE_NAME,
+ lineBreak:
,
+ errorMessage: context.errorMessage,
+ });
+ break;
case TPA_SESSION_EXPIRED:
errorMessage = formatMessage(messages['registration.tpa.session.expired'], { provider: context.provider });
break;
@@ -48,12 +62,15 @@ const RegistrationFailureMessage = (props) => {
};
RegistrationFailureMessage.defaultProps = {
- context: {},
+ context: {
+ errorMessage: null,
+ },
};
RegistrationFailureMessage.propTypes = {
context: PropTypes.shape({
provider: PropTypes.string,
+ errorMessage: PropTypes.string,
}),
errorCode: PropTypes.string.isRequired,
failureCount: PropTypes.number.isRequired,
diff --git a/src/register/RegistrationPage.jsx b/src/register/RegistrationPage.jsx
index ef394713..86fad183 100644
--- a/src/register/RegistrationPage.jsx
+++ b/src/register/RegistrationPage.jsx
@@ -22,6 +22,7 @@ import {
} from '../common-components/data/selectors';
import EnterpriseSSO from '../common-components/EnterpriseSSO';
import {
+ COMPLETE_STATE,
DEFAULT_STATE, INVALID_NAME_REGEX, LETTER_REGEX, NUMBER_REGEX, PENDING_STATE, REGISTER_PAGE, VALID_EMAIL_REGEX,
} from '../data/constants';
import {
@@ -41,10 +42,11 @@ import {
COUNTRY_DISPLAY_KEY,
FIELDS,
FORM_SUBMISSION_ERROR,
+ TPA_AUTHENTICATION_FAILURE,
} from './data/constants';
import { registrationErrorSelector, validationsSelector } from './data/selectors';
import {
- getSuggestionForInvalidEmail, isTpaHintedAuthentication, validateCountryField, validateEmailAddress,
+ getSuggestionForInvalidEmail, validateCountryField, validateEmailAddress,
} from './data/utils';
import messages from './messages';
import RegistrationFailure from './RegistrationFailure';
@@ -95,7 +97,7 @@ const RegistrationPage = (props) => {
const [configurableFormFields, setConfigurableFormFields] = useState({ ...backedUpFormData.configurableFormFields });
const [errors, setErrors] = useState({ ...backedUpFormData.errors });
const [emailSuggestion, setEmailSuggestion] = useState({ ...backedUpFormData.emailSuggestion });
- const [autoSubmitRegisterForm, setAutoSubmitRegisterForm] = useState(isTpaHintedAuthentication());
+ const [autoSubmitRegisterForm, setAutoSubmitRegisterForm] = useState(false);
const [errorCode, setErrorCode] = useState({ type: '', count: 0 });
const [formStartTime, setFormStartTime] = useState(null);
const [focusedField, setFocusedField] = useState(null);
@@ -127,13 +129,13 @@ const RegistrationPage = (props) => {
* Set the userPipelineDetails data in formFields for only first time
*/
useEffect(() => {
- if (!userPipelineDataLoaded) {
+ if (!userPipelineDataLoaded && thirdPartyAuthApiStatus === COMPLETE_STATE) {
const { autoSubmitRegForm, pipelineUserDetails, errorMessage } = thirdPartyAuthContext;
if (errorMessage) {
- localStorage.removeItem('tpaHintedAuthentication');
- setAutoSubmitRegisterForm(false);
+ setErrorCode(prevState => ({ type: TPA_AUTHENTICATION_FAILURE, count: prevState.count + 1 }));
} else if (autoSubmitRegForm) {
checkTOSandHonorCodeFields();
+ setAutoSubmitRegisterForm(true);
}
if (pipelineUserDetails && Object.keys(pipelineUserDetails).length !== 0) {
const { name = '', username = '', email = '' } = pipelineUserDetails;
@@ -538,7 +540,7 @@ const RegistrationPage = (props) => {