243 lines
6.1 KiB
TypeScript
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>
|
|
);
|
|
}
|