ui refactoring for change password (#148)

This commit is contained in:
Michael Quigley 2024-02-16 15:19:32 -05:00
parent fa91d091bb
commit 9949a55c1f
No known key found for this signature in database
GPG Key ID: 9B60314A9DD20A62
3 changed files with 102 additions and 78 deletions

View File

@ -16,7 +16,7 @@ const ActionsTab = (props) => {
<div className={"actions-tab"}>
<div id={"change-password"} style={{"padding-top": "10px"}}>
<h3>Change Password?</h3>
<p>Note that this will <strong>not</strong> log out of any already logged in sessions.</p>
<p>Change your password here. Note that this will <strong>not</strong> log you out of any already logged in sessions.</p>
<Button variant={"danger"} onClick={openChangePasswordModal}>Change Password</Button>
<ChangePassword show={showChangePasswordModal} onHide={closeChangePasswordModal} user={props.user}/>
</div>

View File

@ -1,23 +1,43 @@
import React, { useEffect, useState } from "react";
import React, {useEffect, useState} from "react";
import * as account from "../../../../api/account";
import * as metadata from "../../../../api/metadata";
import { Button, Container, Form, Row } from "react-bootstrap";
import PasswordForm from "../../../../components/password";
import {Button, Container, Form, Row} from "react-bootstrap";
import Modal from "react-bootstrap/Modal";
import * as metadata from "../../../../api/metadata";
const validatePassword = (password, l, rc, rn, rs, spc, cb) => {
if(password.length < l) {
cb(false, "Entered password is too short! (" + l + " characters minimum)!");
return;
}
if(rc && !/[A-Z]/.test(password)) {
cb(false, "Entered password requires a capital letter!");
return;
}
if(rn && !/\d/.test(password)) {
cb(false, "Entered password requires a digit!");
return;
}
if(rs) {
if(!spc.split("").some(v => password.includes(v))) {
cb(false, "Entered password requires a special character!");
return;
}
}
return cb(true, "");
}
const ChangePassword = (props) => {
const [oldPassword, setOldPassword] = useState('');
const [newPassword, setNewPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [message, setMessage] = useState('');
const [complete, setComplete] = useState(false);
const [passwordLength, setPasswordLength] = useState(10);
const [passwordLength, setPasswordLength] = useState(8);
const [passwordRequireCapital, setPasswordRequireCapital] = useState(true);
const [passwordRequireNumeric, setPasswordRequireNumeric] = useState(true);
const [passwordRequireSpecial, setPasswordRequireSpecial] = useState(true);
const [passwordValidSpecialCharacters, setPasswordValidSpecialCharacters] = useState("");
const errorMessage = <h2 className={"errorMessage"}>Change Password Failed!</h2>;
useEffect(() => {
metadata.configuration().then(resp => {
if (!resp.error) {
@ -28,90 +48,95 @@ const ChangePassword = (props) => {
setPasswordValidSpecialCharacters(resp.data.passwordRequirements.validSpecialCharacters)
}
}).catch(err => {
console.log("err", err);
console.log("error getting configuration", err);
});
}, [])
const handleSubmit = async e => {
e.preventDefault();
if (newPassword !== undefined && newPassword !== "" && oldPassword !== undefined && oldPassword !== "") {
account.changePassword({ body: { "email": props.user.email, "oldPassword": oldPassword, "newPassword": newPassword } })
.then(resp => {
if (!resp.error) {
console.log("resp", resp)
setMessage(undefined);
setComplete(true)
} else {
setMessage(errorMessage);
}
}).catch(resp => {
console.log("resp", resp)
setMessage(errorMessage)
})
let ok = false;
validatePassword(newPassword,
passwordLength,
passwordRequireCapital,
passwordRequireNumeric,
passwordRequireSpecial,
passwordValidSpecialCharacters, (isOk, msg) => { ok = isOk; setMessage(msg); })
if(!ok) {
return;
}
if(confirmPassword !== newPassword) {
setMessage("New password and confirmation do not match!");
return;
}
account.changePassword({ body: { oldPassword: oldPassword, newPassword: newPassword, email: props.user.email } })
.then(resp => {
if (!resp.error) {
console.log("resp", resp)
setMessage("Password successfully changed!");
} else {
setMessage("Failure changing password! Is old password correct?");
}
}).catch(resp => {
console.log("resp", resp)
setMessage("Failure changing password! Is old password correct?")
})
}
let hide = () => {
props.onHide();
setMessage("");
setComplete(false);
setOldPassword("");
setNewPassword("");
setConfirmPassword("");
}
if (!complete) {
return (
<Modal show={props.show} onHide={hide} centered>
<Modal.Header closeButton>Change Password</Modal.Header>
<Modal.Body>
<Form onSubmit={handleSubmit}>
<div className="container" style={{ marginBottom: "1em" }}>
<Form.Group controlId={"oldPassword"}>
<Form.Control
type={"password"}
placeholder={"Old Password"}
onChange={t => { setOldPassword(t.target.value); }}
value={oldPassword}
/>
</Form.Group>
</div>
<PasswordForm
setMessage={setMessage}
passwordLength={passwordLength}
passwordRequireCapital={passwordRequireCapital}
passwordRequireNumeric={passwordRequireNumeric}
passwordRequireSpecial={passwordRequireSpecial}
passwordValidSpecialCharacters={passwordValidSpecialCharacters}
setParentPassword={setNewPassword} />
<Row style={{ justifyContent: "center", marginTop: "1em" }}>
<Button variant={"light"} type={"submit"}>Reset Password</Button>
</Row>
</Form>
{message}
</Modal.Body>
</Modal>
)
}
else {
return (
<Modal show={props.show} onHide={hide} centered>
return (
<Modal show={props.show} onHide={hide} size={"md"} centered>
<Modal.Header closeButton>Change Password</Modal.Header>
<Modal.Body>
<Container fluid>
<Row>
<h1>Change Password</h1>
</Row>
<Row>
Password reset successful! You can now return to the actions page.
</Row>
<Row>
<Button variant={"light"} onClick={hide}>Back</Button>
</Row>
</Container>
</Modal.Body>
</Modal>
)
}
<Form onSubmit={handleSubmit}>
<Container>
<Form.Group controlId={"oldPassword"}>
<Form.Control
type={"password"}
placeholder={"Old Password"}
onChange={t => { setMessage(''); setOldPassword(t.target.value); }}
value={oldPassword}
style={{ marginBottom: "1em" }}
/>
</Form.Group>
<Form.Group controlId={"newPassword"}>
<Form.Control
type={"password"}
placeholder={"New Password"}
onChange={t => { setMessage(''); setNewPassword(t.target.value); }}
value={newPassword}
style={{ marginBottom: "1em" }}
/>
</Form.Group>
<Form.Group controlId={"confirmPassword"}>
<Form.Control
type={"password"}
placeholder={"Confirm Password"}
onChange={t => { setMessage(''); setConfirmPassword(t.target.value); }}
value={confirmPassword}
/>
</Form.Group>
<Row style={{ justifyContent: "center", marginTop: "1em" }}>
<p style={{ color: "red" }}>{message}</p>
</Row>
<Row style={{ justifyContent: "right", marginTop: "1em" }}>
<Button variant={"danger"} type={"submit"}>Change Password</Button>
</Row>
</Container>
</Form>
</Modal.Body>
</Modal>
);
}
export default ChangePassword;

View File

@ -64,7 +64,6 @@ const ResetToken = (props) => {
<p>Did you read the warning on the previous screen? This action will reset all of your active environments and shares!</p>
<p>You will need to update each of your <code> &#36;&#123;HOME&#125;/.zrok/environments.yml</code> files with your new token!</p>
<p align={"right"}>
<Button onClick={props.onHide}>Cancel</Button>
<Button variant={"danger"} onClick={resetToken}>Regenerate Token</Button>
</p>
</div>
@ -75,7 +74,7 @@ const ResetToken = (props) => {
return (
<div>
<Modal show={props.show} onHide={hide} centered>
<Modal show={props.show} onHide={hide} size={"lg"} centered>
<Modal.Header closeButton>{modalHeader}</Modal.Header>
<Modal.Body>
{modalBody}