From f946f2f68d54e370013e28efa4cb6517067e5b18 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Thu, 3 Feb 2022 18:26:26 +0000 Subject: [PATCH 1/2] Fix for #4308 - triple brace conversion was not working correctly, wrote this into the string templates instead - also fixing an issue with the RBAC for Rest. --- .../integration/AccessLevelSelect.svelte | 1 + packages/server/src/threads/query.js | 11 ++----- packages/string-templates/src/index.cjs | 1 + packages/string-templates/src/index.js | 31 ++++++++++++++++--- packages/string-templates/src/index.mjs | 1 + packages/string-templates/src/utilities.js | 1 + packages/string-templates/test/basic.spec.js | 20 ++++++++++++ 7 files changed, 52 insertions(+), 14 deletions(-) diff --git a/packages/builder/src/components/integration/AccessLevelSelect.svelte b/packages/builder/src/components/integration/AccessLevelSelect.svelte index 97587c287a..86065893d4 100644 --- a/packages/builder/src/components/integration/AccessLevelSelect.svelte +++ b/packages/builder/src/components/integration/AccessLevelSelect.svelte @@ -26,6 +26,7 @@ async function getPermissions(queryToFetch) { if (fetched?._id === queryToFetch?._id) { + loaded = true return } fetched = queryToFetch diff --git a/packages/server/src/threads/query.js b/packages/server/src/threads/query.js index 35164ac642..7498ff4fb0 100644 --- a/packages/server/src/threads/query.js +++ b/packages/server/src/threads/query.js @@ -5,9 +5,6 @@ const { integrations } = require("../integrations") const { processStringSync } = require("@budibase/string-templates") const CouchDB = require("../db") -const IS_TRIPLE_BRACE = new RegExp(/^{{3}.*}{3}$/) -const IS_HANDLEBARS = new RegExp(/^{{2}.*}{2}$/) - class QueryRunner { constructor(input, flags = { noRecursiveQuery: false }) { this.appId = input.appId @@ -185,12 +182,8 @@ class QueryRunner { enrichedQuery[key] = this.enrichQueryFields(fields[key], parameters) } else if (typeof fields[key] === "string") { // enrich string value as normal - let value = fields[key] - // add triple brace to avoid escaping e.g. '=' in cookie header - if (IS_HANDLEBARS.test(value) && !IS_TRIPLE_BRACE.test(value)) { - value = `{${value}}` - } - enrichedQuery[key] = processStringSync(value, parameters, { + enrichedQuery[key] = processStringSync(fields[key], parameters, { + noEscaping: true, noHelpers: true, }) } else { diff --git a/packages/string-templates/src/index.cjs b/packages/string-templates/src/index.cjs index 5d05f0f57f..dadaea4bba 100644 --- a/packages/string-templates/src/index.cjs +++ b/packages/string-templates/src/index.cjs @@ -15,6 +15,7 @@ module.exports.processStringSync = templates.processStringSync module.exports.processObjectSync = templates.processObjectSync module.exports.processString = templates.processString module.exports.processObject = templates.processObject +module.exports.disableEscaping = templates.disableEscaping /** * Use vm2 to run JS scripts in a node env diff --git a/packages/string-templates/src/index.js b/packages/string-templates/src/index.js index d824d5f1db..404161c4eb 100644 --- a/packages/string-templates/src/index.js +++ b/packages/string-templates/src/index.js @@ -3,11 +3,12 @@ const { registerAll } = require("./helpers/index") const processors = require("./processors") const { atob, btoa } = require("./utilities") const manifest = require("../manifest.json") +const { FIND_DOUBLE_HBS_REGEX } = require("./utilities") const hbsInstance = handlebars.create() registerAll(hbsInstance) const hbsInstanceNoHelpers = handlebars.create() -const defaultOpts = { noHelpers: false } +const defaultOpts = { noHelpers: false, noEscaping: false } /** * utility function to check if the object is valid @@ -57,7 +58,7 @@ module.exports.processObject = async (object, context, opts) => { * then nothing will occur. * @param {string} string The template string which is the filled from the context object. * @param {object} context An object of information which will be used to enrich the string. - * @param {object} opts optional - specify some options for processing. + * @param {object|undefined} opts optional - specify some options for processing. * @returns {Promise} The enriched string, all templates should have been replaced if they can be. */ module.exports.processString = async (string, context, opts) => { @@ -71,7 +72,7 @@ module.exports.processString = async (string, context, opts) => { * @param {object|array} object The input structure which is to be recursed, it is important to note that * if the structure contains any cycles then this will fail. * @param {object} context The context that handlebars should fill data from. - * @param {object} opts optional - specify some options for processing. + * @param {object|undefined} opts optional - specify some options for processing. * @returns {object|array} The structure input, as fully updated as possible. */ module.exports.processObjectSync = (object, context, opts) => { @@ -92,7 +93,7 @@ module.exports.processObjectSync = (object, context, opts) => { * then nothing will occur. This is a pure sync call and therefore does not have the full functionality of the async call. * @param {string} string The template string which is the filled from the context object. * @param {object} context An object of information which will be used to enrich the string. - * @param {object} opts optional - specify some options for processing. + * @param {object|undefined} opts optional - specify some options for processing. * @returns {string} The enriched string, all templates should have been replaced if they can be. */ module.exports.processStringSync = (string, context, opts) => { @@ -109,7 +110,9 @@ module.exports.processStringSync = (string, context, opts) => { string = processors.preprocess(string, shouldFinalise) // this does not throw an error when template can't be fulfilled, have to try correct beforehand const instance = opts.noHelpers ? hbsInstanceNoHelpers : hbsInstance - const template = instance.compile(string, { + const templateString = + opts && opts.noEscaping ? exports.disableEscaping(string) : string + const template = instance.compile(templateString, { strict: false, }) const now = Math.floor(Date.now() / 1000) * 1000 @@ -124,6 +127,24 @@ module.exports.processStringSync = (string, context, opts) => { } } +/** + * By default with expressions like {{ name }} handlebars will escape various + * characters, which can be problematic. To fix this we use the syntax {{{ name }}}, + * this function will find any double braces and switch to triple. + * @param string the string to have double HBS statements converted to triple. + */ +module.exports.disableEscaping = string => { + let regexp = new RegExp(FIND_DOUBLE_HBS_REGEX) + const matches = string.match(regexp) + if (matches == null) { + return string + } + for (let match of matches) { + string = string.replace(match, `{${match}}`) + } + return string +} + /** * Simple utility function which makes sure that a templating property has been wrapped in literal specifiers correctly. * @param {string} property The property which is to be wrapped. diff --git a/packages/string-templates/src/index.mjs b/packages/string-templates/src/index.mjs index 446e71ef88..395a0f497c 100644 --- a/packages/string-templates/src/index.mjs +++ b/packages/string-templates/src/index.mjs @@ -15,6 +15,7 @@ export const processStringSync = templates.processStringSync export const processObjectSync = templates.processObjectSync export const processString = templates.processString export const processObject = templates.processObject +export const disableEscaping = templates.disableEscaping /** * Use polyfilled vm to run JS scripts in a browser Env diff --git a/packages/string-templates/src/utilities.js b/packages/string-templates/src/utilities.js index 645aca78ba..9704f84ecc 100644 --- a/packages/string-templates/src/utilities.js +++ b/packages/string-templates/src/utilities.js @@ -1,6 +1,7 @@ const ALPHA_NUMERIC_REGEX = /^[A-Za-z0-9]+$/g module.exports.FIND_HBS_REGEX = /{{([^{].*?)}}/g +module.exports.FIND_DOUBLE_HBS_REGEX = /(? { return char.match(ALPHA_NUMERIC_REGEX) diff --git a/packages/string-templates/test/basic.spec.js b/packages/string-templates/test/basic.spec.js index b437e386fc..89a749832a 100644 --- a/packages/string-templates/test/basic.spec.js +++ b/packages/string-templates/test/basic.spec.js @@ -4,6 +4,7 @@ const { isValid, makePropSafe, getManifest, + disableEscaping, } = require("../src/index.cjs") describe("Test that the string processing works correctly", () => { @@ -146,3 +147,22 @@ describe("check manifest", () => { ) }) }) + +describe("check that disabling escaping function works", () => { + it("should work for a single statement", () => { + expect(disableEscaping("{{ name }}")).toEqual("{{{ name }}}") + }) + + it("should work for two statements", () => { + expect(disableEscaping("{{ name }} welcome to {{ platform }}")).toEqual("{{{ name }}} welcome to {{{ platform }}}") + }) + + it("shouldn't convert triple braces", () => { + expect(disableEscaping("{{{ name }}}")).toEqual("{{{ name }}}") + }) + + it("should work with a combination", () => { + expect(disableEscaping("{{ name }} welcome to {{{ platform }}}")).toEqual("{{{ name }}} welcome to {{{ platform }}}") + }) +}) + From 2dea8789e8e2f284c630ce7eb4b074c461fcc14a Mon Sep 17 00:00:00 2001 From: Budibase Release Bot <> Date: Fri, 4 Feb 2022 12:19:39 +0000 Subject: [PATCH 2/2] v1.0.49 --- lerna.json | 2 +- packages/backend-core/package.json | 2 +- packages/bbui/package.json | 2 +- packages/builder/package.json | 8 ++++---- packages/cli/package.json | 2 +- packages/client/package.json | 6 +++--- packages/server/package.json | 8 ++++---- packages/string-templates/package.json | 2 +- packages/worker/package.json | 6 +++--- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lerna.json b/lerna.json index 801ba1b871..2e979b7175 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.0.48", + "version": "1.0.49", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index f1998660a8..b382fded28 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.0.48", + "version": "1.0.49", "description": "Budibase backend core libraries used in server and worker", "main": "src/index.js", "author": "Budibase", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index d9192c8b71..89ceca0261 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "1.0.48", + "version": "1.0.49", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/builder/package.json b/packages/builder/package.json index f956a22027..a92a613f4f 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.0.48", + "version": "1.0.49", "license": "GPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.0.48", - "@budibase/client": "^1.0.48", + "@budibase/bbui": "^1.0.49", + "@budibase/client": "^1.0.49", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^1.0.48", + "@budibase/string-templates": "^1.0.49", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 016de84bef..22872872c7 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "1.0.48", + "version": "1.0.49", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { diff --git a/packages/client/package.json b/packages/client/package.json index 4cdbd22f18..6573c17151 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "1.0.48", + "version": "1.0.49", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,9 +19,9 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "^1.0.48", + "@budibase/bbui": "^1.0.49", "@budibase/standard-components": "^0.9.139", - "@budibase/string-templates": "^1.0.48", + "@budibase/string-templates": "^1.0.49", "regexparam": "^1.3.0", "shortid": "^2.2.15", "svelte-spa-router": "^3.0.5" diff --git a/packages/server/package.json b/packages/server/package.json index 16a3a6803f..23d7768b7e 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "1.0.48", + "version": "1.0.49", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -70,9 +70,9 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "^10.0.3", - "@budibase/backend-core": "^1.0.48", - "@budibase/client": "^1.0.48", - "@budibase/string-templates": "^1.0.48", + "@budibase/backend-core": "^1.0.49", + "@budibase/client": "^1.0.49", + "@budibase/string-templates": "^1.0.49", "@bull-board/api": "^3.7.0", "@bull-board/koa": "^3.7.0", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 69c7ae8f83..617d54b09e 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.0.48", + "version": "1.0.49", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/worker/package.json b/packages/worker/package.json index f263f50a27..458ae31de4 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "1.0.48", + "version": "1.0.49", "description": "Budibase background service", "main": "src/index.js", "repository": { @@ -29,8 +29,8 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "^1.0.48", - "@budibase/string-templates": "^1.0.48", + "@budibase/backend-core": "^1.0.49", + "@budibase/string-templates": "^1.0.49", "@koa/router": "^8.0.0", "@sentry/node": "^6.0.0", "@techpass/passport-openidconnect": "^0.3.0",