changed all things to use id instead of file name

This commit is contained in:
ZareMate 2025-04-15 08:03:59 +02:00
parent b4eb2b4657
commit 7133c544e1
Signed by: zaremate
GPG Key ID: 369A0E45E03A81C3
6 changed files with 48 additions and 33 deletions

View File

@ -37,13 +37,13 @@ export default function FileGrid({ session }: FileGridProps) {
}
};
const handleDownload = async (fileName: string) => {
const handleDownload = async (fileId: string, fileName: string) => {
try {
const response = await fetch(`/api/files/download?fileId=${encodeURIComponent(fileName)}`);
const response = await fetch(`/api/files/download?fileId=${encodeURIComponent(fileId)}&fileName=${encodeURIComponent(fileName)}`);
if (!response.ok) {
throw new Error("Failed to download file");
}
// Download the file with the correct filename
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
@ -143,7 +143,7 @@ export default function FileGrid({ session }: FileGridProps) {
<div className="flex gap-2">
{/* Download Button */}
<button
onClick={() => handleDownload(file.name)}
onClick={() => handleDownload(file.id,file.name)}
className="flex items-center justify-center rounded-full bg-blue-500 p-2 hover:bg-blue-600"
>
<svg

View File

@ -5,10 +5,14 @@ import { promises as fs } from "fs";
export async function GET(req: Request) {
const url = new URL(req.url);
const fileId = url.searchParams.get("fileId");
const fileName = url.searchParams.get("fileName");
if (!fileId) {
return NextResponse.json({ error: "File id is required" }, { status: 400 });
}
if (!fileName){
return NextResponse.json({ error: "File name is required" }, { status: 400 });
}
try {
const filePath = path.join(process.cwd(), "uploads", fileId);
@ -17,7 +21,7 @@ export async function GET(req: Request) {
return new Response(fileBuffer, {
headers: {
"Content-Type": "application/octet-stream",
"Content-Disposition": `attachment; filename="${fileId}"`,
"Content-Disposition": `attachment; filename="${fileName}"`,
},
});
} catch (error) {

View File

@ -26,7 +26,7 @@ export async function DELETE(req: Request) {
return NextResponse.json({ error: "Resource not found or unauthorized" }, { status: 404 });
}
const filePath = path.join(process.cwd(), "uploads", path.basename(resource.name));
const filePath = path.join(process.cwd(), "uploads", path.basename(body.id));
await fs.unlink(filePath).catch((err) => {
console.error("Error deleting file from filesystem:", err);
});

View File

@ -5,15 +5,15 @@ import { auth } from "~/server/auth";
export async function GET(req: Request) {
const session = await auth();
const url = new URL(req.url);
const fileName = url.searchParams.get("id");
const fileId = url.searchParams.get("id");
if (!fileName) {
if (!fileId) {
return NextResponse.json({ error: "File name is required" }, { status: 400 });
}
try {
const file = await db.file.findFirst({
where: { name: fileName },
where: { id: fileId },
include: { uploadedBy: true },
});

View File

@ -6,6 +6,7 @@ import { auth } from "~/server/auth";
import Busboy from "busboy";
import { Readable } from "stream";
import { notifyClients } from "~/utils/notifyClients";
import crypto from "crypto";
export const config = {
api: {
@ -15,6 +16,8 @@ export const config = {
export async function POST(req: Request) {
const session = await auth();
// generate id for the file
const guid = crypto.randomUUID();
if (!session?.user) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
@ -59,13 +62,14 @@ export async function POST(req: Request) {
busboy.on("finish", () => {
void (async () => {
try {
const filePath = path.join(uploadDir, fileName);
const filePath = path.join(uploadDir, guid);
await fs.writeFile(filePath, fileBuffer);
// Save file metadata to the database
const newFile = await db.file.create({
data: {
url: `/share?id=${fileName}`,
id: guid,
url: `/share?id=${guid}`,
name: fileName,
size: fileBuffer.length,
extension: path.extname(fileName),

View File

@ -55,31 +55,31 @@ function UploadsPage() {
toast.error("File details not available.");
return;
}
const response = await fetch(`/api/files/download?fileId=${encodeURIComponent(fileDetails?.name)}`); // Use optional chaining
if (!response.ok) {
throw new Error("Failed to download file");
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileId ?? "downloaded-file"; // Use nullish coalescing
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
toast.success("File downloaded successfully!");
} catch (err) {
console.error(err);
toast.error("Failed to download file.");
}
};
const response = await fetch(`/api/files/download?fileId=${encodeURIComponent(fileDetails.id)}&fileName=${encodeURIComponent(fileDetails.name)}`);
if (!response.ok) {
throw new Error("Failed to download file");
}
// Download the file with the correct filename
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = fileDetails.name;
document.body.appendChild(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
toast.success(`File "${fileDetails.name}" downloaded successfully!`);
} catch (err) {
console.error(err);
toast.error("Failed to download file.");
}
};
const handleShare = () => {
if (fileDetails) {
const shareableLink = `${window.location.origin}/share?id=${fileDetails.name}`;
const shareableLink = `${window.location.origin}/share?id=${fileDetails.id}`;
navigator.clipboard
.writeText(shareableLink)
.then(() => toast.success("Shareable link copied to clipboard!"))
@ -136,6 +136,13 @@ function UploadsPage() {
return (
<main className="relative flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c] text-white">
<meta property="og:title" content={fileDetails.name} />
<meta property="og:description" content={`File details for ${fileDetails.name}`} />
<meta property="og:image" content={fileDetails.url} />
<meta property="og:url" content={`${window.location.origin}/share?id=${fileDetails.id}`} />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="File Hosting - Suchodupin" />
<meta property="og:locale" content="en_US" />
<Toaster position="top-right" reverseOrder={false} />
<div className="absolute top-4 left-4">
<button