mirror of
https://github.com/openziti/zrok.git
synced 2024-11-26 01:54:09 +01:00
a better, simpler user interface for token regeneration (#191)
This commit is contained in:
parent
9949a55c1f
commit
36067f5e91
@ -20,6 +20,11 @@ func (handler *resetTokenHandler) Handle(params account.ResetTokenParams, princi
|
|||||||
}
|
}
|
||||||
logrus.Infof("received token reset request for email '%v'", params.Body.EmailAddress)
|
logrus.Infof("received token reset request for email '%v'", params.Body.EmailAddress)
|
||||||
|
|
||||||
|
if params.Body.EmailAddress != principal.Email {
|
||||||
|
logrus.Errorf("mismatched account '%v' for '%v'", params.Body.EmailAddress, principal.Email)
|
||||||
|
return account.NewResetTokenNotFound()
|
||||||
|
}
|
||||||
|
|
||||||
tx, err := str.Begin()
|
tx, err := str.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Errorf("error starting transaction for '%v': %v", params.Body.EmailAddress, err)
|
logrus.Errorf("error starting transaction for '%v': %v", params.Body.EmailAddress, err)
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React, {useState} from "react";
|
import React, {useState} from "react";
|
||||||
import ChangePassword from "./actions/ChangePassword";
|
import ChangePassword from "./actions/ChangePassword";
|
||||||
import ResetToken from "./actions/ResetToken";
|
|
||||||
import {Button} from "react-bootstrap";
|
import {Button} from "react-bootstrap";
|
||||||
|
import RegenerateToken from "./actions/RegenerateToken";
|
||||||
|
|
||||||
const ActionsTab = (props) => {
|
const ActionsTab = (props) => {
|
||||||
const [showResetTokenModal, setShowResetTokenModal] = useState(false);
|
const [showRegenerateTokenModal, setShowRegenerateTokenModal] = useState(false);
|
||||||
const openResetTokenModal = () => setShowResetTokenModal(true);
|
const openRegenerateTokenModal = () => setShowRegenerateTokenModal(true);
|
||||||
const closeResetTokenModal = () => setShowResetTokenModal(false);
|
const closeRegenerateTokenModal = () => setShowRegenerateTokenModal(false);
|
||||||
|
|
||||||
const [showChangePasswordModal, setShowChangePasswordModal] = useState(false);
|
const [showChangePasswordModal, setShowChangePasswordModal] = useState(false);
|
||||||
const openChangePasswordModal = () => setShowChangePasswordModal(true);
|
const openChangePasswordModal = () => setShowChangePasswordModal(true);
|
||||||
@ -40,8 +40,8 @@ const ActionsTab = (props) => {
|
|||||||
need to preserve, your best bet is to update the <code>zrok_token</code> in those environments as
|
need to preserve, your best bet is to update the <code>zrok_token</code> in those environments as
|
||||||
described above.
|
described above.
|
||||||
</p>
|
</p>
|
||||||
<Button variant={"danger"} onClick={openResetTokenModal}>Regenerate Account Token</Button>
|
<Button variant={"danger"} onClick={openRegenerateTokenModal}>Regenerate Account Token</Button>
|
||||||
<ResetToken show={showResetTokenModal} onHide={closeResetTokenModal} user={props.user}/>
|
<RegenerateToken show={showRegenerateTokenModal} onHide={closeRegenerateTokenModal} user={props.user}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
82
ui/src/console/detail/account/actions/RegenerateToken.js
Normal file
82
ui/src/console/detail/account/actions/RegenerateToken.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import Modal from "react-bootstrap/Modal";
|
||||||
|
import {Button, Container, Form, Row} from "react-bootstrap";
|
||||||
|
import React, {useState} from "react";
|
||||||
|
import * as account from "../../../../api/account";
|
||||||
|
|
||||||
|
const RegenerateToken = (props) => {
|
||||||
|
const [confirmEmail, setConfirmEmail] = useState('');
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
|
||||||
|
const hide = () => {
|
||||||
|
props.onHide();
|
||||||
|
setConfirmEmail('');
|
||||||
|
setMessage('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if(confirmEmail !== props.user.email) {
|
||||||
|
setMessage("Email address confirmation does not match!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
account.resetToken({body: {emailAddress: props.user.email}})
|
||||||
|
.then(resp => {
|
||||||
|
console.log(resp);
|
||||||
|
let user = JSON.parse(localStorage.getItem('user'));
|
||||||
|
localStorage.setItem('user', JSON.stringify({
|
||||||
|
email: user.email,
|
||||||
|
token: resp.data.token
|
||||||
|
}));
|
||||||
|
document.dispatchEvent(new Event('storage'));
|
||||||
|
setMessage("Your new account token is: " + resp.data.token);
|
||||||
|
}).catch(err => {
|
||||||
|
setMessage("Account token regeneration failed!");
|
||||||
|
console.log("account token regeneration failed", err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal show={props.show} onHide={hide} size={"md"} centered>
|
||||||
|
<Modal.Header closeButton>Are you very sure?</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<Form onSubmit={handleSubmit}>
|
||||||
|
<Container>
|
||||||
|
<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> ${HOME}/.zrok/environments.yml</code> files
|
||||||
|
with your new token to allow them to continue working!
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Hit <code> Escape </code> or click the 'X' to abort!
|
||||||
|
</p>
|
||||||
|
<Form.Group controlId={"confirmEmail"}>
|
||||||
|
<Form.Control
|
||||||
|
placeholder={"Confirm Your Email Address"}
|
||||||
|
onChange={t => {
|
||||||
|
setMessage('');
|
||||||
|
setConfirmEmail(t.target.value);
|
||||||
|
}}
|
||||||
|
value={confirmEmail}
|
||||||
|
style={{marginBottom: "1em"}}
|
||||||
|
/>
|
||||||
|
</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"}>Regenerate Account Token</Button>
|
||||||
|
</Row>
|
||||||
|
</Container>
|
||||||
|
</Form>
|
||||||
|
</Modal.Body>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RegenerateToken;
|
@ -1,94 +0,0 @@
|
|||||||
import React, {useRef, useState} from "react";
|
|
||||||
import Modal from "react-bootstrap/Modal";
|
|
||||||
import {mdiContentCopy} from "@mdi/js";
|
|
||||||
import Icon from "@mdi/react";
|
|
||||||
import { Button, Overlay, Tooltip } from "react-bootstrap";
|
|
||||||
import * as account from "../../../../api/account";
|
|
||||||
|
|
||||||
const ResetToken = (props) => {
|
|
||||||
const target = useRef(null);
|
|
||||||
const [showTooltip, setShowTooltip] = useState(false);
|
|
||||||
|
|
||||||
const handleCopy = async () => {
|
|
||||||
let copiedText = document.getElementById("zrok-token").innerHTML;
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(copiedText);
|
|
||||||
|
|
||||||
setShowTooltip(true);
|
|
||||||
setTimeout(() => setShowTooltip(false), 1000);
|
|
||||||
|
|
||||||
} catch(err) {
|
|
||||||
console.error("failed to copy", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let resetToken = () => {
|
|
||||||
account.resetToken({ body: { "emailAddress": props.user.email } }).then(resp => {
|
|
||||||
console.log(resp)
|
|
||||||
let user = JSON.parse(localStorage.getItem('user'))
|
|
||||||
localStorage.setItem('user', JSON.stringify({
|
|
||||||
"email": user.email,
|
|
||||||
"token": resp.data.token
|
|
||||||
}));
|
|
||||||
document.dispatchEvent(new Event('storage'))
|
|
||||||
setModalBody((
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
You will need to update your environment files <code> ${HOME}/.zrok/environment.json </code>
|
|
||||||
with the new <code> zrok_token </code>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Your new <code> zrok_token </code> is: <code><span id={"zrok-token"}>{resp.data.token}</span></code>{' '}
|
|
||||||
<Icon ref={target} path={mdiContentCopy} size={0.7} onClick={handleCopy}/>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
));
|
|
||||||
setModalHeader((
|
|
||||||
<span>Account Token Regenerated!</span>
|
|
||||||
))
|
|
||||||
}).catch(err => {
|
|
||||||
console.log("err", err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let hide = () => {
|
|
||||||
setModalHeader(defaultHeader)
|
|
||||||
setModalBody(defaultModal)
|
|
||||||
props.onHide()
|
|
||||||
}
|
|
||||||
|
|
||||||
let defaultHeader = (<span>Are you sure?</span>)
|
|
||||||
let defaultModal = (
|
|
||||||
<div>
|
|
||||||
<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> ${HOME}/.zrok/environments.yml</code> files with your new token!</p>
|
|
||||||
<p align={"right"}>
|
|
||||||
<Button variant={"danger"} onClick={resetToken}>Regenerate Token</Button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const [modalBody, setModalBody] = useState(defaultModal);
|
|
||||||
const [modalHeader, setModalHeader] = useState(defaultHeader);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Modal show={props.show} onHide={hide} size={"lg"} centered>
|
|
||||||
<Modal.Header closeButton>{modalHeader}</Modal.Header>
|
|
||||||
<Modal.Body>
|
|
||||||
{modalBody}
|
|
||||||
</Modal.Body>
|
|
||||||
</Modal>
|
|
||||||
<Overlay target={target.current} show={showTooltip} placement={"bottom"}>
|
|
||||||
{(props) => (
|
|
||||||
<Tooltip id={"copy-tooltip"} {...props}>
|
|
||||||
Copied!
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</Overlay>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ResetToken;
|
|
Loading…
Reference in New Issue
Block a user