Merge pull request #15209 from Budibase/chore/guard-display-column-in-the-api
Guard display column in the api
This commit is contained in:
commit
bbd69ce318
|
@ -37,6 +37,7 @@ import { jsonFromCsvString } from "../../../utilities/csv"
|
|||
import { builderSocket } from "../../../websockets"
|
||||
import { cloneDeep } from "lodash"
|
||||
import {
|
||||
canBeDisplayColumn,
|
||||
helpers,
|
||||
PROTECTED_EXTERNAL_COLUMNS,
|
||||
PROTECTED_INTERNAL_COLUMNS,
|
||||
|
@ -67,6 +68,27 @@ function checkDefaultFields(table: Table) {
|
|||
}
|
||||
}
|
||||
|
||||
async function guardTable(table: Table, isCreate: boolean) {
|
||||
checkDefaultFields(table)
|
||||
|
||||
if (
|
||||
table.primaryDisplay &&
|
||||
!canBeDisplayColumn(table.schema[table.primaryDisplay]?.type)
|
||||
) {
|
||||
// Prevent throwing errors from existing badly configured tables. Only throw for new tables or if this setting is being updated
|
||||
if (
|
||||
isCreate ||
|
||||
(await sdk.tables.getTable(table._id!)).primaryDisplay !==
|
||||
table.primaryDisplay
|
||||
) {
|
||||
throw new HTTPError(
|
||||
`Column "${table.primaryDisplay}" cannot be used as a display type.`,
|
||||
400
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// covers both internal and external
|
||||
export async function fetch(ctx: UserCtx<void, FetchTablesResponse>) {
|
||||
const internal = await sdk.tables.getAllInternalTables()
|
||||
|
@ -111,7 +133,7 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
|
|||
|
||||
const isCreate = !table._id
|
||||
|
||||
checkDefaultFields(table)
|
||||
await guardTable(table, isCreate)
|
||||
|
||||
let savedTable: Table
|
||||
if (isCreate) {
|
||||
|
|
|
@ -3399,7 +3399,7 @@ if (descriptions.length) {
|
|||
type: FieldType.LINK,
|
||||
relationshipType: RelationshipType.MANY_TO_ONE,
|
||||
tableId: toRelateTableId,
|
||||
fieldName: "link",
|
||||
fieldName: "main",
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -3408,7 +3408,7 @@ if (descriptions.length) {
|
|||
)
|
||||
await config.api.table.save({
|
||||
...toRelateTable,
|
||||
primaryDisplay: "link",
|
||||
primaryDisplay: "name",
|
||||
})
|
||||
const relatedRows = await Promise.all([
|
||||
config.api.row.save(toRelateTable._id!, {
|
||||
|
|
|
@ -185,6 +185,62 @@ if (descriptions.length) {
|
|||
)
|
||||
}
|
||||
)
|
||||
|
||||
it("can set primary display", async () => {
|
||||
const columnName = generator.word()
|
||||
const table = await config.api.table.save(
|
||||
tableForDatasource(datasource, {
|
||||
primaryDisplay: columnName,
|
||||
schema: {
|
||||
[columnName]: {
|
||||
name: columnName,
|
||||
type: FieldType.STRING,
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
expect(table.primaryDisplay).toEqual(columnName)
|
||||
|
||||
const res = await config.api.table.get(table._id!)
|
||||
expect(res.primaryDisplay).toEqual(columnName)
|
||||
})
|
||||
|
||||
it("cannot use unexisting columns as primary display", async () => {
|
||||
const columnName = generator.word()
|
||||
await config.api.table.save(
|
||||
tableForDatasource(datasource, {
|
||||
primaryDisplay: columnName,
|
||||
}),
|
||||
{
|
||||
status: 400,
|
||||
body: {
|
||||
message: `Column "${columnName}" cannot be used as a display type.`,
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it("cannot use invalid column types as display name", async () => {
|
||||
const columnName = generator.word()
|
||||
|
||||
await config.api.table.save(
|
||||
tableForDatasource(datasource, {
|
||||
primaryDisplay: columnName,
|
||||
schema: {
|
||||
[columnName]: {
|
||||
name: columnName,
|
||||
type: FieldType.BOOLEAN,
|
||||
},
|
||||
},
|
||||
}),
|
||||
{
|
||||
status: 400,
|
||||
body: {
|
||||
message: `Column "${columnName}" cannot be used as a display type.`,
|
||||
},
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("permissions", () => {
|
||||
|
@ -603,6 +659,49 @@ if (descriptions.length) {
|
|||
}
|
||||
expect(response).toEqual(expectedResponse)
|
||||
})
|
||||
|
||||
it("cannot use unexisting columns as primary display", async () => {
|
||||
const table = await config.api.table.save(
|
||||
tableForDatasource(datasource)
|
||||
)
|
||||
|
||||
const columnName = generator.word()
|
||||
const tableRequest = {
|
||||
...table,
|
||||
primaryDisplay: columnName,
|
||||
}
|
||||
await config.api.table.save(tableRequest, {
|
||||
status: 400,
|
||||
body: {
|
||||
message: `Column "${columnName}" cannot be used as a display type.`,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("cannot use invalid column types as display name", async () => {
|
||||
const table = await config.api.table.save(
|
||||
tableForDatasource(datasource)
|
||||
)
|
||||
const columnName = generator.word()
|
||||
const tableRequest: SaveTableRequest = {
|
||||
...table,
|
||||
primaryDisplay: columnName,
|
||||
schema: {
|
||||
...table.schema,
|
||||
[columnName]: {
|
||||
name: columnName,
|
||||
type: FieldType.BOOLEAN,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
await config.api.table.save(tableRequest, {
|
||||
status: 400,
|
||||
body: {
|
||||
message: `Column "${columnName}" cannot be used as a display type.`,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("import", () => {
|
||||
|
|
|
@ -12,8 +12,8 @@ const allowDisplayColumnByType: Record<FieldType, boolean> = {
|
|||
[FieldType.AUTO]: true,
|
||||
[FieldType.INTERNAL]: true,
|
||||
[FieldType.BARCODEQR]: true,
|
||||
|
||||
[FieldType.BIGINT]: true,
|
||||
|
||||
[FieldType.BOOLEAN]: false,
|
||||
[FieldType.ARRAY]: false,
|
||||
[FieldType.ATTACHMENTS]: false,
|
||||
|
|
Loading…
Reference in New Issue