From 854cfd243d8aeecec4f83b962517d79d0de7c296 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 18 Nov 2021 18:33:35 +0000 Subject: [PATCH 1/2] Fix for #2420 - don't allow columns which are considered invalid/not allowed. --- .../server/src/api/controllers/datasource.js | 42 +++++++++++++++---- packages/server/src/constants/index.js | 7 ++++ packages/server/src/integrations/utils.ts | 7 +++- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/packages/server/src/api/controllers/datasource.js b/packages/server/src/api/controllers/datasource.js index 009baec9e0..112af96939 100644 --- a/packages/server/src/api/controllers/datasource.js +++ b/packages/server/src/api/controllers/datasource.js @@ -7,7 +7,7 @@ const { BudibaseInternalDB, getTableParams, } = require("../../db/utils") -const { BuildSchemaErrors } = require("../../constants") +const { BuildSchemaErrors, InvalidColumns } = require("../../constants") const { integrations } = require("../../integrations") const { getDatasourceAndQuery } = require("./row/utils") @@ -152,6 +152,23 @@ exports.query = async function (ctx) { } } +function getErrorTables(errors, errorType) { + return Object.entries(errors) + .filter(entry => entry[1] === errorType) + .map(([name]) => name) +} + +function updateError(error, newError, tables) { + if (!error) { + error = "" + } + if (error.length > 0) { + error += " - " + } + error += `${newError} ${tables.join(", ")}` + return error +} + const buildSchemaHelper = async datasource => { const Connector = integrations[datasource.source] @@ -176,12 +193,23 @@ const buildSchemaHelper = async datasource => { const errors = connector.schemaErrors let error = null if (errors && Object.keys(errors).length > 0) { - const noKeyTables = Object.entries(errors) - .filter(entry => entry[1] === BuildSchemaErrors.NO_KEY) - .map(([name]) => name) - error = `No primary key constraint found for the following: ${noKeyTables.join( - ", " - )}` + const noKey = getErrorTables(errors, BuildSchemaErrors.NO_KEY) + const invalidCol = getErrorTables(errors, BuildSchemaErrors.INVALID_COLUMN) + if (noKey.length) { + error = updateError( + error, + "No primary key constraint found for the following:", + noKey + ) + } + if (invalidCol.length) { + const invalidCols = Object.values(InvalidColumns).join(", ") + error = updateError( + error, + `Cannot use columns ${invalidCols} found in following:`, + invalidCol + ) + } } return { tables: connector.tables, error } } diff --git a/packages/server/src/constants/index.js b/packages/server/src/constants/index.js index 31353a2e90..c3cb9b7a58 100644 --- a/packages/server/src/constants/index.js +++ b/packages/server/src/constants/index.js @@ -163,8 +163,15 @@ exports.MetadataTypes = { AUTOMATION_TEST_HISTORY: "automationTestHistory", } +exports.InvalidColumns = { + ID: "_id", + REV: "_rev", + TABLE_ID: "tableId", +} + exports.BuildSchemaErrors = { NO_KEY: "no_key", + INVALID_COLUMN: "invalid_column", } // pass through the list from the auth/core lib diff --git a/packages/server/src/integrations/utils.ts b/packages/server/src/integrations/utils.ts index 072cfd138f..59481bcfc3 100644 --- a/packages/server/src/integrations/utils.ts +++ b/packages/server/src/integrations/utils.ts @@ -2,7 +2,7 @@ import { SqlQuery } from "../definitions/datasource" import { Datasource, Table } from "../definitions/common" import { SourceNames } from "../definitions/datasource" const { DocumentTypes, SEPARATOR } = require("../db/utils") -const { FieldTypes, BuildSchemaErrors } = require("../constants") +const { FieldTypes, BuildSchemaErrors, InvalidColumns } = require("../constants") const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}` const ROW_ID_REGEX = /^\[.*]$/g @@ -161,13 +161,18 @@ export function finaliseExternalTables( tables: { [key: string]: any }, entities: { [key: string]: any } ) { + const invalidColumns = Object.values(InvalidColumns) const finalTables: { [key: string]: any } = {} const errors: { [key: string]: string } = {} for (let [name, table] of Object.entries(tables)) { + const schemaFields = Object.keys(table.schema) // make sure every table has a key if (table.primary == null || table.primary.length === 0) { errors[name] = BuildSchemaErrors.NO_KEY continue + } else if (schemaFields.find(field => invalidColumns.includes(field))) { + errors[name] = BuildSchemaErrors.INVALID_COLUMN + continue } // make sure all previous props have been added back finalTables[name] = copyExistingPropsOver(name, table, entities) From 19c096c3e56734c69981e0ab64933f18404696b7 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 22 Nov 2021 10:37:58 +0000 Subject: [PATCH 2/2] Updating inline alert component to handle newlines as different elements, putting out error with new lines. --- packages/bbui/src/InlineAlert/InlineAlert.svelte | 6 +++++- packages/server/src/api/controllers/datasource.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/bbui/src/InlineAlert/InlineAlert.svelte b/packages/bbui/src/InlineAlert/InlineAlert.svelte index 2e4dd0f69a..25e14b7caf 100644 --- a/packages/bbui/src/InlineAlert/InlineAlert.svelte +++ b/packages/bbui/src/InlineAlert/InlineAlert.svelte @@ -8,6 +8,8 @@ export let onConfirm = undefined $: icon = selectIcon(type) + // if newlines used, convert them to different elements + $: split = message.split("\n") function selectIcon(alertType) { switch (alertType) { @@ -33,7 +35,9 @@
{header}
-
{message}
+ {#each split as splitMsg} +
{splitMsg}
+ {/each} {#if onConfirm}