85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
// @ts-nocheck
|
|
import { S3, GetObjectCommand } from "@aws-sdk/client-s3";
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
import { basename } from "node:path";
|
|
import { getServerEntry } from "../database/queries/server-queries.js";
|
|
import { ERR } from "../util/logging.js";
|
|
import { checkAuthorization } from "../database/queries/server-queries.js";
|
|
const s3Region = "us-east-1";
|
|
|
|
async function getS3BackupData(serverId) {
|
|
const serverEntry = await getServerEntry(serverId);
|
|
if (!serverEntry?.backupHost) return undefined;
|
|
const s3Config = {
|
|
credentials: {
|
|
accessKeyId: serverEntry.backupId,
|
|
secretAccessKey: serverEntry.backupKey,
|
|
},
|
|
endpoint: `https://${serverEntry.backupHost}`,
|
|
forcePathStyle: true,
|
|
region: s3Region,
|
|
};
|
|
const pathParts = serverEntry.backupPath.split("/");
|
|
if (pathParts[0] === "") pathParts.shift();
|
|
const bucket = pathParts.shift();
|
|
const backupPrefix = pathParts.join("/");
|
|
return { s3Config, bucket, backupPrefix };
|
|
}
|
|
|
|
export async function listS3Backups(req, res) {
|
|
const serverSpec = req.body;
|
|
if (!serverSpec.id) return res.status(400).send("Server id missing!");
|
|
const authorized = await checkAuthorization(serverSpec.id, req.cairoId);
|
|
if (!authorized)
|
|
return res
|
|
.status(403)
|
|
.send("You do not have permission to access that server!");
|
|
const s3Data = await getS3BackupData(serverSpec.id);
|
|
if (!s3Data) return res.status(409).send("Backup not configured!");
|
|
const { s3Config, bucket, backupPrefix } = s3Data;
|
|
const s3Client = new S3(s3Config);
|
|
try {
|
|
const listResponse = await s3Client.listObjectsV2({
|
|
Bucket: bucket,
|
|
Prefix: backupPrefix,
|
|
});
|
|
const files =
|
|
listResponse.Contents?.map((f) => ({
|
|
name: basename(f.Key),
|
|
lastModified: f.LastModified,
|
|
path: f.Key,
|
|
size: f.Size,
|
|
})) ?? [];
|
|
res.json(files);
|
|
} catch (e) {
|
|
ERR("S3", e);
|
|
res.sendStatus(500);
|
|
}
|
|
}
|
|
|
|
export async function getS3BackupUrl(req, res) {
|
|
const serverSpec = req.body;
|
|
if (!serverSpec.id) return res.status(400).send("Server id missing!");
|
|
if (!serverSpec.backupPath)
|
|
return res.status(400).send("Backup path missing!");
|
|
const authorized = await checkAuthorization(serverSpec.id, req.cairoId);
|
|
if (!authorized)
|
|
return res
|
|
.status(403)
|
|
.send("You do not have permission to access that server!");
|
|
const s3Data = await getS3BackupData(serverSpec.id);
|
|
if (!s3Data) return res.status(409).send("Backup not configured!");
|
|
const { s3Config, bucket } = s3Data;
|
|
const s3Client = new S3(s3Config);
|
|
try {
|
|
const command = new GetObjectCommand({
|
|
Bucket: bucket,
|
|
Key: serverSpec.backupPath,
|
|
});
|
|
const url = await getSignedUrl(s3Client, command, { expiresIn: 3600 });
|
|
res.json({ url });
|
|
} catch (e) {
|
|
ERR("S3", e);
|
|
res.sendStatus(500);
|
|
}
|
|
}
|