From 8612782610fca9a2596d6002a443527c6ee9edfb Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 25 Feb 2021 12:06:13 +0000 Subject: [PATCH] Found some issues with relationship columns being doubled up, this isn't validated client side, best to make sure it doesn't happen server-side (can really break your data structure if columns overwrite each other). --- .../server/src/api/controllers/table/index.js | 24 ++++++++++-------- .../src/db/linkedRows/LinkController.js | 25 +++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/server/src/api/controllers/table/index.js b/packages/server/src/api/controllers/table/index.js index b8e3e56e3a..93f4ec9f94 100644 --- a/packages/server/src/api/controllers/table/index.js +++ b/packages/server/src/api/controllers/table/index.js @@ -89,16 +89,20 @@ exports.save = async function(ctx) { } // update linked rows - const linkResp = await linkRows.updateLinks({ - appId, - eventType: oldTable - ? linkRows.EventType.TABLE_UPDATED - : linkRows.EventType.TABLE_SAVE, - table: tableToSave, - oldTable: oldTable, - }) - if (linkResp != null && linkResp._rev) { - tableToSave._rev = linkResp._rev + try { + const linkResp = await linkRows.updateLinks({ + appId, + eventType: oldTable + ? linkRows.EventType.TABLE_UPDATED + : linkRows.EventType.TABLE_SAVE, + table: tableToSave, + oldTable: oldTable, + }) + if (linkResp != null && linkResp._rev) { + tableToSave._rev = linkResp._rev + } + } catch (err) { + ctx.throw(400, err) } // don't perform any updates until relationships have been diff --git a/packages/server/src/db/linkedRows/LinkController.js b/packages/server/src/db/linkedRows/LinkController.js index d202c07d63..199b8f5755 100644 --- a/packages/server/src/db/linkedRows/LinkController.js +++ b/packages/server/src/db/linkedRows/LinkController.js @@ -3,6 +3,7 @@ const { IncludeDocs, getLinkDocuments } = require("./linkUtils") const { generateLinkID } = require("../utils") const Sentry = require("@sentry/node") const { FieldTypes } = require("../../constants") +const { isEqual } = require("lodash") /** * Creates a new link document structure which can be put to the database. It is important to @@ -113,6 +114,23 @@ class LinkController { }) } + /** + * Makes sure the passed in table schema contains valid relationship structures. + */ + validateTable(table) { + const usedAlready = [] + for (let schema of Object.values(table.schema)) { + if (schema.type !== FieldTypes.LINK) { + continue + } + const unique = schema.tableId + schema.fieldName + if (usedAlready.indexOf(unique) !== -1) { + throw "Cannot re-use the linked column name for a linked table." + } + usedAlready.push(unique) + } + } + // all operations here will assume that the table // this operation is related to has linked rows /** @@ -246,6 +264,8 @@ class LinkController { */ async tableSaved() { const table = await this.table() + // validate the table first + this.validateTable(table) const schema = table.schema for (let fieldName of Object.keys(schema)) { const field = schema[fieldName] @@ -269,6 +289,11 @@ class LinkController { if (field.autocolumn) { linkConfig.autocolumn = field.autocolumn } + // check the linked table to make sure we aren't overwriting an existing column + const existingSchema = linkedTable.schema[field.fieldName] + if (existingSchema != null && !isEqual(existingSchema, linkConfig)) { + throw "Cannot overwrite existing column." + } // create the link field in the other table linkedTable.schema[field.fieldName] = linkConfig const response = await this._db.put(linkedTable)