Skip to content

Commit

Permalink
Feature force reset (#152)
Browse files Browse the repository at this point in the history
Upgrade Kratos dependency to v0.10.1

Signed-off-by: Akshay Gaikwad <[email protected]>

implement handling force reset for user reset

Signed-off-by: mabhi <[email protected]>

handle auto password generate and reset forceReset to false

Signed-off-by: mabhi <[email protected]>
  • Loading branch information
mabhi authored Jan 27, 2023
1 parent 543abaf commit 278300f
Show file tree
Hide file tree
Showing 17 changed files with 272 additions and 140 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.

## Unreleased
### Added
- Enhance: Navigate user to reset page using force reset during first login [mabhi](https://github.com/mabhi)
- Upgraded Ory Kratos client to v0.10.1 [akshay196](https://github.com/akshay196)


## [0.1.6]- 2022-12-29
### Fixed
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@material-ui/core": "^4.9.7",
"@material-ui/icons": "^4.5.1",
"@material-ui/lab": "^4.0.0-alpha.56",
"@ory/kratos-client": "^0.9.0-alpha.3",
"@ory/kratos-client": "0.10.1",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
Expand Down
14 changes: 14 additions & 0 deletions src/actions/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export function getSSOUserDetail(name) {

export function addUser(params) {
return function (dispatch) {
params.spec.forceReset = true;
http("auth")
.post("users/", params)
.then((response) => {
Expand All @@ -98,6 +99,7 @@ export function addUserWithCallback(params, onSuccess, onFailure) {
const organization = JSON.parse(window?.localStorage.getItem("organization"));
params.metadata.partner = partner;
params.metadata.organization = organization;
params.spec.forceReset = true;
return function (dispatch) {
http("auth")
.post("users", params)
Expand Down Expand Up @@ -188,6 +190,18 @@ export function editUser(params) {
};
}

export function updateForceReset(successcb, errcb) {
http("auth")
.put(`user/reset`)
.then((editresponse) => {
console.log(editresponse);
successcb();
})
.catch((error) => {
errcb(error);
});
}

export function updateSSOUser(params) {
const partner = JSON.parse(window?.localStorage.getItem("partner"));
const organization = JSON.parse(window?.localStorage.getItem("organization"));
Expand Down
40 changes: 30 additions & 10 deletions src/appMain/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import React from "react";
import AppBar from "@material-ui/core/AppBar";
import { connect } from "react-redux";
import Toolbar from "@material-ui/core/Toolbar";
import UserInfo from "components/UserInfo";
import ParalusLogo from "assets/images/paralus-logo.png";
import TopNavBar from "./TopNavBar";

const Header = ({ partnerDetail }) => {
const Header = ({ partnerDetail, user, userAndRoleDetail }) => {
let image_src = "";
let hasAccess =
user === null ||
(!!user && !user.spec.forceReset) ||
(user.spec.forceReset &&
user.metadata.name !== userAndRoleDetail.metadata.name);
if (partnerDetail) {
image_src = ParalusLogo;
}
Expand All @@ -17,15 +23,20 @@ const Header = ({ partnerDetail }) => {
return (
<AppBar className="app-main-header">
<Toolbar className="app-toolbar" disableGutters={false}>
<div className="text-center" style={{ minWidth: "143px" }}>
<a className="app-logo" href="#/">
<img src={image_src} alt="" title="" />
</a>
</div>
<div className="ml-4">
<TopNavBar />
</div>
{/* only show the header profile details if user has already set his password */}
{hasAccess && (
<>
<div className="text-center" style={{ minWidth: "143px" }}>
<a className="app-logo" href="#/">
<img src={image_src} alt="" title="" />
</a>
</div>

<div className="ml-4">
<TopNavBar />
</div>
</>
)}
<div className="ml-auto">
<UserInfo />
</div>
Expand All @@ -34,4 +45,13 @@ const Header = ({ partnerDetail }) => {
);
};

export default Header;
const mapStateToProps = ({ Users, settings }) => {
const { user } = Users;
const { userAndRoleDetail } = settings;
return {
user,
userAndRoleDetail,
};
};

export default connect(mapStateToProps, null)(Header);
83 changes: 55 additions & 28 deletions src/appMain/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,19 @@ class AppMain extends React.Component {
UserSession,
userLogout,
organization,
userAndRoleDetail,
user,
} = this.props;
let favicon_src = ParalusMark;
if (partnerDetail && partnerDetail.fav_icon_link) {
favicon_src = partnerDetail.fav_icon_link;
}
const hasAccess = this.userHasAccess();
const forceResetEnabledForUser =
user === null ||
(!!user && !user.spec.forceReset) ||
(user.spec.forceReset &&
user.metadata.name !== userAndRoleDetail.metadata.name);
if (
!hasAccess &&
!UserSession.noRolesUser &&
Expand Down Expand Up @@ -165,33 +172,43 @@ class AppMain extends React.Component {
/>
</div>
)}
{hasAccess && currentProject && currentProject.metadata.name && (
<main className="app-main-content-wrapper">
<div className="app-main-content">
<Container maxWidth="lg">
<Route exact path={`${match.url}`} component={Home} />
<Route path={`${match.url}/users`} component={Users} />
<Route path={`${match.url}/settings`} component={Settings} />
<Route path={`${match.url}/tools`} component={Tools} />
<Route path={`${match.url}/audit`} component={AuditLogs} />
<Route path={`${match.url}/projects`} component={Project} />
<Route path={`${match.url}/groups`} component={Group} />
<Route path={`${match.url}/roles`} component={Roles} />
<Route
exact
path={`${match.url}/sso/new`}
component={RegistrationWizard}
/>
<Route
exact
path={`${match.url}/sso/update/:ssoId`}
component={RegistrationWizard}
/>
<Route exact path={`${match.url}/sso`} component={IdpList} />
</Container>
</div>
</main>
)}
{hasAccess &&
currentProject &&
currentProject.metadata.name &&
forceResetEnabledForUser && (
<main className="app-main-content-wrapper">
<div className="app-main-content">
<Container maxWidth="lg">
<Route exact path={`${match.url}`} component={Home} />
<Route path={`${match.url}/users`} component={Users} />
<Route
path={`${match.url}/settings`}
component={Settings}
/>
<Route path={`${match.url}/tools`} component={Tools} />
<Route path={`${match.url}/audit`} component={AuditLogs} />
<Route path={`${match.url}/projects`} component={Project} />
<Route path={`${match.url}/groups`} component={Group} />
<Route path={`${match.url}/roles`} component={Roles} />
<Route
exact
path={`${match.url}/sso/new`}
component={RegistrationWizard}
/>
<Route
exact
path={`${match.url}/sso/update/:ssoId`}
component={RegistrationWizard}
/>
<Route
exact
path={`${match.url}/sso`}
component={IdpList}
/>
</Container>
</div>
</main>
)}
{!this.props.kubectlOpen && <Footer />}
</div>
{hasAccess && currentProject?.metadata.name && <MiniKubectl />}
Expand All @@ -200,18 +217,28 @@ class AppMain extends React.Component {
}
}

const mapStateToProps = ({ settings, Projects, UserSession, Kubectl }) => {
const mapStateToProps = ({
settings,
Projects,
UserSession,
Kubectl,
Users,
}) => {
const { organization, partnerDetail, reloadApp, userAndRoleDetail } =
settings;
const { currentProject } = Projects;
const kubectlOpen = Kubectl?.open;
const { user } = Users;

return {
partnerDetail,
currentProject,
reloadApp,
organization,
UserSession,
kubectlOpen,
userAndRoleDetail,
user,
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const GridLayout = ({ leftTitle, rightTitle, leftView, rightView }) => {
<Grid
container
spacing={2}
justify="center"
justifyContent="center"
alignItems="stretch"
className={classes.root}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const Profile = ({ user, handleAccountChange }) => {
<ValidatorForm
noValidate
autoComplete="off"
// onSubmit={handleAdduser}
onSubmit={() => {}}
onError={(errors) => console.log(errors)}
>
<div className="row">
Expand All @@ -55,7 +55,7 @@ const Profile = ({ user, handleAccountChange }) => {
value={user.metadata.name}
label="Email"
fullWidth
disabled={user.metadata.id}
disabled={!!user.metadata.id}
validators={["required", "isEmail"]}
errorMessages={["this field is required", "email is not valid"]}
/>
Expand Down
21 changes: 10 additions & 11 deletions src/appMain/routes/users/routes/UsersList/UserList.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ class UserList extends React.Component {
if (props.isAddUserSuccess && props.newUser) {
this.setState({ open: false });
this.fetchUsers();
this.setState({ newUserOpen: true, newUserName: props.newUser.username });
this.setState({
newUserOpen: true,
newUserName: props.newUser.metadata.name,
});
}
if (props.isEditUserSuccess) {
this.fetchUsers();
Expand Down Expand Up @@ -440,7 +443,7 @@ class UserList extends React.Component {
.catch((error) => {
this.setState({
showAlert: true,
recoveryLink: null,
recoveryLink: null, // existing user
alertMessage: parseError(error) || "Unexpected Error",
alertSeverity: "error",
});
Expand Down Expand Up @@ -742,22 +745,18 @@ class UserList extends React.Component {
>
<DialogContent>
New user <a style={{ color: "teal" }}>{this.state.newUserName}</a>,
has been added successfully. Use the following link to set the
password:
has been added successfully. Use the following to set the password:
<br />
<div className={style.urlCopy}>
<a
style={{ color: "teal" }}
href={this.props.newUser?.recoveryUrl}
>
{this.props.newUser?.recoveryUrl}
</a>
<span style={{ color: "teal" }}>
{this.props.newUser?.spec.password}
</span>
{copyable && (
<Tooltip title={"Copy"} id="clip">
<IconButton
onClick={() => {
navigator.clipboard.writeText(
`${this.props.newUser?.recoveryUrl}`
`${this.props.newUser?.spec.password}`
);
}}
aria-label="copy"
Expand Down
2 changes: 1 addition & 1 deletion src/components/ProjectList.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const ProjectList = ({ roles, handleClick, showExpandedList = false }) => {
) : (
<>
{projectList?.baseList.map((item, idx) => (
<span className={classes.activeLabel}>
<span className={classes.activeLabel} key={idx}>
{item} {idx !== projectList.baseList.length - 1 && ", "}
</span>
))}
Expand Down
4 changes: 2 additions & 2 deletions src/components/TableComponents/DataTableHead.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ const DataTableHead = ({
>
{isSortEnabled && !column.disableSorting ? (
<TableSortLabel
active={orderBy && orderBy === column.id}
active={!!orderBy && orderBy === column.id}
disabled={column.disableSorting || false}
direction={orderBy && orderBy === column.id ? order : "asc"}
direction={!!orderBy && orderBy === column.id ? order : "asc"}
onClick={createSortHandler(column.id)}
>
{column.label}
Expand Down
22 changes: 13 additions & 9 deletions src/components/TableComponents/DataTableRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,19 @@ const DataTableRow = ({ rowIndex, data, parseRowData }) => {
if (b.type === "edit-icon") {
return (
<Tooltip key={i} title="Edit">
<IconButton
key={i}
aria-label="edit"
disabled={b.disabled}
className="m-0"
onClick={b.handleClick}
>
<EditIcon fontSize="small" />
</IconButton>
{b.disabled ? (
<span></span>
) : (
<IconButton
key={i}
aria-label="edit"
disabled={b.disabled}
className="m-0"
onClick={b.handleClick}
>
<EditIcon fontSize="small" />
</IconButton>
)}
</Tooltip>
);
}
Expand Down
Loading

0 comments on commit 278300f

Please sign in to comment.