diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 7b3619351a..8069fadf10 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -873,6 +873,27 @@ describe.each([ expect(row.one).toBeUndefined() expect(row.two).toEqual("bar") }) + + it("can't persist readonly columns", async () => { + mocks.licenses.useViewReadonlyColumns() + const view = await config.api.viewV2.create({ + tableId: table._id!, + name: generator.guid(), + schema: { + one: { visible: true, readonly: true }, + two: { visible: true }, + }, + }) + const row = await config.api.row.save(view.id, { + tableId: table!._id, + _viewId: view.id, + one: "foo", + two: "bar", + }) + + expect(row.one).toBeUndefined() + expect(row.two).toEqual("bar") + }) }) describe("patch", () => { @@ -893,6 +914,33 @@ describe.each([ expect(row.one).toEqual("foo") expect(row.two).toEqual("newBar") }) + + it("can't update readonly columns", async () => { + mocks.licenses.useViewReadonlyColumns() + const view = await config.api.viewV2.create({ + tableId: table._id!, + name: generator.guid(), + schema: { + one: { visible: true, readonly: true }, + two: { visible: true }, + }, + }) + const newRow = await config.api.row.save(table._id!, { + one: "foo", + two: "bar", + }) + await config.api.row.patch(view.id, { + tableId: table._id!, + _id: newRow._id!, + _rev: newRow._rev!, + one: "newFoo", + two: "newBar", + }) + + const row = await config.api.row.get(table._id!, newRow._id!) + expect(row.one).toEqual("foo") + expect(row.two).toEqual("newBar") + }) }) describe("destroy", () => { diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index da66e8ac18..ea05ecf512 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -104,7 +104,13 @@ export async function remove(viewId: string): Promise { export function allowedFields(view: View | ViewV2) { return [ - ...Object.keys(view?.schema || {}), + ...Object.keys(view?.schema || {}).filter(key => { + if (!isV2(view)) { + return true + } + const fieldSchema = view.schema![key] + return fieldSchema.visible && !fieldSchema.readonly + }), ...dbCore.CONSTANT_EXTERNAL_ROW_COLS, ...dbCore.CONSTANT_INTERNAL_ROW_COLS, ]