Initial commit
This commit is contained in:
commit
78f8d225ee
21173 changed files with 2907774 additions and 0 deletions
50
app/api/files/route.ts
Normal file
50
app/api/files/route.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import fs from "node:fs/promises";
|
||||
import fssync from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const BASE = "/app/files"; // this is /var/www/makearmy.io/app/files on the host
|
||||
|
||||
function safeJoin(base: string, reqPath: string) {
|
||||
const decoded = decodeURIComponent(reqPath || "/");
|
||||
// normalize, strip traversal, and join under BASE
|
||||
const normalized = path.posix.normalize("/" + decoded).replace(/^(\.\.(\/|\\|$))+/g, "");
|
||||
const full = path.join(base, normalized);
|
||||
if (!full.startsWith(base)) throw new Error("Invalid path");
|
||||
return full;
|
||||
}
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const { searchParams } = new URL(req.url);
|
||||
const p = searchParams.get("path") || "/";
|
||||
const abs = safeJoin(BASE, p);
|
||||
|
||||
const entries = await fs.readdir(abs, { withFileTypes: true });
|
||||
const rows = await Promise.all(entries.map(async (ent) => {
|
||||
const full = path.join(abs, ent.name);
|
||||
const stat = await fs.stat(full);
|
||||
const isDir = ent.isDirectory();
|
||||
return {
|
||||
name: ent.name,
|
||||
type: isDir ? "dir" : "file",
|
||||
size: isDir ? null : stat.size,
|
||||
mtime: stat.mtime.toISOString(),
|
||||
path: path.posix.join(p.endsWith("/") ? p : p + "/", ent.name),
|
||||
// raw download/view URL (served by /api/files/raw)
|
||||
url: isDir ? null : `/api/files/raw?path=${encodeURIComponent(path.posix.join(p, ent.name))}`,
|
||||
};
|
||||
}));
|
||||
|
||||
// Sort: directories first, then files alphabetically
|
||||
rows.sort((a, b) => {
|
||||
if (a.type !== b.type) return a.type === "dir" ? -1 : 1;
|
||||
return a.name.localeCompare(b.name, undefined, { sensitivity: "base" });
|
||||
});
|
||||
|
||||
return NextResponse.json({ ok: true, path: p, items: rows });
|
||||
} catch (err: any) {
|
||||
return NextResponse.json({ ok: false, error: err?.message || "Error" }, { status: 400 });
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue