2
0

fix(results): 🔒️ Improve delete security checks

This commit is contained in:
Baptiste Arnaud
2022-06-18 09:41:23 +02:00
parent 4e6217597c
commit 9352587298
6 changed files with 25 additions and 24 deletions

View File

@ -4,7 +4,6 @@ import { SubmissionsTable } from 'components/results/SubmissionsTable'
import React, { useCallback, useMemo, useState } from 'react'
import {
convertResultsToTableData,
deleteAllResults,
deleteResults,
getAllResults,
useResults,
@ -70,10 +69,11 @@ export const SubmissionsContent = ({
const selectedIds = (results ?? [])
.filter((_, idx) => selectedIndices.includes(idx))
.map((result) => result.id)
const { error } =
totalSelected === totalResults
? await deleteAllResults(typebotId)
: await deleteResults(typebotId, selectedIds)
const { error } = await deleteResults(
workspaceId,
typebotId,
totalSelected === totalResults ? [] : selectedIds
)
if (error) showToast({ description: error.message, title: error.name })
else {
mutate(

View File

@ -2,7 +2,7 @@ import { rest, setupWorker } from 'msw'
import { setupServer } from 'msw/node'
const handlers = () => [
rest.get('/api/auth/session', (req, res, ctx) => {
rest.get('http://localhost:3000/api/auth/session', (req, res, ctx) => {
const authenticatedUser = JSON.parse(
typeof localStorage !== 'undefined'
? (localStorage.getItem('authenticatedUser') as string)

View File

@ -15,13 +15,13 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const user = await getAuthenticatedUser(req)
if (!user) return notAuthenticated(res)
const workspaceId = req.query.workspaceId as string | undefined
if (!workspaceId) return badRequest(res, 'workspaceId is required')
const workspace = await prisma.workspace.findFirst({
where: { id: workspaceId, members: { some: { userId: user.id } } },
select: { plan: true },
})
if (!workspace) return forbidden(res)
if (req.method === 'GET') {
if (!workspaceId) return badRequest(res, 'workspaceId is required')
const workspace = await prisma.workspace.findFirst({
where: { id: workspaceId, members: { some: { userId: user.id } } },
select: { plan: true },
})
if (!workspace) return forbidden(res)
const typebotId = req.query.typebotId.toString()
const lastResultId = req.query.lastResultId?.toString()
const take = parseInt(req.query.limit?.toString())
@ -46,7 +46,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
return res.status(200).send({ results })
}
if (req.method === 'DELETE') {
const typebotId = req.query.typebotId.toString()
const typebotId = req.query.typebotId as string
const ids = req.query.ids as string[]
const results = await prisma.result.deleteMany({
where: {

View File

@ -57,10 +57,12 @@ test.describe('Results page', () => {
await deleteButtonInConfirmDialog(page).click()
await expect(page.locator('text=content199')).toBeHidden()
await expect(page.locator('text=content198')).toBeHidden()
await page.waitForTimeout(1000)
await page.click('[data-testid="checkbox"] >> nth=0')
await page.click('button:has-text("Delete198")')
await deleteButtonInConfirmDialog(page).click()
await expect(page.locator(':nth-match(tr, 2)')).toBeHidden()
await page.waitForTimeout(1000)
expect(await page.locator('tr').count()).toBe(1)
})
test('submissions table should have infinite scroll', async ({ page }) => {

View File

@ -76,10 +76,15 @@ export const useResults = ({
}
}
export const deleteResults = async (typebotId: string, ids: string[]) => {
export const deleteResults = async (
workspaceId: string,
typebotId: string,
ids: string[]
) => {
const params = stringify(
{
ids,
workspaceId,
},
{ indices: false }
)
@ -89,12 +94,6 @@ export const deleteResults = async (typebotId: string, ids: string[]) => {
})
}
export const deleteAllResults = async (typebotId: string) =>
sendRequest({
url: `/api/typebots/${typebotId}/results`,
method: 'DELETE',
})
export const getAllResults = async (workspaceId: string, typebotId: string) => {
const results = []
let hasMore = true

View File

@ -3604,9 +3604,9 @@
set-cookie-parser "^2.4.6"
"@mswjs/interceptors@^0.15.1":
version "0.15.1"
resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.15.1.tgz#4a0009f56e51bc2cd3176f1507065c7d2f6c0d5e"
integrity sha512-D5B+ZJNlfvBm6ZctAfRBdNJdCHYAe2Ix4My5qfbHV5WH+3lkt3mmsjiWJzEh5ZwGDauzY487TldI275If7DJVw==
version "0.15.3"
resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.15.3.tgz#bcd17b5d7558d4f598007a4bb383b42dc9264f8d"
integrity sha512-GJ1qzBq82EQ3bwhsvw5nScbrLzOSI5H/TyB2CGd1K7dDqX58DJDLJHexiN+S5Ucvl6/84FjRdIysz0RxE/L8MA==
dependencies:
"@open-draft/until" "^1.0.3"
"@xmldom/xmldom" "^0.7.5"