From 8b0a93c1f925abeef07771e5d4fcf04c3c660608 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 30 Nov 2022 12:53:48 +0530 Subject: [PATCH] fix(gui): validate attachment value Signed-off-by: Pranav C --- .../useMultiSelect/convertCellData.ts | 19 ++-- .../composables/useMultiSelect/index.ts | 94 ++++++++++--------- packages/nc-gui/lang/en.json | 2 +- 3 files changed, 64 insertions(+), 51 deletions(-) diff --git a/packages/nc-gui/composables/useMultiSelect/convertCellData.ts b/packages/nc-gui/composables/useMultiSelect/convertCellData.ts index 47c81656e9..4f354b13cd 100644 --- a/packages/nc-gui/composables/useMultiSelect/convertCellData.ts +++ b/packages/nc-gui/composables/useMultiSelect/convertCellData.ts @@ -1,9 +1,8 @@ import { UITypes } from 'nocodb-sdk' -export default -function convertCellData(args: { from: UITypes; to: UITypes; value: any }) { +export default function convertCellData(args: { from: UITypes; to: UITypes; value: any }) { const { from, to, value } = args - if (from === to) { + if (from === to && from !== UITypes.Attachment) { return value } @@ -14,16 +13,24 @@ function convertCellData(args: { from: UITypes; to: UITypes; value: any }) { return Boolean(value) case UITypes.Date: return new Date(value) - case UITypes.Attachment: + case UITypes.Attachment: { + let parsedVal; try { - return typeof value === 'string' ? JSON.parse(value) : value + parsedVal = typeof value === 'string' ? JSON.parse(value) : value + parsedVal = Array.isArray(parsedVal) ? parsedVal : [parsedVal] } catch (e) { - return [] + throw new Error('Invalid attachment data') } + if (parsedVal.some((v: any) => v && !(v.url || v.data))) { + throw new Error('Invalid attachment data') + } + return JSON.stringify(parsedVal) + } case UITypes.LinkToAnotherRecord: case UITypes.Lookup: case UITypes.Rollup: case UITypes.Formula: + case UITypes.QrCode: throw new Error(`Unsupported conversion from ${from} to ${to}`) default: return value diff --git a/packages/nc-gui/composables/useMultiSelect/index.ts b/packages/nc-gui/composables/useMultiSelect/index.ts index 58fafe78a6..e5eccad6f1 100644 --- a/packages/nc-gui/composables/useMultiSelect/index.ts +++ b/packages/nc-gui/composables/useMultiSelect/index.ts @@ -5,7 +5,7 @@ import type { Cell } from './cellRange' import { CellRange } from './cellRange' import convertCellData from '~/composables/useMultiSelect/convertCellData' import { useMetas } from '~/composables/useMetas' -import { extractPkFromRow } from '~/utils' +import { extractPkFromRow, extractSdkResponseErrorMsg } from '~/utils' import { copyTable, message, reactive, ref, unref, useCopy, useEventListener, useI18n } from '#imports' import type { Row } from '~/lib' @@ -245,52 +245,58 @@ export function useMultiSelect( await copyValue() break case 86: - // handle belongs to column - if ( - columnObj.uidt === UITypes.LinkToAnotherRecord && - (columnObj.colOptions as LinkToAnotherRecordType)?.type === RelationTypes.BELONGS_TO - ) { - if (!clipboardContext.value || typeof clipboardContext.value !== 'object') { - return message.info('Invalid data') + try { + // handle belongs to column + if ( + columnObj.uidt === UITypes.LinkToAnotherRecord && + (columnObj.colOptions as LinkToAnotherRecordType)?.type === RelationTypes.BELONGS_TO + ) { + if (!clipboardContext.value || typeof clipboardContext.value !== 'object') { + return message.info('Invalid data') + } + rowObj.row[columnObj.title!] = convertCellData({ + value: clipboardContext.value, + from: clipboardContext.uidt, + to: columnObj.uidt as UITypes, + }) + e.preventDefault() + + const foreignKeyColumn: ColumnType = meta.value?.columns.find( + (column: ColumnType) => column.id === (columnObj.colOptions as LinkToAnotherRecordType)?.fk_child_column_id, + ) + + const relatedTableMeta = await getMeta((columnObj.colOptions as LinkToAnotherRecordType).fk_related_model_id!) + + rowObj.row[foreignKeyColumn.title!] = extractPkFromRow( + clipboardContext.value, + (relatedTableMeta as any)!.columns!, + ) + + // makeEditable(rowObj, columnObj) + return await syncCellData?.({ ...selectedCell, updatedColumnTitle: foreignKeyColumn.title }) } - rowObj.row[columnObj.title!] = convertCellData({ - value: clipboardContext.value, - from: clipboardContext.uidt, - to: columnObj.uidt as UITypes, - }) - e.preventDefault() - - const foreignKeyColumn: ColumnType = meta.value?.columns.find( - (c) => c.id === (columnObj.colOptions as LinkToAnotherRecordType)?.fk_child_column_id, - ) - - const relatedTableMeta = await getMeta((columnObj.colOptions as LinkToAnotherRecordType)?.fk_related_model_id!) - - rowObj.row[foreignKeyColumn.title!] = extractPkFromRow(clipboardContext.value, relatedTableMeta!.columns!) - - // makeEditable(rowObj, columnObj) - return syncCellData?.({ ...selectedCell, updatedColumnTitle: foreignKeyColumn.title }) - } - - // if it's a virtual column excluding belongs to cell type skip paste - if (isVirtualCol(columnObj)) { - return message.info(t('msg.info.cannotPasteHere')) - } + // if it's a virtual column excluding belongs to cell type skip paste + if (isVirtualCol(columnObj)) { + return message.info(t('msg.info.notSupported')) + } - // const clipboardText = await getClipboardData() - if (clipboardContext) { - rowObj.row[columnObj.title!] = convertCellData({ - value: clipboardContext.value, - from: clipboardContext.uidt, - to: columnObj.uidt as UITypes, - }) - e.preventDefault() - // makeEditable(rowObj, columnObj) - syncCellData?.(selectedCell) - } else { - clearCell(selectedCell as { row: number; col: number }, true) - makeEditable(rowObj, columnObj) + // const clipboardText = await getClipboardData() + if (clipboardContext) { + rowObj.row[columnObj.title!] = convertCellData({ + value: clipboardContext.value, + from: clipboardContext.uidt, + to: columnObj.uidt as UITypes, + }) + e.preventDefault() + // makeEditable(rowObj, columnObj) + syncCellData?.(selectedCell) + } else { + clearCell(selectedCell as { row: number; col: number }, true) + makeEditable(rowObj, columnObj) + } + } catch (error) { + message.error(await extractSdkResponseErrorMsg(error)) } } } diff --git a/packages/nc-gui/lang/en.json b/packages/nc-gui/lang/en.json index 579789c6ec..28aa99e572 100644 --- a/packages/nc-gui/lang/en.json +++ b/packages/nc-gui/lang/en.json @@ -497,7 +497,7 @@ } }, "info": { - "cannotPasteHere": "Cannot paste here", + "notSupported": "Not supported", "roles": { "orgCreator": "Creator can create new projects and access any invited project.", "orgViewer": "Viewer is not allowed to create new projects but they can access any invited project."