From 8aca1eaac42bb1ed60d0eb6294ef8701bd054931 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:11:14 +0000 Subject: [PATCH] fix: add file size limit validation --- .../components/general/ImageCropper.vue | 41 +++++++++++++------ .../general/WorkspaceIconSelector.vue | 1 + .../src/services/attachments.service.ts | 4 ++ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/packages/nc-gui/components/general/ImageCropper.vue b/packages/nc-gui/components/general/ImageCropper.vue index 4eacd21852..45023a2642 100644 --- a/packages/nc-gui/components/general/ImageCropper.vue +++ b/packages/nc-gui/components/general/ImageCropper.vue @@ -15,6 +15,8 @@ interface Props { uploadConfig?: { path?: string scope?: PublicAttachmentScope + // filesize in bytes + maxFileSize?: number } showCropper: boolean } @@ -38,12 +40,21 @@ const previewImage = ref({ src: '', }) +const fileSize = ref(0) + +const isValidFileSize = computed(() => { + return !!(fileSize.value && fileSize.value * 1.33 <= (uploadConfig?.maxFileSize || 3 * 1024 * 1024)) +}) + const handleCropImage = () => { const { canvas } = cropperRef.value.getResult() previewImage.value = { canvas, src: canvas.toDataURL(imageConfig.type), } + ;(canvas as any).toBlob((blob: Blob) => { + fileSize.value = blob.size + }, imageConfig.type) } const handleUploadImage = async (fileToUpload: AttachmentReqType[]) => { @@ -77,18 +88,16 @@ const handleUploadImage = async (fileToUpload: AttachmentReqType[]) => { const handleSaveImage = async () => { if (previewImage.value.canvas) { - ;(previewImage.value.canvas as any).toBlob(async (blob: Blob) => { - await handleUploadImage([ - { - title: imageConfig.name, - fileName: imageConfig.name, - mimetype: imageConfig.type, - size: blob.size, - url: previewImage.value.src, - data: previewImage.value.src, - }, - ]) - }, imageConfig.type) + await handleUploadImage([ + { + title: imageConfig.name, + fileName: imageConfig.name, + mimetype: imageConfig.type, + size: fileSize.value, + url: previewImage.value.src, + data: previewImage.value.src, + }, + ]) } } @@ -139,7 +148,13 @@ watch(showCropper, () => { Crop - Save + + + + + Save + + diff --git a/packages/nc-gui/components/general/WorkspaceIconSelector.vue b/packages/nc-gui/components/general/WorkspaceIconSelector.vue index 589dcca27e..ff1490f50c 100644 --- a/packages/nc-gui/components/general/WorkspaceIconSelector.vue +++ b/packages/nc-gui/components/general/WorkspaceIconSelector.vue @@ -106,6 +106,7 @@ const imageCropperData = ref({ uploadConfig: { path: [NOCO, 'workspace', currentWorkspace.value?.id, 'icon'].join('/'), scope: PublicAttachmentScope.WORKSPACEPICS, + maxFileSize: 2 * 1024 * 1024 }, }) diff --git a/packages/nocodb/src/services/attachments.service.ts b/packages/nocodb/src/services/attachments.service.ts index 69048969a4..a12b236180 100644 --- a/packages/nocodb/src/services/attachments.service.ts +++ b/packages/nocodb/src/services/attachments.service.ts @@ -289,6 +289,10 @@ export class AttachmentsService { size = response.headers['content-length']; finalUrl = response.request.res.responseUrl; } else { + if (urlMeta.size && urlMeta.size * 1.33 > 3 * 1024 * 1024) { + NcError.badRequest('Base64 data URL is too large'); + } + const matches = url.match(/^data:(.+);base64,(.+)$/); if (!matches) throw new Error('Invalid data URL format.');