Certificates Renewal + SSE

- Certificate renewal is just a re-request as it's forced already
- Rejig the routes for readability
- Added Server Side Events so that the UI would invalidate the
cache when changes happen on the backend, such as certs being
provided or failing
- Added a SSE Token, which has the same shelf life as normal token
but can't be used interchangeably. The reason for this is, the
SSE endpoint needs a token for auth as a Query param, so it would
be stored in log files. If someone where to get a hold of that,
it's pretty useless as it can't be used to change anything, only
to listen for events until it expires
- Added test endpoint for SSE testing only availabe in debug mode
This commit is contained in:
Jamie Curnow
2023-03-07 16:42:26 +10:00
parent 35550082bf
commit 215083f6cf
29 changed files with 665 additions and 197 deletions

View File

@ -25,6 +25,7 @@ export interface TableProps {
sortBy: TableSortBy[];
filters: TableFilter[];
onTableEvent: any;
onRenewal: (id: number) => void;
}
function Table({
data,
@ -32,6 +33,7 @@ function Table({
onTableEvent,
sortBy,
filters,
onRenewal,
}: TableProps) {
const [editId, setEditId] = useState(0);
const [columns, tableData] = useMemo(() => {
@ -85,7 +87,7 @@ function Table({
title: intl.formatMessage({
id: "action.renew",
}),
onClick: (e: any, { id }: any) => alert(id),
onClick: (e: any, { id }: any) => onRenewal(id),
icon: <FiRefreshCw />,
disabled: (data: any) =>
data.type !== "dns" && data.type !== "http",
@ -110,7 +112,7 @@ function Table({
},
];
return [columns, data];
}, [data]);
}, [data, onRenewal]);
const tableInstance = useTable(
{

View File

@ -1,9 +1,11 @@
import { useEffect, useReducer, useState } from "react";
import { Alert, AlertIcon } from "@chakra-ui/react";
import { Alert, AlertIcon, useToast } from "@chakra-ui/react";
import { renewCertificate } from "api/npm";
import { EmptyList, SpinnerPage, tableEventReducer } from "components";
import { useCertificates } from "hooks";
import { intl } from "locale";
import { useQueryClient } from "react-query";
import Table from "./Table";
@ -19,6 +21,9 @@ const initialState = {
filters: [],
};
function TableWrapper() {
const toast = useToast();
const queryClient = useQueryClient();
const [{ offset, limit, sortBy, filters }, dispatch] = useReducer(
tableEventReducer,
initialState,
@ -36,6 +41,32 @@ function TableWrapper() {
setTableData(data as any);
}, [data]);
const renewCert = async (id: number) => {
try {
await renewCertificate(id);
toast({
description: intl.formatMessage({
id: `certificate.renewal-requested`,
}),
status: "info",
position: "top",
duration: 3000,
isClosable: true,
});
setTimeout(() => {
queryClient.invalidateQueries("certificates");
}, 500);
} catch (err: any) {
toast({
description: err.message,
status: "error",
position: "top",
duration: 3000,
isClosable: true,
});
}
};
if (isFetching || isLoading || !tableData) {
return <SpinnerPage />;
}
@ -76,6 +107,7 @@ function TableWrapper() {
sortBy={sortBy}
filters={filters}
onTableEvent={dispatch}
onRenewal={renewCert}
/>
);
}