Skip to content

Commit

Permalink
🐛 (editor) Fix typebot update permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Feb 13, 2023
1 parent 8a02c70 commit bac97a8
Showing 1 changed file with 86 additions and 24 deletions.
110 changes: 86 additions & 24 deletions apps/builder/src/pages/api/typebots/[typebotId].ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { CollaborationType, Prisma } from 'db'
import { CollaborationType, CollaboratorsOnTypebots, Prisma, User } from 'db'
import prisma from '@/lib/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
import { canReadTypebots, canWriteTypebots } from '@/utils/api/dbRules'
import { methodNotAllowed, notAuthenticated } from 'utils/api'
import { getAuthenticatedUser } from '@/features/auth/api'
import { archiveResults } from '@/features/results/api'
import { typebotSchema } from 'models'
import { Typebot, typebotSchema } from 'models'
import { captureEvent } from '@sentry/nextjs'
import { omit } from 'utils'
import { isDefined, omit } from 'utils'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const user = await getAuthenticatedUser(req)
Expand All @@ -26,15 +25,8 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
webhooks: true,
},
})
if (!typebot) return res.send({ typebot: null })
const memberInWorkspace = await prisma.memberInWorkspace.findFirst({
where: {
workspaceId: typebot.workspaceId,
userId: user.id,
},
})
if (process.env.ADMIN_EMAIL !== user.email && !memberInWorkspace)
return res.send({ typebot: null })
if (!typebot || !(await canReadTypebots(typebot, user)))
return res.status(404).send({ typebot: null })

const { publishedTypebot, collaborators, webhooks, ...restOfTypebot } =
typebot
Expand All @@ -50,21 +42,31 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
}

if (req.method === 'DELETE') {
const typebot = await prisma.typebot.findFirst({
where: { id: typebotId },
select: {
workspaceId: true,
collaborators: { select: { userId: true, type: true } },
},
})
if (!typebot || !(await canWriteTypebots(typebot, user)))
return res.status(404).send({ typebot: null })
const { success } = await archiveResults({
typebotId,
user,
resultsFilter: { typebotId },
})
if (!success) return res.status(500).send({ success: false })
await prisma.publicTypebot.deleteMany({
where: { typebot: canWriteTypebots(typebotId, user) },
where: { typebotId },
})
const typebots = await prisma.typebot.updateMany({
where: canWriteTypebots(typebotId, user),
where: { id: typebotId },
data: { isArchived: true, publicId: null },
})
return res.send({ typebots })
}

if (req.method === 'PUT') {
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const parser = typebotSchema.safeParse({
Expand All @@ -81,17 +83,22 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
},
})
}
const existingTypebot = await prisma.typebot.findFirst({
where: canReadTypebots(typebotId, user),
select: { updatedAt: true },

const typebot = await prisma.typebot.findFirst({
where: { id: typebotId },
select: {
updatedAt: true,
workspaceId: true,
collaborators: { select: { userId: true, type: true } },
},
})
if (
existingTypebot &&
existingTypebot?.updatedAt > new Date(data.updatedAt)
)
if (!typebot || !(await canWriteTypebots(typebot, user)))
return res.status(404).send({ message: 'Typebot not found' })

if (typebot.updatedAt > new Date(data.updatedAt))
return res.send({ message: 'Found newer version of typebot in database' })
const typebots = await prisma.typebot.updateMany({
where: canWriteTypebots(typebotId, user),
where: { id: typebotId },
data: removeOldProperties({
...data,
theme: data.theme ?? undefined,
Expand All @@ -101,17 +108,72 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
})
return res.send({ typebots })
}

if (req.method === 'PATCH') {
const typebot = await prisma.typebot.findFirst({
where: { id: typebotId },
select: {
updatedAt: true,
workspaceId: true,
collaborators: { select: { userId: true, type: true } },
},
})
if (!typebot || !(await canWriteTypebots(typebot, user)))
return res.status(404).send({ message: 'Typebot not found' })
const data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body
const typebots = await prisma.typebot.updateMany({
where: canWriteTypebots(typebotId, user),
where: { id: typebotId },
data,
})
return res.send({ typebots })
}
return methodNotAllowed(res)
}

const canReadTypebots = async (
typebot: Pick<Typebot, 'workspaceId'> & {
collaborators: Pick<CollaboratorsOnTypebots, 'userId' | 'type'>[]
},
user: Pick<User, 'email' | 'id'>
) => {
if (
process.env.ADMIN_EMAIL === user.email ||
typebot.collaborators.find(
(collaborator) => collaborator.userId === user.id
)
)
return true
const memberInWorkspace = await prisma.memberInWorkspace.findFirst({
where: {
workspaceId: typebot.workspaceId,
userId: user.id,
},
})
return isDefined(memberInWorkspace)
}

const canWriteTypebots = async (
typebot: Pick<Typebot, 'workspaceId'> & {
collaborators: Pick<CollaboratorsOnTypebots, 'userId' | 'type'>[]
},
user: Pick<User, 'email' | 'id'>
) => {
if (
process.env.ADMIN_EMAIL === user.email ||
typebot.collaborators.find(
(collaborator) => collaborator.userId === user.id
)?.type === CollaborationType.WRITE
)
return true
const memberInWorkspace = await prisma.memberInWorkspace.findFirst({
where: {
workspaceId: typebot.workspaceId,
userId: user.id,
},
})
return memberInWorkspace && memberInWorkspace?.role !== 'GUEST'
}

// TODO: Remove in a month
const removeOldProperties = (data: unknown) => {
if (data && typeof data === 'object' && 'publishedTypebotId' in data) {
Expand Down

4 comments on commit bac97a8

@vercel
Copy link

@vercel vercel bot commented on bac97a8 Feb 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-typebot-io.vercel.app
builder-v2-git-main-typebot-io.vercel.app
app.typebot.io

@vercel
Copy link

@vercel vercel bot commented on bac97a8 Feb 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2 – ./apps/viewer

ns8.vn
1stop.au
yobot.me
klujo.com
247987.com
8jours.top
aginap.com
bee.cr8.ai
bot.aws.bj
bot.bbc.bj
cat.cr8.ai
finplex.be
nepkit.com
pig.cr8.ai
sat.cr8.ai
bot.aipr.kr
bot.joof.it
bull.cr8.ai
docs.cr8.ai
minipost.uk
mole.cr8.ai
team.cr8.ai
wolf.cr8.ai
cinecorn.com
kusamint.com
rhino.cr8.ai
sheep.cr8.ai
snake.cr8.ai
svhm.mprs.in
tiger.cr8.ai
video.cr8.ai
yoda.riku.ai
zebra.cr8.ai
bergamo.store
bot.krdfy.com
bot.tvbeat.it
cgcassets.com
filmylogy.com
goldorayo.com
rabbit.cr8.ai
signup.cr8.ai
turkey.cr8.ai
vhpage.cr8.ai
vitamyway.com
am.nigerias.io
an.nigerias.io
app.yvon.earth
ar.nigerias.io
bot.enreso.org
bot.rslabs.pro
bots.bridge.ai
chat.hayuri.id
chicken.cr8.ai
gollum.riku.ai
gsbulletin.com
panther.cr7.ai
panther.cr8.ai
penguin.cr8.ai
talk.gocare.io
mainmenu1one.wpwakanda.com
tarian.theiofoundation.org
ted.meujalecobrasil.com.br
type.dericsoncalari.com.br
bot.pinpointinteractive.com
bot.polychromes-project.com
bot.seidinembroseanchetu.it
chatbot.berbelanjabiz.trade
designguide.techyscouts.com
liveconvert2.kandalearn.com
presente.empresarias.com.mx
sell.sellthemotorhome.co.uk
anamnese.odontopavani.com.br
austin.channelautomation.com
bot.marketingplusmindset.com
bot.seidibergamoseanchetu.it
desabafe.sergiolimajr.com.br
download.venturemarketing.in
piazzatorre.barrettamario.it
type.cookieacademyonline.com
bot.brigadeirosemdrama.com.br
forms.escoladeautomacao.com.br
onboarding.libertydreamcare.ie
type.talitasouzamarques.com.br
agendamento.sergiolimajr.com.br
anamnese.clinicamegasjdr.com.br
bookings.littlepartymonkeys.com
bot.comercializadoraomicron.com
elevateyourmind.groovepages.com
viewer-v2-typebot-io.vercel.app
yourfeedback.comebackreward.com
gerador.verificadordehospedes.com
personal-trainer.barrettamario.it
preagendamento.sergiolimajr.com.br
studiotecnicoimmobiliaremerelli.it
download.thailandmicespecialist.com
register.thailandmicespecialist.com
bot.studiotecnicoimmobiliaremerelli.it
pesquisa.escolamodacomproposito.com.br
anamnese.clinicaramosodontologia.com.br
viewer-v2-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on bac97a8 Feb 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

docs – ./apps/docs

docs-typebot-io.vercel.app
docs.typebot.io
docs-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on bac97a8 Feb 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.