Browse Source

fix(gui): validate attachment value

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/4514/head
Pranav C 2 years ago
parent
commit
8b0a93c1f9
  1. 19
      packages/nc-gui/composables/useMultiSelect/convertCellData.ts
  2. 94
      packages/nc-gui/composables/useMultiSelect/index.ts
  3. 2
      packages/nc-gui/lang/en.json

19
packages/nc-gui/composables/useMultiSelect/convertCellData.ts

@ -1,9 +1,8 @@
import { UITypes } from 'nocodb-sdk' import { UITypes } from 'nocodb-sdk'
export default export default function convertCellData(args: { from: UITypes; to: UITypes; value: any }) {
function convertCellData(args: { from: UITypes; to: UITypes; value: any }) {
const { from, to, value } = args const { from, to, value } = args
if (from === to) { if (from === to && from !== UITypes.Attachment) {
return value return value
} }
@ -14,16 +13,24 @@ function convertCellData(args: { from: UITypes; to: UITypes; value: any }) {
return Boolean(value) return Boolean(value)
case UITypes.Date: case UITypes.Date:
return new Date(value) return new Date(value)
case UITypes.Attachment: case UITypes.Attachment: {
let parsedVal;
try { 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) { } 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.LinkToAnotherRecord:
case UITypes.Lookup: case UITypes.Lookup:
case UITypes.Rollup: case UITypes.Rollup:
case UITypes.Formula: case UITypes.Formula:
case UITypes.QrCode:
throw new Error(`Unsupported conversion from ${from} to ${to}`) throw new Error(`Unsupported conversion from ${from} to ${to}`)
default: default:
return value return value

94
packages/nc-gui/composables/useMultiSelect/index.ts

@ -5,7 +5,7 @@ import type { Cell } from './cellRange'
import { CellRange } from './cellRange' import { CellRange } from './cellRange'
import convertCellData from '~/composables/useMultiSelect/convertCellData' import convertCellData from '~/composables/useMultiSelect/convertCellData'
import { useMetas } from '~/composables/useMetas' 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 { copyTable, message, reactive, ref, unref, useCopy, useEventListener, useI18n } from '#imports'
import type { Row } from '~/lib' import type { Row } from '~/lib'
@ -245,52 +245,58 @@ export function useMultiSelect(
await copyValue() await copyValue()
break break
case 86: case 86:
// handle belongs to column try {
if ( // handle belongs to column
columnObj.uidt === UITypes.LinkToAnotherRecord && if (
(columnObj.colOptions as LinkToAnotherRecordType)?.type === RelationTypes.BELONGS_TO columnObj.uidt === UITypes.LinkToAnotherRecord &&
) { (columnObj.colOptions as LinkToAnotherRecordType)?.type === RelationTypes.BELONGS_TO
if (!clipboardContext.value || typeof clipboardContext.value !== 'object') { ) {
return message.info('Invalid data') 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({ // if it's a virtual column excluding belongs to cell type skip paste
value: clipboardContext.value, if (isVirtualCol(columnObj)) {
from: clipboardContext.uidt, return message.info(t('msg.info.notSupported'))
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'))
}
// const clipboardText = await getClipboardData() // const clipboardText = await getClipboardData()
if (clipboardContext) { if (clipboardContext) {
rowObj.row[columnObj.title!] = convertCellData({ rowObj.row[columnObj.title!] = convertCellData({
value: clipboardContext.value, value: clipboardContext.value,
from: clipboardContext.uidt, from: clipboardContext.uidt,
to: columnObj.uidt as UITypes, to: columnObj.uidt as UITypes,
}) })
e.preventDefault() e.preventDefault()
// makeEditable(rowObj, columnObj) // makeEditable(rowObj, columnObj)
syncCellData?.(selectedCell) syncCellData?.(selectedCell)
} else { } else {
clearCell(selectedCell as { row: number; col: number }, true) clearCell(selectedCell as { row: number; col: number }, true)
makeEditable(rowObj, columnObj) makeEditable(rowObj, columnObj)
}
} catch (error) {
message.error(await extractSdkResponseErrorMsg(error))
} }
} }
} }

2
packages/nc-gui/lang/en.json

@ -497,7 +497,7 @@
} }
}, },
"info": { "info": {
"cannotPasteHere": "Cannot paste here", "notSupported": "Not supported",
"roles": { "roles": {
"orgCreator": "Creator can create new projects and access any invited project.", "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." "orgViewer": "Viewer is not allowed to create new projects but they can access any invited project."

Loading…
Cancel
Save