Skip to content

Commit

Permalink
🧑‍💻 (s3) Correctly delete the files when deleting resources
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Sep 2, 2024
1 parent f537052 commit 041b817
Show file tree
Hide file tree
Showing 16 changed files with 224 additions and 205 deletions.
7 changes: 5 additions & 2 deletions apps/builder/src/features/results/api/deleteResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const deleteResults = authenticatedProcedure
groups: true,
workspace: {
select: {
id: true,
isSuspended: true,
isPastDue: true,
members: {
Expand All @@ -65,8 +66,10 @@ export const deleteResults = authenticatedProcedure
throw new TRPCError({ code: 'NOT_FOUND', message: 'Typebot not found' })
const { success } = await archiveResults(prisma)({
typebot: {
groups: typebot.groups,
} as Pick<Typebot, 'groups'>,
id: typebotId,
workspaceId: typebot.workspace.id,
groups: typebot.groups as Typebot['groups'],
},
resultsFilter: {
id: (idsArray?.length ?? 0) > 0 ? { in: idsArray } : undefined,
typebotId,
Expand Down
12 changes: 10 additions & 2 deletions apps/builder/src/features/typebot/api/deleteTypebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Typebot } from '@typebot.io/schemas'
import { z } from 'zod'
import { isWriteTypebotForbidden } from '../helpers/isWriteTypebotForbidden'
import { archiveResults } from '@typebot.io/results/archiveResults'
import { removeObjectsFromTypebot } from '@typebot.io/lib/s3/removeObjectsRecursively'

export const deleteTypebot = authenticatedProcedure
.meta({
Expand Down Expand Up @@ -40,6 +41,7 @@ export const deleteTypebot = authenticatedProcedure
groups: true,
workspace: {
select: {
id: true,
isSuspended: true,
isPastDue: true,
members: {
Expand All @@ -66,8 +68,10 @@ export const deleteTypebot = authenticatedProcedure

const { success } = await archiveResults(prisma)({
typebot: {
groups: existingTypebot.groups,
} as Pick<Typebot, 'groups'>,
id: typebotId,
workspaceId: existingTypebot.workspace.id,
groups: existingTypebot.groups as Typebot['groups'],
},
resultsFilter: { typebotId },
})
if (!success)
Expand All @@ -82,6 +86,10 @@ export const deleteTypebot = authenticatedProcedure
where: { id: typebotId },
data: { isArchived: true, publicId: null, customDomain: null },
})
await removeObjectsFromTypebot({
workspaceId: existingTypebot.workspace.id,
typebotId,
})
return {
message: 'success',
}
Expand Down
3 changes: 3 additions & 0 deletions apps/builder/src/features/workspace/api/deleteWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TRPCError } from '@trpc/server'
import { isNotEmpty } from '@typebot.io/lib/utils'
import Stripe from 'stripe'
import { env } from '@typebot.io/env'
import { removeObjectsFromWorkspace } from '@typebot.io/lib/s3/removeObjectsRecursively'

export const deleteWorkspace = authenticatedProcedure
.meta({
Expand Down Expand Up @@ -44,6 +45,8 @@ export const deleteWorkspace = authenticatedProcedure
where: { id: workspaceId },
})

await removeObjectsFromWorkspace(workspaceId)

if (isNotEmpty(workspace.stripeId) && env.STRIPE_SECRET_KEY) {
const stripe = new Stripe(env.STRIPE_SECRET_KEY, {
apiVersion: '2022-11-15',
Expand Down
118 changes: 58 additions & 60 deletions apps/viewer/src/test/assets/typebots/fileUpload.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
{
"id": "cl45ojo7z01383q1av699t0qj",
"createdAt": "2022-06-08T14:22:14.879Z",
"updatedAt": "2022-06-08T16:19:32.893Z",
"icon": null,
"version": "6",
"id": "cm0kr4xle00014e0mrmqvyp1x",
"name": "My typebot",
"folderId": null,
"groups": [
"events": [
{
"id": "cl45ojo7y00013q1aaysi2o6i",
"blocks": [
{
"id": "cl45ojo7y00023q1aavrwd411",
"type": "start",
"label": "Start",
"groupId": "cl45ojo7y00013q1aaysi2o6i",
"outgoingEdgeId": "cl45ojxvc00082e6gw1xqnxpp"
}
],
"title": "Start",
"graphCoordinates": { "x": 0, "y": 0 }
},
"outgoingEdgeId": "cl45ojxvc00082e6gw1xqnxpp",
"graphCoordinates": { "x": 0, "y": 0 },
"type": "start"
}
],
"groups": [
{
"id": "cl45ojrrd00062e6g17tuu9t0",
"title": "Group #1",
"graphCoordinates": { "x": 416, "y": 98 },
"blocks": [
{
"id": "cl45ojrre00072e6gk91592pj",
"type": "text",
"groupId": "cl45ojrrd00062e6g17tuu9t0",
"content": {
"richText": [
{
Expand All @@ -38,89 +30,95 @@
},
{
"id": "cl45ojzs300092e6gkno525c4",
"outgoingEdgeId": "cl45okfgz000d2e6g7z3wnqgq",
"type": "file input",
"groupId": "cl45ojrrd00062e6g17tuu9t0",
"options": {
"labels": {
"button": "Upload",
"placeholder": "<strong>\n Click to upload\n </strong> or drag and drop<br>\n (size limit: 10MB)"
},
"variableId": "vcl45ok77i000a2e6g79ye53a2",
"isMultipleAllowed": true
},
"outgoingEdgeId": "cl45okfgz000d2e6g7z3wnqgq"
"isMultipleAllowed": true,
"labels": {
"placeholder": "<strong>\n Click to upload\n </strong> or drag and drop<br>\n (size limit: 10MB)",
"button": "Upload"
}
}
}
],
"title": "Group #1",
"graphCoordinates": { "x": 416, "y": 98 }
]
},
{
"id": "cl45ok963000b2e6g2ky0wkvx",
"title": "Group #2",
"graphCoordinates": { "x": 863, "y": 249 },
"blocks": [
{
"id": "cl45ok963000c2e6g9snvbhw4",
"type": "text",
"groupId": "cl45ok963000b2e6g2ky0wkvx",
"content": {
"richText": [
{ "type": "p", "children": [{ "text": "Thank you!" }] }
]
}
}
],
"title": "Group #2",
"graphCoordinates": { "x": 863, "y": 249 }
]
}
],
"variables": [{ "id": "vcl45ok77i000a2e6g79ye53a2", "name": "Files" }],
"edges": [
{
"id": "cl45ojxvc00082e6gw1xqnxpp",
"to": { "groupId": "cl45ojrrd00062e6g17tuu9t0" },
"from": {
"blockId": "cl45ojo7y00023q1aavrwd411",
"groupId": "cl45ojo7y00013q1aaysi2o6i"
}
"from": { "eventId": "cl45ojo7y00013q1aaysi2o6i" },
"to": { "groupId": "cl45ojrrd00062e6g17tuu9t0" }
},
{
"id": "cl45okfgz000d2e6g7z3wnqgq",
"to": { "groupId": "cl45ok963000b2e6g2ky0wkvx" },
"from": {
"blockId": "cl45ojzs300092e6gkno525c4",
"groupId": "cl45ojrrd00062e6g17tuu9t0"
}
"from": { "blockId": "cl45ojzs300092e6gkno525c4" },
"to": { "groupId": "cl45ok963000b2e6g2ky0wkvx" }
}
],
"variables": [
{
"id": "vcl45ok77i000a2e6g79ye53a2",
"name": "Files",
"isSessionVariable": false
}
],
"theme": {
"general": { "font": "Open Sans", "background": { "type": "None" } },
"chat": {
"hostAvatar": {
"isEnabled": true,
"url": "https://avatars.githubusercontent.com/u/16015833?v=4"
},
"hostBubbles": { "backgroundColor": "#F7F8FF", "color": "#303235" },
"guestBubbles": { "backgroundColor": "#FF8E21", "color": "#FFFFFF" },
"buttons": { "backgroundColor": "#0042DA", "color": "#FFFFFF" },
"inputs": {
"color": "#303235",
"backgroundColor": "#FFFFFF",
"color": "#303235",
"placeholderColor": "#9095A0"
},
"buttons": { "color": "#FFFFFF", "backgroundColor": "#0042DA" },
"hostAvatar": {
"url": "https://avatars.githubusercontent.com/u/16015833?v=4",
"isEnabled": true
},
"hostBubbles": { "color": "#303235", "backgroundColor": "#F7F8FF" },
"guestBubbles": { "color": "#FFFFFF", "backgroundColor": "#FF8E21" }
},
"general": { "font": "Open Sans", "background": { "type": "None" } }
}
}
},
"selectedThemeTemplateId": null,
"settings": {
"general": {
"isBrandingEnabled": true,
"isInputPrefillEnabled": true,
"isHideQueryParamsEnabled": true,
"isNewResultOnRefreshEnabled": false
},
"typingEmulation": { "enabled": true, "speed": 300, "maxDelay": 1.5 },
"metadata": {
"description": "Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form."
},
"typingEmulation": { "speed": 300, "enabled": true, "maxDelay": 1.5 }
}
},
"publicId": "my-typebot-699t0qj",
"createdAt": "2024-09-02T08:41:53.426Z",
"updatedAt": "2024-09-02T08:41:53.426Z",
"icon": null,
"folderId": null,
"publicId": null,
"customDomain": null,
"workspaceId": "proWorkspace"
"workspaceId": "proWorkspace",
"resultsTablePreferences": null,
"isArchived": false,
"isClosed": false,
"whatsAppCredentialsId": null,
"riskLevel": null
}
6 changes: 3 additions & 3 deletions apps/viewer/src/test/fileUpload.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ test('should work as expected', async ({ page, browser }) => {
getTestAsset('typebots/fileUpload.json'),
getTestAsset('typebots/hugeGroup.json'),
])
await expect(page.locator(`text="3"`)).toBeVisible()
await page.locator('text="Upload 3 files"').click()
await expect(page.locator(`text="3 files uploaded"`)).toBeVisible()
await page.goto(`${env.NEXTAUTH_URL}/typebots/${typebotId}/results`)
Expand Down Expand Up @@ -68,6 +67,7 @@ test('should work as expected', async ({ page, browser }) => {
page.getByRole('button', { name: 'Delete' }).click()
await page.locator('button >> text="Delete"').click()
await expect(page.locator('text="api.json"')).toBeHidden()
await page2.goto(urls[0])
await expect(page2.locator('pre')).toBeHidden()
const page3 = await browser.newPage()
await page3.goto(urls[0])
await expect(page3.locator('pre')).toBeHidden()
})
43 changes: 0 additions & 43 deletions packages/lib/s3/deleteFilesFromBucket.ts

This file was deleted.

17 changes: 3 additions & 14 deletions packages/lib/s3/generatePresignedPostPolicy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { env } from '@typebot.io/env'
import { Client, PostPolicyResult } from 'minio'
import { PostPolicyResult } from 'minio'
import { initClient } from './initClient'

type Props = {
filePath: string
Expand All @@ -14,19 +15,7 @@ export const generatePresignedPostPolicy = async ({
fileType,
maxFileSize,
}: Props): Promise<PostPolicyResult> => {
if (!env.S3_ENDPOINT || !env.S3_ACCESS_KEY || !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 minioClient = new Client({
endPoint: env.S3_ENDPOINT,
port: env.S3_PORT,
useSSL: env.S3_SSL,
accessKey: env.S3_ACCESS_KEY,
secretKey: env.S3_SECRET_KEY,
region: env.S3_REGION,
})
const minioClient = initClient()

const postPolicy = minioClient.newPostPolicy()
if (maxFileSize)
Expand Down
17 changes: 2 additions & 15 deletions packages/lib/s3/getFileTempUrl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { env } from '@typebot.io/env'
import { Client } from 'minio'
import { initClient } from './initClient'

type Props = {
key: string
Expand All @@ -9,19 +9,6 @@ export const getFileTempUrl = async ({
key,
expires,
}: Props): Promise<string> => {
if (!env.S3_ENDPOINT || !env.S3_ACCESS_KEY || !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 minioClient = new Client({
endPoint: env.S3_ENDPOINT,
port: env.S3_PORT,
useSSL: env.S3_SSL,
accessKey: env.S3_ACCESS_KEY,
secretKey: env.S3_SECRET_KEY,
region: env.S3_REGION,
})

const minioClient = initClient()
return minioClient.presignedGetObject(env.S3_BUCKET, key, expires ?? 3600)
}
Loading

0 comments on commit 041b817

Please sign in to comment.