From f6d5eb577755e9f28c27265c3fe263ea8749e009 Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Fri, 18 Feb 2022 18:18:38 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=9B=82=20Protect=20from=20others?= =?UTF-8?q?=20to=20consult=20typebots=20and=20folders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/builder/pages/api/folders/[id].ts | 9 +++++---- apps/builder/pages/api/typebots/[typebotId].ts | 10 ++++++---- .../migration.sql | 16 ++++++++++++++++ packages/db/prisma/schema.prisma | 4 +++- 4 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 packages/db/prisma/migrations/20220218171811_add_unique_constraints/migration.sql diff --git a/apps/builder/pages/api/folders/[id].ts b/apps/builder/pages/api/folders/[id].ts index b27f85bc6..8467145f2 100644 --- a/apps/builder/pages/api/folders/[id].ts +++ b/apps/builder/pages/api/folders/[id].ts @@ -1,5 +1,5 @@ import { withSentry } from '@sentry/nextjs' -import { DashboardFolder } from 'db' +import { DashboardFolder, User } from 'db' import prisma from 'libs/prisma' import { NextApiRequest, NextApiResponse } from 'next' import { getSession } from 'next-auth/react' @@ -12,22 +12,23 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { return res.status(401).json({ message: 'Not authenticated' }) const id = req.query.id.toString() + const user = session.user as User if (req.method === 'GET') { const folder = await prisma.dashboardFolder.findUnique({ - where: { id }, + where: { id_ownerId: { id, ownerId: user.id } }, }) return res.send({ folder }) } if (req.method === 'DELETE') { const folders = await prisma.dashboardFolder.delete({ - where: { id }, + where: { id_ownerId: { id, ownerId: user.id } }, }) return res.send({ folders }) } if (req.method === 'PATCH') { const data = JSON.parse(req.body) as Partial const folders = await prisma.dashboardFolder.update({ - where: { id }, + where: { id_ownerId: { id, ownerId: user.id } }, data, }) return res.send({ typebots: folders }) diff --git a/apps/builder/pages/api/typebots/[typebotId].ts b/apps/builder/pages/api/typebots/[typebotId].ts index a9f930e74..0b13243de 100644 --- a/apps/builder/pages/api/typebots/[typebotId].ts +++ b/apps/builder/pages/api/typebots/[typebotId].ts @@ -1,4 +1,5 @@ import { withSentry } from '@sentry/nextjs' +import { User } from 'db' import prisma from 'libs/prisma' import { NextApiRequest, NextApiResponse } from 'next' import { getSession } from 'next-auth/react' @@ -11,9 +12,10 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { return res.status(401).json({ message: 'Not authenticated' }) const typebotId = req.query.typebotId.toString() + const user = session.user as User if (req.method === 'GET') { const typebot = await prisma.typebot.findUnique({ - where: { id: typebotId }, + where: { id_ownerId: { id: typebotId, ownerId: user.id } }, include: { publishedTypebot: true, }, @@ -24,14 +26,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { } if (req.method === 'DELETE') { const typebots = await prisma.typebot.delete({ - where: { id: typebotId }, + where: { id_ownerId: { id: typebotId, ownerId: user.id } }, }) return res.send({ typebots }) } if (req.method === 'PUT') { const data = JSON.parse(req.body) const typebots = await prisma.typebot.update({ - where: { id: typebotId }, + where: { id_ownerId: { id: typebotId, ownerId: user.id } }, data: { ...data, theme: data.theme ?? undefined, @@ -43,7 +45,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { if (req.method === 'PATCH') { const data = JSON.parse(req.body) const typebots = await prisma.typebot.update({ - where: { id: typebotId }, + where: { id_ownerId: { id: typebotId, ownerId: user.id } }, data, }) return res.send({ typebots }) diff --git a/packages/db/prisma/migrations/20220218171811_add_unique_constraints/migration.sql b/packages/db/prisma/migrations/20220218171811_add_unique_constraints/migration.sql new file mode 100644 index 000000000..5f55cbe8e --- /dev/null +++ b/packages/db/prisma/migrations/20220218171811_add_unique_constraints/migration.sql @@ -0,0 +1,16 @@ +/* + Warnings: + + - A unique constraint covering the columns `[code]` on the table `Coupon` will be added. If there are existing duplicate values, this will fail. + - A unique constraint covering the columns `[id,ownerId]` on the table `DashboardFolder` will be added. If there are existing duplicate values, this will fail. + - A unique constraint covering the columns `[id,ownerId]` on the table `Typebot` will be added. If there are existing duplicate values, this will fail. + +*/ +-- CreateIndex +CREATE UNIQUE INDEX "Coupon_code_key" ON "Coupon"("code"); + +-- CreateIndex +CREATE UNIQUE INDEX "DashboardFolder_id_ownerId_key" ON "DashboardFolder"("id", "ownerId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Typebot_id_ownerId_key" ON "Typebot"("id", "ownerId"); diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index 0dd72264a..0aab3dfda 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -96,6 +96,7 @@ model DashboardFolder { parentFolder DashboardFolder? @relation("ParentChild", fields: [parentFolderId], references: [id]) childrenFolder DashboardFolder[] @relation("ParentChild") typebots Typebot[] + @@unique([id, ownerId]) } model Typebot { @@ -117,6 +118,7 @@ model Typebot { settings Json publicId String? @unique customDomain String? @unique + @@unique([id, ownerId]) } model PublicTypebot { @@ -157,6 +159,6 @@ model Answer { model Coupon { userPropertiesToUpdate Json - code String @id + code String @id @unique dateRedeemed DateTime? }