From 62fa05a855205f43b0ef929fc051cd91b0fd8f58 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 31 Jul 2024 13:28:28 +0200 Subject: [PATCH 1/3] Type --- packages/server/src/sdk/app/rows/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/sdk/app/rows/utils.ts b/packages/server/src/sdk/app/rows/utils.ts index cd1b663f6a..e463397ad9 100644 --- a/packages/server/src/sdk/app/rows/utils.ts +++ b/packages/server/src/sdk/app/rows/utils.ts @@ -76,7 +76,7 @@ export async function getDatasourceAndQuery( } export function cleanExportRows( - rows: any[], + rows: Row[], schema: TableSchema, format: string, columns?: string[], From fe2b2bb097fb4ee106754630d2419f0f6a8a3cd2 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 31 Jul 2024 13:33:20 +0200 Subject: [PATCH 2/3] Don't export couchdb fields --- .../server/src/sdk/app/rows/search/internal.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/server/src/sdk/app/rows/search/internal.ts b/packages/server/src/sdk/app/rows/search/internal.ts index 46d2cd8c61..f86b041597 100644 --- a/packages/server/src/sdk/app/rows/search/internal.ts +++ b/packages/server/src/sdk/app/rows/search/internal.ts @@ -11,6 +11,7 @@ import { SearchResponse, SortType, Table, + TableSchema, User, } from "@budibase/types" import { getGlobalUsersFromMetadata } from "../../../../utilities/global" @@ -137,6 +138,9 @@ export async function exportRows( let rows: Row[] = [] let schema = table.schema let headers + + result = trimFields(result, schema) + // Filter data to only specified columns if required if (columns && columns.length) { for (let i = 0; i < result.length; i++) { @@ -299,3 +303,13 @@ async function getView(db: Database, viewName: string) { } return viewInfo } + +function trimFields(rows: Row[], schema: TableSchema) { + const allowedFields = ["_id", ...Object.keys(schema)] + const result = rows.map(row => + Object.keys(row) + .filter(key => allowedFields.includes(key)) + .reduce((acc, key) => ({ ...acc, [key]: row[key] }), {} as Row) + ) + return result +} From 543d0e1ce619b7fbaeeb994c0d33c325b2d934eb Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 31 Jul 2024 14:01:38 +0200 Subject: [PATCH 3/3] Add tests --- .../server/src/api/routes/tests/row.spec.ts | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index 8871841ee7..96a157893f 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -1640,23 +1640,38 @@ describe.each([ table = await config.api.table.save(defaultTable()) }) - it("should allow exporting all columns", async () => { - const existing = await config.api.row.save(table._id!, {}) - const res = await config.api.row.exportRows(table._id!, { - rows: [existing._id!], - }) - const results = JSON.parse(res) - expect(results.length).toEqual(1) - const row = results[0] + isInternal && + it("should not export internal couchdb fields", async () => { + const existing = await config.api.row.save(table._id!, { + name: generator.guid(), + description: generator.paragraph(), + }) + const res = await config.api.row.exportRows(table._id!, { + rows: [existing._id!], + }) + const results = JSON.parse(res) + expect(results.length).toEqual(1) + const row = results[0] - // Ensure all original columns were exported - expect(Object.keys(row).length).toBeGreaterThanOrEqual( - Object.keys(existing).length - ) - Object.keys(existing).forEach(key => { - expect(row[key]).toEqual(existing[key]) + expect(Object.keys(row)).toEqual(["_id", "name", "description"]) + }) + + !isInternal && + it("should allow exporting all columns", async () => { + const existing = await config.api.row.save(table._id!, {}) + const res = await config.api.row.exportRows(table._id!, { + rows: [existing._id!], + }) + const results = JSON.parse(res) + expect(results.length).toEqual(1) + const row = results[0] + + // Ensure all original columns were exported + expect(Object.keys(row).length).toBe(Object.keys(existing).length) + Object.keys(existing).forEach(key => { + expect(row[key]).toEqual(existing[key]) + }) }) - }) it("should allow exporting only certain columns", async () => { const existing = await config.api.row.save(table._id!, {})