import { Button, Grid } from "@mui/material"; import React from "react"; import { useNavigate } from "react-router-dom"; import { NWFilter, NWFilterApi } from "../../api/NWFilterApi"; import { NetworkApi, NetworkInfo } from "../../api/NetworksApi"; import { ServerApi } from "../../api/ServerApi"; import { APIToken, TokensApi } from "../../api/TokensApi"; import { VMApi, VMInfo } from "../../api/VMApi"; import { useAlert } from "../../hooks/providers/AlertDialogProvider"; import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider"; import { useSnackbar } from "../../hooks/providers/SnackbarProvider"; import { AsyncWidget } from "../AsyncWidget"; import { TabsWidget } from "../TabsWidget"; import { EditSection } from "../forms/EditSection"; import { IPInputWithMask } from "../forms/IPInput"; import { RadioGroupInput } from "../forms/RadioGroupInput"; import { TextInput } from "../forms/TextInput"; import { TokenRawRightsEditor } from "./TokenRawRightsEditor"; import { TokenRightsEditor } from "./TokenRightsEditor"; const SECS_PER_DAY = 3600 * 24; export enum TokenWidgetStatus { Create, Read, Update, } interface DetailsProps { token: APIToken; status: TokenWidgetStatus; onChange?: () => void; } export function APITokenDetails(p: DetailsProps): React.ReactElement { const [vms, setVMs] = React.useState(); const [networks, setNetworks] = React.useState(); const [nwFilters, setNetworkFilters] = React.useState(); const [tokens, setTokens] = React.useState(); const load = async () => { setVMs(await VMApi.GetList()); setNetworks(await NetworkApi.GetList()); setNetworkFilters(await NWFilterApi.GetList()); setTokens(await TokensApi.GetList()); }; return ( ( )} /> ); } enum TokenTab { General = 0, Rights, RawRights, Danger, } type DetailsInnerProps = DetailsProps & { vms: VMInfo[]; networks: NetworkInfo[]; nwFilters: NWFilter[]; tokens: APIToken[]; }; function APITokenDetailsInner(p: DetailsInnerProps): React.ReactElement { const [currTab, setCurrTab] = React.useState(TokenTab.General); return ( <> {currTab === TokenTab.General && } {currTab === TokenTab.Rights && } {currTab === TokenTab.RawRights && } {currTab === TokenTab.Danger && } ); } function APITokenTabGeneral(p: DetailsInnerProps): React.ReactElement { const [ipVersion, setIpVersion] = React.useState<4 | 6>( (p.token.ip_restriction ?? "").includes(":") ? 6 : 4 ); return ( {/* Metadata section */} {p.status !== TokenWidgetStatus.Create && ( )} { p.token.name = v ?? ""; p.onChange?.(); }} size={ServerApi.Config.constraints.api_token_name_size} /> { p.token.description = v ?? ""; p.onChange?.(); }} multiline={true} size={ServerApi.Config.constraints.api_token_description_size} /> {p.status === TokenWidgetStatus.Create && ( { setIpVersion(Number(v) as any); }} label="Token IP restriction version" /> )} { p.token.ip_restriction = ipAndMask; p.onChange?.(); }} /> { const secs = Number(v ?? "0") * SECS_PER_DAY; p.token.max_inactivity = secs === 0 ? undefined : secs; p.onChange?.(); }} /> ); } function APITokenRights(p: DetailsInnerProps): React.ReactElement { return (
); } function APITokenRawRights(p: DetailsInnerProps): React.ReactElement { return (
); } function APITokenTabDanger(p: DetailsInnerProps): React.ReactElement { const confirm = useConfirm(); const snackbar = useSnackbar(); const alert = useAlert(); const navigate = useNavigate(); const requestDelete = async () => { try { if ( !(await confirm( "Do you really want to delete this API token?", `Delete API token ${p.token.name}`, "Delete" )) ) return; await TokensApi.Delete(p.token); navigate("/tokens"); snackbar("The API token was successfully deleted!"); } catch (e) { console.error(e); alert(`Failed to delete the API token!\n${e}`); } }; return ( ); }