diff --git a/next.config.mjs b/next.config.mjs index 669540ec9..1d32a3d5c 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -22,6 +22,27 @@ const nextConfig = { }, ]; }, + async headers() { + return [ + { + source: "/:path*", + headers: [ + { + key: "Referrer-Policy", + value: "no-referrer-when-downgrade", + }, + { + key: "X-DNS-Prefetch-Control", + value: "on", + }, + { + key: "X-Frame-Options", + value: "DENY", + }, + ], + }, + ]; + }, experimental: { outputFileTracingIncludes: { "/api/mupdf/*": ["./node_modules/mupdf/dist/*.wasm"], diff --git a/pages/api/jobs/send-dataroom-new-document-notification.ts b/pages/api/jobs/send-dataroom-new-document-notification.ts index d7c5eeaae..3f5228e8e 100644 --- a/pages/api/jobs/send-dataroom-new-document-notification.ts +++ b/pages/api/jobs/send-dataroom-new-document-notification.ts @@ -37,14 +37,14 @@ export default async function handle( senderUserId: string; }; - let viewer: { email: string; dataroom: { name: string } } | null = null; + let viewer: { email: string; dataroom: { name: string } | null } | null = + null; try { // Fetch the link to verify the settings viewer = await prisma.viewer.findUnique({ where: { id: viewerId, - dataroomId: dataroomId, }, select: { email: true, @@ -98,7 +98,7 @@ export default async function handle( } await sendDataroomNotification({ - dataroomName: viewer.dataroom.name, + dataroomName: viewer.dataroom?.name ?? "", senderEmail: user.email!, documentName: document?.document.name, to: viewer.email, diff --git a/pages/api/jobs/send-dataroom-view-invitation.ts b/pages/api/jobs/send-dataroom-view-invitation.ts index 98080ce23..63bfc98f8 100644 --- a/pages/api/jobs/send-dataroom-view-invitation.ts +++ b/pages/api/jobs/send-dataroom-view-invitation.ts @@ -35,14 +35,14 @@ export default async function handle( senderUserId: string; }; - let viewer: { email: string; dataroom: { name: string } } | null = null; + let viewer: { email: string; dataroom: { name: string } | null } | null = + null; try { // Fetch the link to verify the settings viewer = await prisma.viewer.findUnique({ where: { id: viewerId, - dataroomId: dataroomId, }, select: { email: true, @@ -82,7 +82,7 @@ export default async function handle( // send email to document owner that document await sendDataroomViewerInvite({ - dataroomName: viewer.dataroom.name, + dataroomName: viewer.dataroom?.name ?? "", senderEmail: user.email!, to: viewer.email, url: `${process.env.NEXT_PUBLIC_MARKETING_URL}/view/${linkId}?email=${encodeURIComponent(viewer.email)}`, diff --git a/prisma/migrations/20240921000000_add_viewer_migration/migration.sql b/prisma/migrations/20240921000000_add_viewer_migration/migration.sql new file mode 100644 index 000000000..95e896a07 --- /dev/null +++ b/prisma/migrations/20240921000000_add_viewer_migration/migration.sql @@ -0,0 +1,16 @@ +-- DropForeignKey +ALTER TABLE "Viewer" DROP CONSTRAINT "Viewer_dataroomId_fkey"; + +-- DropIndex +DROP INDEX "Viewer_dataroomId_email_key"; + +-- AlterTable +ALTER TABLE "Viewer" ALTER COLUMN "dataroomId" DROP NOT NULL, +ALTER COLUMN "teamId" SET NOT NULL; + +-- CreateIndex +CREATE UNIQUE INDEX "Viewer_teamId_email_key" ON "Viewer"("teamId", "email"); + +-- AddForeignKey +ALTER TABLE "Viewer" ADD CONSTRAINT "Viewer_dataroomId_fkey" FOREIGN KEY ("dataroomId") REFERENCES "Dataroom"("id") ON DELETE SET NULL ON UPDATE CASCADE; + diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c7792b269..dd8ced26b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -125,27 +125,27 @@ model VerificationToken { } model Document { - id String @id @default(cuid()) - name String - description String? - file String // This should be a reference to where the file is stored (S3, Google Cloud Storage, etc.) - originalFile String? // This should be a reference to the original file like pptx, xlsx, etc. (S3, Google Cloud Storage, etc.) - type String? // This should be a reference to the file type (pdf, sheet, etc.) - contentType String? // This should be the actual contentType of the file like application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, etc. - storageType DocumentStorageType @default(VERCEL_BLOB) - numPages Int? // This should be a reference to the number of pages in the document - owner User? @relation(fields: [ownerId], references: [id], onDelete: SetNull) - teamId String - team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) - ownerId String? // This field holds the foreign key. - assistantEnabled Boolean @default(false) // This indicates if assistant is enabled for this document + id String @id @default(cuid()) + name String + description String? + file String // This should be a reference to where the file is stored (S3, Google Cloud Storage, etc.) + originalFile String? // This should be a reference to the original file like pptx, xlsx, etc. (S3, Google Cloud Storage, etc.) + type String? // This should be a reference to the file type (pdf, sheet, etc.) + contentType String? // This should be the actual contentType of the file like application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, etc. + storageType DocumentStorageType @default(VERCEL_BLOB) + numPages Int? // This should be a reference to the number of pages in the document + owner User? @relation(fields: [ownerId], references: [id], onDelete: SetNull) + teamId String + team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) + ownerId String? // This field holds the foreign key. + assistantEnabled Boolean @default(false) // This indicates if assistant is enabled for this document advancedExcelEnabled Boolean @default(false) // This indicates if advanced Excel is enabled for this document - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - links Link[] - views View[] - versions DocumentVersion[] - conversations Conversation[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + links Link[] + views View[] + versions DocumentVersion[] + conversations Conversation[] folderId String? // Optional Folder ID for documents in folders folder Folder? @relation(fields: [folderId], references: [id], onDelete: SetNull) @@ -339,10 +339,10 @@ model Viewer { verified Boolean @default(false) // Whether the viewer email has been verified invitedAt DateTime? // This is the time the viewer was invited - dataroomId String - dataroom Dataroom @relation(fields: [dataroomId], references: [id], onDelete: Cascade) - teamId String? - team Team? @relation(fields: [teamId], references: [id], onDelete: Cascade) + dataroomId String? + dataroom Dataroom? @relation(fields: [dataroomId], references: [id], onDelete: SetNull) + teamId String + team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) views View[] groups ViewerGroupMembership[] @@ -350,7 +350,7 @@ model Viewer { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - @@unique([dataroomId, email]) + @@unique([teamId, email]) @@index([teamId]) @@index([dataroomId]) }