This is an automated email from the ASF dual-hosted git repository. mehul pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ranger.git
commit 50a56de798b968d6e1e05b71c2f356502f5abaee Author: Mugdha Varadkar <mug...@apache.org> AuthorDate: Wed Aug 16 00:10:23 2023 +0530 RANGER-4374: Getting page not found when wrong password is send in 'Old Password' Signed-off-by: Mehul Parikh <me...@apache.org> --- .../react-webapp/src/components/Editable.jsx | 7 -- .../webapp/react-webapp/src/utils/XAMessages.js | 8 +-- .../main/webapp/react-webapp/src/utils/XAUtils.js | 2 +- .../main/webapp/react-webapp/src/utils/appState.js | 3 + .../main/webapp/react-webapp/src/utils/fetchAPI.js | 6 +- .../src/views/AuditEvent/AccessLogDetail.jsx | 10 +-- .../src/views/AuditEvent/AccessLogsTable.jsx | 8 ++- .../src/views/AuditEvent/AdminLogs/PolicyLogs.jsx | 8 +-- .../src/views/AuditEvent/AdminLogs/UserLogs.jsx | 6 +- .../src/views/Encryption/KeyManager.jsx | 13 ++-- .../src/views/SecurityZone/SecurityZoneForm.jsx | 4 +- .../src/views/ServiceManager/ServiceDefinition.jsx | 20 +++--- .../views/ServiceManager/ServiceViewDetails.jsx | 12 ++-- .../react-webapp/src/views/SideBar/SideBarBody.jsx | 1 + .../users_details/EditUserView.jsx | 51 +++++++++----- .../users_details/UserFormComp.jsx | 10 ++- .../users_details/UserListing.jsx | 2 +- .../webapp/react-webapp/src/views/UserProfile.jsx | 78 +++++++++++++++++++--- 18 files changed, 171 insertions(+), 78 deletions(-) diff --git a/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx b/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx index 34eb8c5fa..75f7fcff1 100644 --- a/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/components/Editable.jsx @@ -727,13 +727,6 @@ const Editable = (props) => { <RadioBtnComp value={value} options={options} valRef={selectValRef} /> ) : type === TYPE_INPUT ? ( <InputboxComp value={value} valRef={selectValRef} /> - ) : type === TYPE_SELECT ? ( - <CreatableSelectNew - value={value} - valRef={selectValRef} - conditionDefVal={props.conditionDefVal} - selectProps={props.selectProps} - /> ) : type === TYPE_CUSTOM ? ( <CustomCondition value={value} diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js index 82eb8fe18..aae75199b 100644 --- a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js +++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js @@ -25,7 +25,7 @@ export const RegexMessage = { "Please avoid these characters (&, <, >, ', \", `) for policy name.", userNameValidationMsg: ( <> - <p className="pd-10" style={{ fontSize: "small" }}> + <p className="pd-10 mb-0" style={{ fontSize: "small" }}> 1. User name should be start with alphabet / numeric / underscore / non-us characters. <br /> @@ -39,7 +39,7 @@ export const RegexMessage = { "Password should be minimum 8 characters ,atleast one uppercase letter, one lowercase letter and one numeric. For FIPS environment password should be minimum 14 characters with atleast one uppercase letter, one special characters, one lowercase letter and one numeric.", emailvalidationinfomessage: ( <> - <p className="pd-10" style={{ fontSize: "small" }}> + <p className="pd-10 mb-0" style={{ fontSize: "small" }}> 1. Email address should be start with alphabet / numeric / underscore / non-us characters. <br /> 2. Allowed special character <b>.-@</b> . @@ -55,7 +55,7 @@ export const RegexMessage = { 2. Dragging bottom-right corner of javascript condition editor(Textarea) can resizable", firstNameValidationMsg: ( <> - <p className="pd-10" style={{ fontSize: "small" }}> + <p className="pd-10 mb-0" style={{ fontSize: "small" }}> 1. First name should be start with alphabet / numeric / underscore / non-us characters. <br /> @@ -67,7 +67,7 @@ export const RegexMessage = { ), lastNameValidationMsg: ( <> - <p className="pd-10" style={{ fontSize: "small" }}> + <p className="pd-10 mb-0" style={{ fontSize: "small" }}> 1. Last name should be start with alphabet / numeric / underscore / non-us characters. <br /> diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js index 7edee019e..20dece45f 100644 --- a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js +++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js @@ -18,7 +18,7 @@ */ import React, { useState } from "react"; -import { getUserProfile, setUserProfile } from "Utils/appState"; +import { getUserProfile } from "Utils/appState"; import { UserRoles, PathAssociateWithModule, QueryParams } from "Utils/XAEnums"; import { filter, diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/appState.js b/security-admin/src/main/webapp/react-webapp/src/utils/appState.js index 6267de2b4..938cf9b2d 100644 --- a/security-admin/src/main/webapp/react-webapp/src/utils/appState.js +++ b/security-admin/src/main/webapp/react-webapp/src/utils/appState.js @@ -19,6 +19,7 @@ const appState = {}; const serviceDefData = {}; + function getUserProfile() { return appState.userProfile; } @@ -26,9 +27,11 @@ function getUserProfile() { function setUserProfile(profile = null) { appState.userProfile = profile; } + function getServiceDef() { return serviceDefData; } + function setServiceDef(serviceDef, tagServiceDef, allServiceDefs) { serviceDefData.serviceDefs = serviceDef; serviceDefData.tagServiceDefs = tagServiceDef; diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/fetchAPI.js b/security-admin/src/main/webapp/react-webapp/src/utils/fetchAPI.js index ef32634bb..135182b40 100644 --- a/security-admin/src/main/webapp/react-webapp/src/utils/fetchAPI.js +++ b/security-admin/src/main/webapp/react-webapp/src/utils/fetchAPI.js @@ -17,7 +17,6 @@ * under the License. */ import axios from "axios"; -import ErrorPage from "../views/ErrorPage"; import { RANGER_REST_CSRF_ENABLED, RANGER_REST_CSRF_CUSTOM_HEADER, @@ -55,6 +54,7 @@ async function fetchApi(axiosConfig = {}, otherConf = {}) { const config = { ...axiosConfig }; + if (otherConf && otherConf.cancelRequest) { /* Below code add "source" attribute in second argument which is use to cancel request. @@ -77,6 +77,7 @@ async function fetchApi(axiosConfig = {}, otherConf = {}) { config.cancelToken = source.token; otherConf.source = source; } + try { const resp = await axios(config); return resp; @@ -88,6 +89,9 @@ async function fetchApi(axiosConfig = {}, otherConf = {}) { window.location.replace("login.jsp?sessionTimeout=true"); } } + if (config.skipNavigate !== undefined && config.skipNavigate) { + throw error; + } if ( error?.response?.status === 400 && (error?.response?.data?.messageList?.[0]?.name == "DATA_NOT_FOUND" || diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogDetail.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogDetail.jsx index af64aa877..dc75efe50 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogDetail.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogDetail.jsx @@ -36,6 +36,7 @@ function AccessLogDetail(props) { fetchServiceDefs(); fetchAcessLogs(); }, []); + const fetchServiceDefs = async () => { let serviceDefsResp = []; try { @@ -51,9 +52,10 @@ function AccessLogDetail(props) { setServiceDefs(serviceDefsResp.data.serviceDefs); setLoader(false); }; + const fetchAcessLogs = async () => { - let accessResp; - let accessData; + let accessResp = {}; + let accessData = {}; try { accessResp = await fetchApi({ @@ -66,7 +68,7 @@ function AccessLogDetail(props) { console.error( `Error occurred while fetching Access or CSRF headers! ${error}` ); - toast.error(error.response.data.msgDesc); + toast.error(error?.response?.data?.msgDesc); } if (!isEmpty(accessResp)) { accessResp.data.vXAccessAudits.map((obj) => { @@ -91,7 +93,7 @@ function AccessLogDetail(props) { <div className="wrap"> <AccessLogsTable data={access}></AccessLogsTable> </div> - {access.policyId != -1 && ( + {access?.policyId !== undefined && access?.policyId > 0 && ( <> <h5 className="heading-without-wrap">Policy Details</h5> <div className="wrap"> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogsTable.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogsTable.jsx index cf92a9a99..e4c814dca 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogsTable.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AccessLogsTable.jsx @@ -173,7 +173,13 @@ export const AccessLogsTable = ({ data = {} }) => { </tr> <tr> <td>Result</td> - <td>{accessResult == 1 ? "Allowed" : "Denied"}</td> + <td> + {accessResult !== undefined + ? accessResult == 1 + ? "Allowed" + : "Denied" + : "--"} + </td> </tr> <tr> <td className="text-nowrap">Access Enforcer</td> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyLogs.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyLogs.jsx index 92a1aac47..2ea9816ef 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyLogs.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/PolicyLogs.jsx @@ -241,7 +241,7 @@ export const PolicyLogs = ({ data, reportdata }) => { return obj.attributeName == "Policy Resources" && obj.action == "update"; }); - /*UPDATESS*/ + /* UPDATES */ const policyDetailsUpdate = (details, resources) => { let tablerow = []; @@ -1743,7 +1743,7 @@ export const PolicyLogs = ({ data, reportdata }) => { let keynew = {}; resources.map((obj) => { - keynew = !isEmpty(ovj.previousValue) && JSON.parse(obj.previousValue); + keynew = !isEmpty(obj.previousValue) && JSON.parse(obj.previousValue); }); Object.keys(keynew).map((key, index) => { @@ -3041,8 +3041,8 @@ export const PolicyLogs = ({ data, reportdata }) => { <td className="table-warning policyitem-field"> <i>{`Users`}</i> {`: ${ - !isEmpty(policy.suers) - ? policy.suers.join(", ") + !isEmpty(policy.users) + ? policy.users.join(", ") : "<empty>" } `} </td> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/UserLogs.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/UserLogs.jsx index 0a94a3b85..a856187af 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/UserLogs.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/AdminLogs/UserLogs.jsx @@ -243,15 +243,15 @@ export const UserLogs = ({ data, reportdata }) => { if (val == "ROLE_USER") { val = UserRoles.ROLE_USER.label; } - if (val == "ROLE_USER") { - val = UserRoles.ROLE_USER.label; - } if (val == "ROLE_SYS_ADMIN") { val = UserRoles.ROLE_SYS_ADMIN.label; } if (val == "ROLE_KEY_ADMIN") { val = UserRoles.ROLE_KEY_ADMIN.label; } + if (val == "ROLE_ADMIN_AUDITOR") { + val = UserRoles.ROLE_ADMIN_AUDITOR.label; + } if (val == "ROLE_KEY_ADMIN_AUDITOR") { val = UserRoles.ROLE_KEY_ADMIN_AUDITOR.label; } diff --git a/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyManager.jsx b/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyManager.jsx index d4f4a24b6..fa5f975b7 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyManager.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/Encryption/KeyManager.jsx @@ -31,7 +31,6 @@ import { fetchApi } from "Utils/fetchAPI"; import dateFormat from "dateformat"; import moment from "moment-timezone"; import { find, sortBy, isUndefined, isEmpty } from "lodash"; -import { commonBreadcrumb } from "../../utils/XAUtils"; import StructuredFilter from "../../components/structured-filter/react-typeahead/tokenizer"; import AsyncSelect from "react-select/async"; import { isKeyAdmin, parseSearchFilter } from "../../utils/XAUtils"; @@ -60,7 +59,7 @@ function init(props) { updatetable: moment.now(), currentPageIndex: 0, currentPageSize: 25, - resetPage: { page: null } + resetPage: { page: 0 } }; } @@ -166,7 +165,8 @@ const KeyManager = (props) => { currentPageIndex, currentPageSize, pagecount, - updatetable + updatetable, + resetPage } = keyState; useEffect(() => { @@ -331,9 +331,8 @@ const KeyManager = (props) => { setBlockUI(false); toast.success(`Success! Key deleted successfully`); if (keydata.length == 1 && currentPageIndex > 1) { - let page = currentPageIndex - currentPageIndex; if (typeof resetPage?.page === "function") { - resetPage.page(page); + resetPage.page(0); } } else { dispatch({ @@ -344,7 +343,7 @@ const KeyManager = (props) => { } catch (error) { setBlockUI(false); let errorMsg = ""; - if (error.response.data.msgDesc) { + if (error?.response?.data?.msgDesc) { errorMsg = toast.error("Error! " + error.response.data.msgDesc + "\n"); } else { errorMsg = `Error occurred during deleting Key` + "\n"; @@ -410,7 +409,7 @@ const KeyManager = (props) => { }); dispatch({ type: "SET_RESET_PAGE", - resetPage: gotoPage + resetPage: { page: gotoPage } }); dispatch({ type: "SET_LOADER", diff --git a/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx b/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx index ea76fa823..c506ee0f8 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/SecurityZone/SecurityZoneForm.jsx @@ -205,7 +205,9 @@ const SecurityZoneForm = (props) => { console.error( `Error occurred while fetching Zone or CSRF headers! ${error}` ); - toast.error(error.response.data.msgDesc); + if (error?.response?.data?.msgDesc) { + toast.error(error.response.data.msgDesc); + } } setZone(zoneResp?.data); } diff --git a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx index af1903ec7..696c25c8c 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceDefinition.jsx @@ -476,15 +476,17 @@ class ServiceDefinition extends Component { <p className="form-header"> Config Properties : </p> - <Table bordered size="sm"> - <tbody className="service-config"> - {s?.configs && - this.getServiceConfigs( - this.state.serviceDef, - s.configs - )} - </tbody> - </Table> + <div className="table-responsive"> + <Table bordered size="sm"> + <tbody className="service-config"> + {s?.configs && + this.getServiceConfigs( + this.state.serviceDef, + s.configs + )} + </tbody> + </Table> + </div> <p className="form-header">Audit Filter :</p> <div className="table-responsive"> <Table diff --git a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceViewDetails.jsx b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceViewDetails.jsx index c774504ec..52279345f 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceViewDetails.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/ServiceManager/ServiceViewDetails.jsx @@ -281,11 +281,13 @@ export const ServiceViewDetails = (props) => { </tbody> </Table> <p className="form-header">Config Properties :</p> - <Table bordered size="sm"> - <tbody className="service-config"> - {getServiceConfigs(serviceDefData, serviceData.configs)} - </tbody> - </Table> + <div className="table-responsive"> + <Table bordered size="sm"> + <tbody className="service-config"> + {getServiceConfigs(serviceDefData, serviceData.configs)} + </tbody> + </Table> + </div> <p className="form-header">Audit Filter :</p> <div className="table-responsive"> <Table bordered size="sm" className="table-audit-filter-ready-only"> diff --git a/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx b/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx index 4d8494fc4..aa4a2d890 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/SideBar/SideBarBody.jsx @@ -45,6 +45,7 @@ import { import { getServiceDef } from "../../utils/appState"; import ResourceTagContent from "./ResourceTagContent"; import { Button } from "react-bootstrap"; +import { toast } from "react-toastify"; function reducer(state, action) { switch (action.type) { diff --git a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/EditUserView.jsx b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/EditUserView.jsx index 73585458a..44468cda6 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/EditUserView.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/EditUserView.jsx @@ -17,18 +17,18 @@ * under the License. */ -import React, { useState, useEffect, useReducer } from "react"; +import React, { useEffect, useReducer } from "react"; import { Tab, Button, Nav, Row, Col } from "react-bootstrap"; import { Form, Field } from "react-final-form"; -import { getUserProfile, setUserProfile } from "Utils/appState"; +import { getUserProfile } from "Utils/appState"; import UserFormComp from "Views/UserGroupRoleListing/users_details/UserFormComp"; import { Loader, scrollToError } from "Components/CommonComponents"; import { fetchApi } from "Utils/fetchAPI"; import { UserTypes, RegexValidation } from "Utils/XAEnums"; import { toast } from "react-toastify"; -import withRouter from "Hooks/withRouter"; import { useParams, useLocation, useNavigate } from "react-router-dom"; -import { commonBreadcrumb } from "../../../utils/XAUtils"; +import { has } from "lodash"; +import { commonBreadcrumb, InfoIcon } from "../../../utils/XAUtils"; const initialState = { userInfo: {}, @@ -89,16 +89,6 @@ function AddUserView(props) { }); }; - const Error = ({ name }) => ( - <Field name={name}> - {({ meta: { error, touched } }) => { - return error && touched ? ( - <div className="col-sm-2">{error}</div> - ) : null; - }} - </Field> - ); - const validateForm = (values) => { const errors = {}; if (!values.newPassword) { @@ -110,7 +100,10 @@ function AddUserView(props) { } if (!values.reEnterPassword) { errors.reEnterPassword = "Required"; - } else if (values.newPassword !== values.reEnterPassword) { + } else if ( + has(values, "newPassword") && + values.newPassword !== values.reEnterPassword + ) { errors.reEnterPassword = "Password must be match with new password"; } return errors; @@ -132,7 +125,8 @@ function AddUserView(props) { toast.success("User password change successfully!!"); navigate("/users/usertab"); } catch (error) { - console.error(`Error occurred while updating user password! ${error}`); + toast.error("Error occured while updating user details!"); + console.error(`Error occurred while updating user details! ${error}`); } }; @@ -187,7 +181,6 @@ function AddUserView(props) { <Tab.Content> <Tab.Pane eventKey="edit-password"> <> - <h4 className="wrap-header bold">User Password Change</h4> <Form onSubmit={handleSubmit} validate={validateForm} @@ -241,6 +234,18 @@ function AddUserView(props) { } data-cy="newPassword" /> + <InfoIcon + css="info-user-role-grp-icon" + position="right" + message={ + <p + className="pd-10 mb-0" + style={{ fontSize: "small" }} + > + {RegexValidation.PASSWORD.message} + </p> + } + /> {meta.error && meta.touched && ( <span className="invalid-field"> {meta.error} @@ -277,6 +282,18 @@ function AddUserView(props) { } data-cy="reEnterPassword" /> + <InfoIcon + css="info-user-role-grp-icon" + position="right" + message={ + <p + className="pd-10 mb-0" + style={{ fontSize: "small" }} + > + {RegexValidation.PASSWORD.message} + </p> + } + /> {meta.error && meta.touched && ( <span className="invalid-field"> {meta.error} diff --git a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserFormComp.jsx b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserFormComp.jsx index 1b32993b7..23bc1b169 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserFormComp.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserFormComp.jsx @@ -469,7 +469,10 @@ function UserFormComp(props) { css="info-user-role-grp-icon" position="right" message={ - <p className="pd-10" style={{ fontSize: "small" }}> + <p + className="pd-10 mb-0" + style={{ fontSize: "small" }} + > { RegexMessage.MESSAGE .passwordvalidationinfomessage @@ -518,7 +521,10 @@ function UserFormComp(props) { css="info-user-role-grp-icon" position="right" message={ - <p className="pd-10" style={{ fontSize: "small" }}> + <p + className="pd-10 mb-0" + style={{ fontSize: "small" }} + > { RegexMessage.MESSAGE .passwordvalidationinfomessage diff --git a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserListing.jsx b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserListing.jsx index c3150fd65..1890168e5 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserListing.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/UserGroupRoleListing/users_details/UserListing.jsx @@ -279,7 +279,7 @@ function Users() { setBlockUI(false); } catch (error) { setBlockUI(false); - if (error.response.data.msgDesc) { + if (error?.response?.data?.msgDesc) { errorMsg += error.response.data.msgDesc + "\n"; } else { errorMsg += diff --git a/security-admin/src/main/webapp/react-webapp/src/views/UserProfile.jsx b/security-admin/src/main/webapp/react-webapp/src/views/UserProfile.jsx index 452fe931e..64c695b33 100644 --- a/security-admin/src/main/webapp/react-webapp/src/views/UserProfile.jsx +++ b/security-admin/src/main/webapp/react-webapp/src/views/UserProfile.jsx @@ -30,6 +30,7 @@ import { has, isEmpty, isUndefined } from "lodash"; import { RegexMessage } from "../utils/XAMessages"; import { fetchApi } from "Utils/fetchAPI"; import CustomBreadcrumb from "./CustomBreadcrumb"; + class UserProfile extends Component { constructor(props) { super(props); @@ -37,6 +38,7 @@ class UserProfile extends Component { blockUI: false }; } + updateUserInfo = async (values) => { const userProps = getUserProfile(); @@ -83,7 +85,8 @@ class UserProfile extends Component { const passwdResp = await fetchApi({ url: "users/" + userProps.id + "/passwordchange", method: "post", - data: jsonData + data: jsonData, + skipNavigate: true }); this.setState({ blockUI: false }); toast.success("Successfully updated user password"); @@ -91,11 +94,11 @@ class UserProfile extends Component { } catch (error) { this.setState({ blockUI: false }); if ( - (has(error?.response, "data.msgDesc") && - error?.response?.data?.msgDesc == "serverMsg.userMgrOldPassword") || - "serverMsg.userMgrNewPassword" + has(error?.response, "data.msgDesc") && + (error?.response?.data?.msgDesc == "serverMsg.userMgrOldPassword" || + error?.response?.data?.msgDesc == "serverMsg.userMgrNewPassword") ) { - toast.error("You can not use old password."); + toast.error("Error occured while updating user password!"); } console.error(`Error occurred while updating user password! ${error}`); } @@ -103,12 +106,14 @@ class UserProfile extends Component { validatePasswordForm = (values) => { const errors = {}; + if (!values.oldPassword) { errors.oldPassword = "Required"; } if (!values.newPassword) { errors.newPassword = "Required"; } + if ( values && has(values, "newPassword") && @@ -116,19 +121,53 @@ class UserProfile extends Component { ) { errors.newPassword = RegexValidation.PASSWORD.message; } + if (!values.reEnterPassword) { errors.reEnterPassword = "Required"; - } else if (values.newPassword !== values.reEnterPassword) { - errors.reEnterPassword = "Must match"; + } else if ( + has(values, "newPassword") && + values.newPassword !== values.reEnterPassword + ) { + errors.reEnterPassword = + "Re-enter New Password must match with New Password"; } + + if (values && has(values, "oldPassword") && has(values, "newPassword")) { + if (values.oldPassword === values.newPassword) { + errors.newPassword = "New Password cannot be same as Old Password"; + } + } + return errors; }; validateUserForm = (values) => { const errors = {}; + if (!values.firstName) { errors.firstName = "Required"; } + + if ( + values && + has(values, "firstName") && + !RegexValidation.NAME_VALIDATION.regexExpressionForFirstAndLastName.test( + values.firstName + ) + ) { + errors.firstName = RegexMessage.MESSAGE.firstNameValidationMsg; + } + + if ( + values && + has(values, "lastName") && + !RegexValidation.NAME_VALIDATION.regexExpressionForFirstAndLastName.test( + values.lastName + ) + ) { + errors.lastName = RegexMessage.MESSAGE.lastNameValidationMsg; + } + if ( (!isEmpty(values.emailAddress) || !isUndefined(values.emailAddress)) && !RegexValidation.EMAIL_VALIDATION.regexExpressionForEmail.test( @@ -266,7 +305,11 @@ class UserProfile extends Component { ? "isError" : "lastName" } - className="form-control" + className={ + meta.error && meta.touched + ? "form-control border-danger" + : "form-control" + } disabled={ userProps.userSource == UserTypes.USER_INTERNAL.value @@ -282,6 +325,11 @@ class UserProfile extends Component { RegexMessage.MESSAGE.lastNameValidationMsg } /> + {meta.error && meta.touched && ( + <span className="invalid-field"> + {meta.error} + </span> + )} </Col> </Row> )} @@ -318,6 +366,14 @@ class UserProfile extends Component { } data-cy="emailAddress" /> + <InfoIcon + css="info-user-role-grp-icon" + position="right" + message={ + RegexMessage.MESSAGE + .emailvalidationinfomessage + } + /> {meta.error && meta.touched && ( <span className="invalid-field"> {meta.error} @@ -455,7 +511,7 @@ class UserProfile extends Component { position="right" message={ <p - className="pd-10" + className="pd-10 mb-0" style={{ fontSize: "small" }} > {RegexValidation.PASSWORD.message} @@ -503,7 +559,7 @@ class UserProfile extends Component { position="right" message={ <p - className="pd-10" + className="pd-10 mb-0" style={{ fontSize: "small" }} > {RegexValidation.PASSWORD.message} @@ -551,7 +607,7 @@ class UserProfile extends Component { position="right" message={ <p - className="pd-10" + className="pd-10 mb-0" style={{ fontSize: "small" }} > {RegexValidation.PASSWORD.message}