MoneyMgr/moneymgr_web/src/dialogs/CreateTokenDialog.tsx

243 lines
6.1 KiB
TypeScript

import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
Tooltip,
} from "@mui/material";
import React from "react";
import { ServerApi } from "../api/ServerApi";
import { NewToken, TokenWithSecret, TokensApi } from "../api/TokensApi";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
import { checkConstraint } from "../utils/FormUtils";
import { CheckboxInput } from "../widgets/forms/CheckboxInput";
import { TextInput } from "../widgets/forms/TextInput";
const SECS_IN_DAY = 3600 * 24;
export function CreateTokenDialog(p: {
open: boolean;
onClose: () => void;
onCreated: (t: TokenWithSecret) => void;
}): React.ReactElement {
const alert = useAlert();
const loadingMessage = useLoadingMessage();
const [newTokenUndef, setNewToken] = React.useState<NewToken | undefined>();
const newToken = newTokenUndef ?? {
name: "",
ip_net: undefined,
max_inactivity: 3600 * 24 * 90,
read_only: false,
right_account: false,
right_file: false,
right_auth: false,
right_inbox: false,
right_movement: false,
right_stats: false,
right_backup: false,
};
const clearForm = () => {
setNewToken(undefined);
};
const cancel = () => {
p.onClose();
clearForm();
};
const nameErr = checkConstraint(
ServerApi.Config.constraints.token_name,
newToken.name
);
const isValid = nameErr === undefined;
const submit = async () => {
try {
loadingMessage.show("Creating token...");
const token = await TokensApi.Create(newToken);
clearForm();
p.onCreated(token);
} catch (e) {
console.error(e);
alert(`Failed to create token ! ${e}`);
} finally {
loadingMessage.hide();
}
};
const updateRightsForMobileApp = () => {
setNewToken({
...newToken,
read_only: false,
right_account: false,
right_movement: false,
right_file: true,
right_auth: true,
right_inbox: true,
right_stats: false,
right_backup: false,
});
};
return (
<Dialog open={p.open} onClose={cancel}>
<DialogTitle>New token</DialogTitle>
<DialogContent>
<TextInput
editable
label="Token name"
value={newToken.name}
onValueChange={(v) => {
setNewToken({
...newToken,
name: v ?? "",
});
}}
size={ServerApi.Config.constraints.token_name}
/>
<TextInput
editable
label="IP Network (optional)"
value={newToken.ip_net}
onValueChange={(v) => {
setNewToken({
...newToken,
ip_net: v ?? "",
});
}}
size={ServerApi.Config.constraints.token_ip_net}
/>
<TextInput
editable
label="Max inactivity period (days)"
type="number"
value={(newToken.max_inactivity / SECS_IN_DAY).toString()}
onValueChange={(i) => {
setNewToken({
...newToken,
max_inactivity: Number(i) * SECS_IN_DAY,
});
}}
size={{
min:
ServerApi.Config.constraints.token_max_inactivity.min /
SECS_IN_DAY,
max:
ServerApi.Config.constraints.token_max_inactivity.max /
SECS_IN_DAY,
}}
/>
<CheckboxInput
editable
label="Read only"
checked={newToken.read_only}
onValueChange={(v) => {
setNewToken({
...newToken,
read_only: v,
});
}}
/>
<Tooltip title="Tailor the rights for the mobile application">
<Button onClick={updateRightsForMobileApp}>For mobile app</Button>
</Tooltip>
<br />
<CheckboxInput
editable
label="Right: account routes"
checked={newToken.right_account}
onValueChange={(v) => {
setNewToken({
...newToken,
right_account: v,
});
}}
/>
<br />
<CheckboxInput
editable
label="Right: movement routes"
checked={newToken.right_movement}
onValueChange={(v) => {
setNewToken({
...newToken,
right_movement: v,
});
}}
/>
<br />
<CheckboxInput
editable
label="Right: inbox routes"
checked={newToken.right_inbox}
onValueChange={(v) => {
setNewToken({
...newToken,
right_inbox: v,
});
}}
/>
<br />
<CheckboxInput
editable
label="Right: file routes"
checked={newToken.right_file}
onValueChange={(v) => {
setNewToken({
...newToken,
right_file: v,
});
}}
/>
<br />
<CheckboxInput
editable
label="Right: auth routes"
checked={newToken.right_auth}
onValueChange={(v) => {
setNewToken({
...newToken,
right_auth: v,
});
}}
/>
<br />
<CheckboxInput
editable
label="Right: statistics routes"
checked={newToken.right_stats}
onValueChange={(v) => {
setNewToken({
...newToken,
right_stats: v,
});
}}
/>
<br />
<CheckboxInput
editable
label="Right: backup routes"
checked={newToken.right_backup}
onValueChange={(v) => {
setNewToken({
...newToken,
right_backup: v,
});
}}
/>
</DialogContent>
<DialogActions>
<Button onClick={cancel}>Cancel</Button>
<Button onClick={submit} autoFocus disabled={!isValid}>
Create
</Button>
</DialogActions>
</Dialog>
);
}