Files
panel/src/app/api/files/[fileId]/route.js

187 lines
4.3 KiB
JavaScript

import { NextResponse } from "next/server";
import { readFile } from "fs/promises";
import { existsSync } from "fs";
import { unlink } from "fs/promises";
import path from "path";
import db from "@/lib/db";
export async function GET(request, { params }) {
const { fileId } = await params;
try {
// Get file info from database
const file = db.prepare(`
SELECT * FROM file_attachments WHERE file_id = ?
`).get(parseInt(fileId));
if (!file) {
return NextResponse.json(
{ error: "File not found" },
{ status: 404 }
);
}
// Construct the full file path
const fullPath = path.join(process.cwd(), "public", file.file_path);
// Check if file exists
if (!existsSync(fullPath)) {
return NextResponse.json(
{ error: "File not found on disk" },
{ status: 404 }
);
}
// Read the file
const fileBuffer = await readFile(fullPath);
// Return the file with appropriate headers
return new NextResponse(fileBuffer, {
headers: {
"Content-Type": file.mime_type || "application/octet-stream",
"Content-Disposition": `attachment; filename="${encodeURIComponent(file.original_filename)}"`,
"Content-Length": fileBuffer.length.toString(),
},
});
} catch (error) {
console.error("Error downloading file:", error);
return NextResponse.json(
{ error: "Failed to download file" },
{ status: 500 }
);
}
}
export async function PUT(request, { params }) {
const { fileId } = await params;
try {
const body = await request.json();
const { description, original_filename } = body;
// Validate input
if (description !== undefined && typeof description !== 'string') {
return NextResponse.json(
{ error: "Description must be a string" },
{ status: 400 }
);
}
if (original_filename !== undefined && typeof original_filename !== 'string') {
return NextResponse.json(
{ error: "Original filename must be a string" },
{ status: 400 }
);
}
// Check if file exists
const existingFile = db.prepare(`
SELECT * FROM file_attachments WHERE file_id = ?
`).get(parseInt(fileId));
if (!existingFile) {
return NextResponse.json(
{ error: "File not found" },
{ status: 404 }
);
}
// Build update query
const updates = [];
const values = [];
if (description !== undefined) {
updates.push('description = ?');
values.push(description);
}
if (original_filename !== undefined) {
updates.push('original_filename = ?');
values.push(original_filename);
}
if (updates.length === 0) {
return NextResponse.json(
{ error: "No valid fields to update" },
{ status: 400 }
);
}
values.push(parseInt(fileId));
const result = db.prepare(`
UPDATE file_attachments
SET ${updates.join(', ')}
WHERE file_id = ?
`).run(...values);
if (result.changes === 0) {
return NextResponse.json(
{ error: "File not found" },
{ status: 404 }
);
}
// Get updated file
const updatedFile = db.prepare(`
SELECT * FROM file_attachments WHERE file_id = ?
`).get(parseInt(fileId));
return NextResponse.json(updatedFile);
} catch (error) {
console.error("Error updating file:", error);
return NextResponse.json(
{ error: "Failed to update file" },
{ status: 500 }
);
}
}
export async function DELETE(request, { params }) {
const { fileId } = await params;
try {
// Get file info from database
const file = db.prepare(`
SELECT * FROM file_attachments WHERE file_id = ?
`).get(parseInt(fileId));
if (!file) {
return NextResponse.json(
{ error: "File not found" },
{ status: 404 }
);
}
// Delete physical file
try {
const fullPath = path.join(process.cwd(), "public", file.file_path);
await unlink(fullPath);
} catch (fileError) {
console.warn("Could not delete physical file:", fileError.message);
// Continue with database deletion even if file doesn't exist
}
// Delete from database
const result = db.prepare(`
DELETE FROM file_attachments WHERE file_id = ?
`).run(parseInt(fileId));
if (result.changes === 0) {
return NextResponse.json(
{ error: "File not found" },
{ status: 404 }
);
}
return NextResponse.json({ success: true });
} catch (error) {
console.error("Error deleting file:", error);
return NextResponse.json(
{ error: "Failed to delete file" },
{ status: 500 }
);
}
}