comunicconsole/src/ui/accountSettings/KeySettingsSection.tsx

187 lines
4.2 KiB
TypeScript
Raw Normal View History

2021-05-14 19:09:01 +02:00
import {
Table,
TableHead,
TableRow,
TableCell,
TableBody,
IconButton,
Divider,
Button,
} from "@material-ui/core";
import { Delete } from "@material-ui/icons";
import React from "react";
import { AdminAccount, AccountHelper } from "../../helpers/AccountHelper";
import { AdminAccountKey, AdminKeyHelper } from "../../helpers/AdminKeyHelper";
import { CopyToClipboard } from "../../utils/ClipboardUtils";
import { AsyncWidget } from "../widgets/AsyncWidget";
import {
matConfirm,
snackbar,
matAlert,
input,
} from "../widgets/DialogsProvider";
import { TimestampWidget } from "../widgets/TimestampWidget";
import { SettingsSection } from "./SettingsSection";
export class KeySettingsSection extends React.Component<
{ admin: AdminAccount },
{ keys: AdminAccountKey[]; counter: number }
> {
constructor(props: any) {
super(props);
this.state = {
keys: [],
counter: 1,
};
this.load = this.load.bind(this);
this.build = this.build.bind(this);
this.generateResetToken = this.generateResetToken.bind(this);
this.registerNewKey = this.registerNewKey.bind(this);
this.deleteKey = this.deleteKey.bind(this);
}
async load() {
const keys = await AdminKeyHelper.GetAdminKeys(this.props.admin.id);
this.setState({ keys: keys });
}
async generateResetToken() {
try {
if (
!(await matConfirm(
"Do you really want to generate a reset token for this account?"
))
)
return;
const token = await AccountHelper.GenerateResetToken(
this.props.admin.id
);
CopyToClipboard(token.token);
snackbar("Reset token was successfully copied to the clipboard!");
} catch (e) {
console.error(e);
matAlert("Failed to generate a token!");
}
}
async registerNewKey() {
try {
const challenge =
await AdminKeyHelper.GetKeyRegistrationChallenge();
const credential = await navigator.credentials.create(challenge);
if (credential == null) throw new Error("Operation aborted!");
const name = await input({
label: "Key name",
maxLength: 40,
minLength: 2,
});
await AdminKeyHelper.RegisterKey(name, credential);
snackbar("Successfully enrolled a new key!");
this.setState({ counter: this.state.counter + 1 });
} catch (e) {
console.error(e);
matAlert("Failed to register a new key!");
}
}
async deleteKey(key: AdminAccountKey) {
try {
if (
!(await matConfirm(
"Do you really want to delete the key '" + key.name + "' ?"
))
)
return;
await AdminKeyHelper.DeleteAuthKey(this.props.admin.id, key.id);
snackbar("The key was successfully deleted!");
this.setState({ counter: this.state.counter + 1 });
} catch (e) {
console.error(e);
matAlert("Failed to delete key!");
}
}
render() {
return (
<AsyncWidget
errorMessage="Failed to load admin keys!"
load={this.load}
onBuild={this.build}
key={this.props.admin.id + "-" + this.state.counter}
></AsyncWidget>
);
}
build() {
return (
<SettingsSection title="Security keys">
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Key name</TableCell>
<TableCell align="right">Date added</TableCell>
<TableCell align="right"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.keys.map((key) => (
<TableRow key={key.id}>
<TableCell component="th" scope="row">
{key.name}
</TableCell>
<TableCell align="right">
<TimestampWidget time={key.time_add} />
</TableCell>
<TableCell align="right">
<IconButton
aria-label="delete"
size="small"
onClick={() => this.deleteKey(key)}
>
<Delete />
</IconButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<Divider />
{/* Action buttons */}
<div
style={{
textAlign: "right",
margin: "5px 10px",
}}
>
<Button onClick={this.generateResetToken}>
New reset token
</Button>
<Button
disabled={
this.props.admin.id !==
AccountHelper.currentAccount.id
}
onClick={this.registerNewKey}
>
Register a new key
</Button>
</div>
</SettingsSection>
);
}
}