feat: Add backup system for ZIP downloads
This commit is contained in:
@@ -22,6 +22,7 @@ import { logsRouter } from "./routes/logs.ts";
|
||||
import { userSettingsRouter } from "./routes/usersettings.ts";
|
||||
import gitlabRouter from "./routes/gitlab.ts";
|
||||
import { giteaRouter } from "./routes/gitea.ts";
|
||||
import { backupRouter } from "./routes/backup.ts";
|
||||
import { dockerRouter } from "./routes/docker.ts";
|
||||
import { exportRouter } from "./routes/export.ts";
|
||||
import { appUpdateRouter } from "./routes/appUpdate.ts";
|
||||
@@ -78,6 +79,8 @@ app.use(userSettingsRouter.allowedMethods());
|
||||
app.use(gitlabRouter.routes());
|
||||
app.use(giteaRouter.routes());
|
||||
app.use(giteaRouter.allowedMethods());
|
||||
app.use(backupRouter.routes());
|
||||
app.use(backupRouter.allowedMethods());
|
||||
app.use(gitlabRouter.allowedMethods());
|
||||
app.use(dockerRouter.routes());
|
||||
app.use(dockerRouter.allowedMethods());
|
||||
|
||||
71
src/routes/backup.ts
Normal file
71
src/routes/backup.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Router } from "@oak/oak";
|
||||
import { authMiddleware } from "../middleware/auth.ts";
|
||||
|
||||
const router = new Router();
|
||||
|
||||
const GITEA_URL = Deno.env.get("GITEA_URL") || "https://git.kronos-soulution.de";
|
||||
const GITEA_TOKEN = Deno.env.get("GITEA_TOKEN") || "";
|
||||
|
||||
interface GiteaRepo {
|
||||
id: number;
|
||||
name: string;
|
||||
full_name: string;
|
||||
description: string | null;
|
||||
default_branch: string;
|
||||
html_url: string;
|
||||
updated_at: string;
|
||||
size: number;
|
||||
owner: { login: string };
|
||||
}
|
||||
|
||||
// Get all repos with download info
|
||||
router.get("/api/backup/repos", authMiddleware, async (ctx) => {
|
||||
try {
|
||||
const response = await fetch(`${GITEA_URL}/api/v1/user/repos?limit=100`, {
|
||||
headers: { "Authorization": `token ${GITEA_TOKEN}` }
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error("Failed to fetch repos");
|
||||
|
||||
const repos: GiteaRepo[] = await response.json();
|
||||
|
||||
ctx.response.body = repos.map(r => ({
|
||||
id: r.id,
|
||||
name: r.name,
|
||||
fullName: r.full_name,
|
||||
description: r.description,
|
||||
branch: r.default_branch,
|
||||
url: r.html_url,
|
||||
updatedAt: r.updated_at,
|
||||
size: r.size,
|
||||
downloadUrl: `${GITEA_URL}/${r.full_name}/archive/${r.default_branch}.zip`
|
||||
}));
|
||||
} catch (err) {
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: err instanceof Error ? err.message : "Failed to fetch repos" };
|
||||
}
|
||||
});
|
||||
|
||||
// Proxy download (to avoid CORS issues)
|
||||
router.get("/api/backup/download/:owner/:repo", authMiddleware, async (ctx) => {
|
||||
const { owner, repo } = ctx.params;
|
||||
const branch = ctx.request.url.searchParams.get("branch") || "main";
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${GITEA_URL}/${owner}/${repo}/archive/${branch}.zip`,
|
||||
{ headers: { "Authorization": `token ${GITEA_TOKEN}` } }
|
||||
);
|
||||
|
||||
if (!response.ok) throw new Error(`Download failed: ${response.status}`);
|
||||
|
||||
ctx.response.headers.set("Content-Type", "application/zip");
|
||||
ctx.response.headers.set("Content-Disposition", `attachment; filename="${repo}-${branch}.zip"`);
|
||||
ctx.response.body = response.body;
|
||||
} catch (err) {
|
||||
ctx.response.status = 500;
|
||||
ctx.response.body = { error: err instanceof Error ? err.message : "Download failed" };
|
||||
}
|
||||
});
|
||||
|
||||
export const backupRouter = router;
|
||||
Reference in New Issue
Block a user