diff --git a/apps/builder/pages/api/typebots/[typebotId]/results.ts b/apps/builder/pages/api/typebots/[typebotId]/results.ts index 37131ea99..93f93220d 100644 --- a/apps/builder/pages/api/typebots/[typebotId]/results.ts +++ b/apps/builder/pages/api/typebots/[typebotId]/results.ts @@ -1,7 +1,9 @@ import { withSentry } from '@sentry/nextjs' import prisma from 'libs/prisma' +import { InputBlockType, Typebot } from 'models' import { NextApiRequest, NextApiResponse } from 'next' import { canReadTypebot, canWriteTypebot } from 'services/api/dbRules' +import { deleteFiles } from 'services/api/storage' import { getAuthenticatedUser } from 'services/api/utils' import { isFreePlan } from 'services/workspace' import { @@ -49,13 +51,47 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { const typebotId = req.query.typebotId as string const data = req.body as { ids: string[] } const ids = data.ids - const results = await prisma.result.deleteMany({ + const resultsFilter = { + id: ids.length > 0 ? { in: ids } : undefined, + typebot: canWriteTypebot(typebotId, user), + } + // Weird bug waiting for https://github.com/aws/aws-sdk-js/issues/4137 + // const typebot = await prisma.typebot.findFirst({ + // where: canWriteTypebot(typebotId, user), + // select: { groups: true }, + // }) + // if (!typebot) return forbidden(res) + // const fileUploadBlockIds = (typebot as Typebot).groups + // .flatMap((g) => g.blocks) + // .filter((b) => b.type === InputBlockType.FILE) + // .map((b) => b.id) + // if (fileUploadBlockIds.length > 0) { + // const filesToDelete = await prisma.answer.findMany({ + // where: { result: resultsFilter, blockId: { in: fileUploadBlockIds } }, + // }) + // if (filesToDelete.length > 0) + // await deleteFiles({ + // urls: filesToDelete.flatMap((a) => a.content.split(', ')), + // }) + // } + await prisma.log.deleteMany({ where: { - id: ids.length > 0 ? { in: ids } : undefined, - typebot: canWriteTypebot(typebotId, user), + result: resultsFilter, }, }) - return res.status(200).send({ results }) + await prisma.answer.deleteMany({ + where: { + result: resultsFilter, + }, + }) + await prisma.result.updateMany({ + where: resultsFilter, + data: { + isArchived: true, + variables: [], + }, + }) + return res.status(200).send({ message: 'done' }) } return methodNotAllowed(res) } diff --git a/apps/builder/services/api/storage.ts b/apps/builder/services/api/storage.ts new file mode 100644 index 000000000..570db09f3 --- /dev/null +++ b/apps/builder/services/api/storage.ts @@ -0,0 +1,44 @@ +import { AWSError, config, Endpoint, S3 } from 'aws-sdk' +import { PromiseResult } from 'aws-sdk/lib/request' + +export const deleteFiles = async ({ + urls, +}: { + urls: string[] +}): Promise> => { + if ( + !process.env.S3_ENDPOINT || + !process.env.S3_ACCESS_KEY || + !process.env.S3_SECRET_KEY + ) + throw new Error( + 'S3 not properly configured. Missing one of those variables: S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY' + ) + + const sslEnabled = + process.env.S3_SSL && process.env.S3_SSL === 'false' ? false : true + config.update({ + accessKeyId: process.env.S3_ACCESS_KEY, + secretAccessKey: process.env.S3_SECRET_KEY, + region: process.env.S3_REGION, + sslEnabled, + }) + const protocol = sslEnabled ? 'https' : 'http' + const s3 = new S3({ + endpoint: new Endpoint( + `${protocol}://${process.env.S3_ENDPOINT}${ + process.env.S3_PORT ? `:${process.env.S3_PORT}` : '' + }` + ), + }) + + const Bucket = process.env.S3_BUCKET ?? 'typebot' + return s3 + .deleteObjects({ + Bucket, + Delete: { + Objects: urls.map((url) => ({ Key: url.split(`/${Bucket}/`)[1] })), + }, + }) + .promise() +} diff --git a/apps/viewer/playwright/tests/fileUpload.spec.ts b/apps/viewer/playwright/tests/fileUpload.spec.ts index b62d0e79b..284db9e63 100644 --- a/apps/viewer/playwright/tests/fileUpload.spec.ts +++ b/apps/viewer/playwright/tests/fileUpload.spec.ts @@ -5,8 +5,9 @@ import { parse } from 'papaparse' import { typebotViewer } from '../services/selectorUtils' import { importTypebotInDatabase } from '../services/database' import { readFileSync } from 'fs' +import { isDefined } from 'utils' -test('should work as expected', async ({ page, context }) => { +test('should work as expected', async ({ page, browser }) => { const typebotId = cuid() await importTypebotInDatabase( path.join(__dirname, '../fixtures/typebots/fileUpload.json'), @@ -34,9 +35,9 @@ test('should work as expected', async ({ page, context }) => { 'href', /.+\/fileUpload\.json/ ) - await expect(page.locator('text="api.json"')).toHaveAttribute( + await expect(page.locator('text="hugeGroup.json"')).toHaveAttribute( 'href', - /.+\/api\.json/ + /.+\/hugeGroup\.json/ ) await page.click('[data-testid="checkbox"] >> nth=0') @@ -50,4 +51,25 @@ test('should work as expected', async ({ page, context }) => { const { data } = parse(file) expect(data).toHaveLength(2) expect((data[1] as unknown[])[1]).toContain('http://localhost:9000') + + // Waiting for https://github.com/aws/aws-sdk-js/issues/4137 + // const urls = ( + // await Promise.all( + // [ + // page.locator('text="api.json"'), + // page.locator('text="fileUpload.json"'), + // page.locator('text="hugeGroup.json"'), + // ].map((elem) => elem.getAttribute('href')) + // ) + // ).filter(isDefined) + + // const page2 = await browser.newPage() + // await page2.goto(urls[0]) + // await expect(page2.locator('pre')).toBeVisible() + + // await page.locator('button >> text="Delete"').click() + // await page.locator('button >> text="Delete" >> nth=1').click() + // await expect(page.locator('text="api.json"')).toBeHidden() + // await page2.goto(urls[0]) + // await expect(page2.locator('text="grkwobnowrk')).toBeVisible() }) diff --git a/packages/db/prisma/migrations/20220624120243_add_is_archived_on_result/migration.sql b/packages/db/prisma/migrations/20220624120243_add_is_archived_on_result/migration.sql new file mode 100644 index 000000000..e74f9a4ac --- /dev/null +++ b/packages/db/prisma/migrations/20220624120243_add_is_archived_on_result/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Result" ADD COLUMN "isArchived" BOOLEAN; diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index fb113deb2..07a0555e8 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -232,6 +232,7 @@ model Result { variables Json[] isCompleted Boolean hasStarted Boolean? + isArchived Boolean? logs Log[] }