Browse Source

fix: block circular lookup creation

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5091/head
Pranav C 2 years ago
parent
commit
13dae9f90e
  1. 2
      packages/nc-gui/components/smartsheet/column/LookupOptions.vue
  2. 9
      packages/nocodb/src/lib/meta/api/columnApis.ts
  3. 23
      packages/nocodb/src/lib/meta/api/helpers/columnHelpers.ts

2
packages/nc-gui/components/smartsheet/column/LookupOptions.vue

@ -50,7 +50,7 @@ const columns = $computed<ColumnType[]>(() => {
if (!selectedTable?.id) {
return []
}
return metas[selectedTable.id].columns.filter((c: ColumnType) => !isSystemColumn(c))
return metas[selectedTable.id].columns.filter((c: ColumnType) => !isSystemColumn(c) && c.id !== vModel.value.id)
})
onMounted(() => {

9
packages/nocodb/src/lib/meta/api/columnApis.ts

@ -40,8 +40,8 @@ import { MetaTable } from '../../utils/globals';
import formulaQueryBuilderv2 from '../../db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2';
import {
createHmAndBtColumn,
validateRequiredField,
validateLookupPayload,
validateRequiredField,
validateRollupPayload,
} from './helpers';
@ -626,9 +626,12 @@ export async function columnSetAsPrimary(req: Request, res: Response) {
async function updateRollupOrLookup(colBody: any, column: Column<any>) {
if (
UITypes.Lookup === column.uidt &&
validateRequiredField(colBody, ['fk_lookup_column_id', 'fk_relation_column_id'])
validateRequiredField(colBody, [
'fk_lookup_column_id',
'fk_relation_column_id',
])
) {
await validateLookupPayload(colBody);
await validateLookupPayload(colBody, column.id);
await Column.update(column.id, colBody);
} else if (
UITypes.Rollup === column.uidt &&

23
packages/nocodb/src/lib/meta/api/helpers/columnHelpers.ts

@ -8,6 +8,7 @@ import {
} from 'nocodb-sdk';
import Column from '../../../models/Column';
import LinkToAnotherRecordColumn from '../../../models/LinkToAnotherRecordColumn';
import LookupColumn from '../../../models/LookupColumn';
import Model from '../../../models/Model';
import { getUniqueColumnAliasName } from '../../helpers/getUniqueName';
import validateParams from '../../helpers/validateParams';
@ -111,13 +112,33 @@ export async function validateRollupPayload(
}
export async function validateLookupPayload(
payload: ColumnReqType & { uidt: UITypes }
payload: ColumnReqType & { uidt: UITypes },
columnId?: string
) {
validateParams(
['title', 'fk_relation_column_id', 'fk_lookup_column_id'],
payload
);
// check for circular reference
if (columnId) {
let lkCol: LookupColumn | LookupColumnReqType =
payload as LookupColumnReqType;
while (lkCol) {
// check if lookup column is same as column itself
if (columnId === lkCol.fk_lookup_column_id)
throw new Error('Circular lookup reference not allowed');
lkCol = await Column.get({ colId: lkCol.fk_lookup_column_id }).then(
(c: Column) => {
if (c.uidt === 'Lookup') {
return c.getColOptions<LookupColumn>();
}
return null;
}
);
}
}
const relation = await (
await Column.get({
colId: (payload as LookupColumnReqType).fk_relation_column_id,

Loading…
Cancel
Save