1
0
Fork 0

feat: add backup list/viewer

user-stream
Lea 2023-08-22 18:29:48 +02:00
parent a03c539890
commit d1ff57b239
Signed by: lea
GPG Key ID: 1BAFFE8347019C42
5 changed files with 89 additions and 2 deletions

View File

@ -0,0 +1,18 @@
import { JsonCard } from "@/components/cards/JsonCard";
import { Card, CardHeader, CardTitle } from "@/components/ui/card";
import { fetchBackup } from "@/lib/actions"
export default async function Report({ params }: { params: { name: string } }) {
const name = decodeURIComponent(params.name);
const backup = await fetchBackup(name);
return <>
<Card>
<CardHeader>
<CardTitle>{name}</CardTitle>
</CardHeader>
</Card>
<br />
<JsonCard obj={backup} />
</>
}

View File

@ -0,0 +1,37 @@
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { fetchBackups } from "@/lib/actions";
import Link from "next/link";
export default async function Backups() {
const backups = await fetchBackups();
return (
<Card>
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Type</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{backups.map((backup) => (
<TableRow key={backup.name}>
<TableCell>{backup.name}</TableCell>
<TableCell>{backup.type}</TableCell>
<TableCell>
<Link href={`/panel/backups/${encodeURIComponent(backup.name)}`}>
<Button>
Open
</Button>
</Link>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Card>
);
}

View File

@ -1,6 +1,7 @@
import Link from "next/link";
import { buttonVariants } from "../ui/button";
import {
Bomb,
Eye,
Globe2,
Home,
@ -38,6 +39,12 @@ export function NavigationLinks() {
>
<Search className="h-4 w-4" />
</Link>
<Link
className={buttonVariants({ variant: "outline", size: "icon" })}
href="/panel/backups"
>
<Bomb className="h-4 w-4" />
</Link>
{/*<Link
className={buttonVariants({ variant: "outline", size: "icon" })}
href="/panel/discover"

View File

@ -53,7 +53,8 @@ type Permission =
| `safety_notes${
| ""
| `/fetch${"" | `/${SafetyNotes["_id"]["type"]}`}`
| `/update${"" | `/${SafetyNotes["_id"]["type"]}`}`}`;
| `/update${"" | `/${SafetyNotes["_id"]["type"]}`}`}`
| `backup${"" | `/fetch${"" | "/by-name"}`}`;
const PermissionSets = {
// Admin
@ -149,6 +150,7 @@ const PermissionSets = {
"channels/create/dm",
"servers/update/quarantine",
"backup/fetch",
"reports/fetch/related/by-user",
"reports/fetch/related/by-content",

View File

@ -1,6 +1,6 @@
"use server";
import { writeFile } from "fs/promises";
import { readFile, readdir, writeFile } from "fs/promises";
import { PLATFORM_MOD_ID, RESTRICT_ACCESS_LIST } from "./constants";
import mongo, {
Account,
@ -862,3 +862,26 @@ export async function cancelAccountDeletion(accountId: string) {
}
);
}
export async function fetchBackups() {
await checkPermission("backup/fetch", null);
return await Promise.all(
(await readdir("./exports", { withFileTypes: true }))
.filter((file) => file.isFile() && file.name.endsWith(".json"))
.map(async (file) => {
let type: string | null = null;
try {
type = JSON.parse((await readFile(`./exports/${file.name}`)).toString("utf-8"))._event;
} catch(e) {}
return { name: file.name, type: type }
})
);
}
export async function fetchBackup(name: string) {
await checkPermission("backup/fetch/by-name", null);
return JSON.parse((await readFile(`./exports/${name}`)).toString("utf-8"));
}