From c592857b1955951f541803c046bddd663a675f63 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 7 Jul 2025 17:21:45 +0200 Subject: [PATCH 1/5] Update Schema (and Mock Data) --- README.md | 1 + src/lib/mock-data.ts | 1 - src/server/db/schema.ts | 17 ++++++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index da6e2d9..df4281a 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ The database and UI are now connected, some improvements to make: Uploading a file to '[uploadthing](https://uploadthing.com/)' works, things that can be approved: +- [ ] Add "ownership" to files and folders - [ ] Upload files to the right folder - [ ] Delete file button - [ ] Allow files that are not images to be uploaded diff --git a/src/lib/mock-data.ts b/src/lib/mock-data.ts index ba2e9a2..50f1e5b 100644 --- a/src/lib/mock-data.ts +++ b/src/lib/mock-data.ts @@ -16,7 +16,6 @@ export type Folder = { // prettier-ignore export const mockFolders: Folder[] = [ - { id: "root", name: "root", type: "folder", parent: null }, // the root folder { id: "1", name: "Documents", type: "folder", parent: "root" }, { id: "2", name: "Images", type: "folder", parent: "root" }, { id: "3", name: "Work", type: "folder", parent: "root" }, diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts index 9a67b4e..7745fda 100644 --- a/src/server/db/schema.ts +++ b/src/server/db/schema.ts @@ -4,6 +4,7 @@ import { text, singlestoreTableCreator, bigint, + timestamp, } from "drizzle-orm/singlestore-core"; const createTable = singlestoreTableCreator((name) => `drive_tutorial_${name}`); @@ -14,12 +15,17 @@ export const files_table = createTable( id: bigint("id", { mode: "number", unsigned: true }) .primaryKey() .autoincrement(), + ownerId: text("owner_id").notNull(), name: text("name").notNull(), url: text("url").notNull(), size: int("size").notNull(), - parent: bigint("parent", { mode: "number", unsigned: true }), + parent: bigint("parent", { mode: "number", unsigned: true }).notNull(), + createdAt: timestamp("created_at").notNull().defaultNow(), }, - (table) => [index("parent_index").on(table.parent)], + (table) => [ + index("owner_id_index").on(table.ownerId), + index("parent_index").on(table.parent), + ], ); export const folders_table = createTable( @@ -28,10 +34,15 @@ export const folders_table = createTable( id: bigint("id", { mode: "number", unsigned: true }) .primaryKey() .autoincrement(), + ownerId: text("owner_id").notNull(), name: text("name").notNull(), parent: bigint("parent", { mode: "number", unsigned: true }), + createdAt: timestamp("created_at").notNull().defaultNow(), }, - (table) => [index("parent_index").on(table.parent)], + (table) => [ + index("owner_id_index").on(table.ownerId), + index("parent_index").on(table.parent), + ], ); export type File = typeof files_table.$inferSelect; From e96c267500d4a1f4897fc08ac539767b90ed25be Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 10 Jul 2025 08:02:44 +0200 Subject: [PATCH 2/5] Add Folder Id when Uploadin a File --- src/app/api/uploadthing/core.ts | 19 ++++++++++++++----- src/server/db/mutations.ts | 7 +++++-- src/server/db/queries.ts | 8 ++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/app/api/uploadthing/core.ts b/src/app/api/uploadthing/core.ts index 61a82aa..59e9041 100644 --- a/src/app/api/uploadthing/core.ts +++ b/src/app/api/uploadthing/core.ts @@ -1,26 +1,35 @@ +/* eslint-disable @typescript-eslint/only-throw-error */ + import { auth } from "@clerk/nextjs/server"; import { createUploadthing, type FileRouter } from "uploadthing/next"; import { UploadThingError } from "uploadthing/server"; +import { z } from "zod"; import * as mutations from "~/server/db/mutations"; +import * as queries from "~/server/db/queries"; const f = createUploadthing(); export const ourFileRouter = { imageUploader: f({ image: { maxFileSize: "4MB", maxFileCount: 1 } }) - .middleware(async () => { + .input(z.object({ folderId: z.number() })) + .middleware(async ({ input }) => { const user = await auth(); - - // eslint-disable-next-line @typescript-eslint/only-throw-error if (!user.userId) throw new UploadThingError("Unauthorized"); - return { userId: user.userId }; + const folder = await queries.getFolderById(input.folderId); + if (!folder) throw new UploadThingError("Folder not found"); + + if (folder.ownerId !== user.userId) + throw new UploadThingError("Unauthorized"); + + return { userId: user.userId, parent: folder.id }; }) .onUploadComplete(async ({ metadata, file }) => { console.log("Upload complete for userId:", metadata.userId); console.log("file url", file.ufsUrl); - const uploadedFile = { ...file, parent: 0 }; + const uploadedFile = { ...file, parent: metadata.parent }; await mutations.createFile(uploadedFile, metadata.userId); return { uploadedBy: metadata.userId }; diff --git a/src/server/db/mutations.ts b/src/server/db/mutations.ts index d28a28e..bfedb51 100644 --- a/src/server/db/mutations.ts +++ b/src/server/db/mutations.ts @@ -1,6 +1,9 @@ import { db } from "~/server/db"; import { type File, files_table as filesSchema } from "~/server/db/schema"; -export function createFile(file: Omit, _userId: string) { - return db.insert(filesSchema).values({ ...file, parent: 1 }); +export function createFile( + file: Pick, + userId: string, +) { + return db.insert(filesSchema).values({ ...file, ownerId: userId }); } diff --git a/src/server/db/queries.ts b/src/server/db/queries.ts index 4ba47f7..e20fd24 100644 --- a/src/server/db/queries.ts +++ b/src/server/db/queries.ts @@ -33,6 +33,14 @@ export function getAllFolders(folderId: number) { .where(eq(folderSchema.parent, folderId)); } +export async function getFolderById(folderId: number) { + const folders = await db + .select() + .from(folderSchema) + .where(eq(folderSchema.id, folderId)); + return folders[0]; +} + export function getAllFiles(folderId: number) { return db.select().from(fileSchema).where(eq(fileSchema.parent, folderId)); } From 75ce114fba173ef9f14ecc96172860cc6b97dfc3 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 10 Jul 2025 08:17:03 +0200 Subject: [PATCH 3/5] Use Folder Id from URL when Uploading a File --- src/app/drive-contents.tsx | 2 ++ src/app/f/[folderId]/page.tsx | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/drive-contents.tsx b/src/app/drive-contents.tsx index f5a8149..6195554 100644 --- a/src/app/drive-contents.tsx +++ b/src/app/drive-contents.tsx @@ -13,6 +13,7 @@ export default function DriveContents(props: { files: File[]; folders: Folder[]; parents: Folder[]; + currentFolderId: number; }) { const navigate = useRouter(); @@ -65,6 +66,7 @@ export default function DriveContents(props: { { navigate.refresh(); }} diff --git a/src/app/f/[folderId]/page.tsx b/src/app/f/[folderId]/page.tsx index 5c1a3b6..f788a9b 100644 --- a/src/app/f/[folderId]/page.tsx +++ b/src/app/f/[folderId]/page.tsx @@ -20,5 +20,12 @@ export default async function GoogleDriveClone(props: { queries.getAllParentsForFolder(data.folderId), ]); - return ; + return ( + + ); } From a4aa904af95f75a9be1e97b59cf4b78d4bb619eb Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 10 Jul 2025 08:19:57 +0200 Subject: [PATCH 4/5] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index df4281a..09a7e12 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ The database and UI are now connected, some improvements to make: Uploading a file to '[uploadthing](https://uploadthing.com/)' works, things that can be approved: -- [ ] Add "ownership" to files and folders -- [ ] Upload files to the right folder +- [x] Add "ownership" to files and folders +- [x] Upload files to the right folder - [ ] Delete file button - [ ] Allow files that are not images to be uploaded From 83a0be186bfd5be3d7aa9a9c1e755035b9414565 Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 10 Jul 2025 08:40:26 +0200 Subject: [PATCH 5/5] Allow All Kind of File Types --- README.md | 2 +- src/app/api/uploadthing/core.ts | 2 +- src/app/drive-contents.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 09a7e12..a7dea1f 100644 --- a/README.md +++ b/README.md @@ -115,4 +115,4 @@ can be approved: - [x] Add "ownership" to files and folders - [x] Upload files to the right folder - [ ] Delete file button -- [ ] Allow files that are not images to be uploaded +- [x] Allow files that are not images to be uploaded diff --git a/src/app/api/uploadthing/core.ts b/src/app/api/uploadthing/core.ts index 59e9041..ba0baac 100644 --- a/src/app/api/uploadthing/core.ts +++ b/src/app/api/uploadthing/core.ts @@ -11,7 +11,7 @@ import * as queries from "~/server/db/queries"; const f = createUploadthing(); export const ourFileRouter = { - imageUploader: f({ image: { maxFileSize: "4MB", maxFileCount: 1 } }) + driveUploader: f({ blob: { maxFileSize: "4MB", maxFileCount: 1 } }) .input(z.object({ folderId: z.number() })) .middleware(async ({ input }) => { const user = await auth(); diff --git a/src/app/drive-contents.tsx b/src/app/drive-contents.tsx index 6195554..97636d8 100644 --- a/src/app/drive-contents.tsx +++ b/src/app/drive-contents.tsx @@ -65,7 +65,7 @@ export default function DriveContents(props: { { navigate.refresh();