diff --git a/.github/workflows/release-selfhost.yml b/.github/workflows/release-selfhost.yml index b746c76bc3..da064f3e32 100644 --- a/.github/workflows/release-selfhost.yml +++ b/.github/workflows/release-selfhost.yml @@ -12,19 +12,28 @@ jobs: runs-on: ubuntu-latest steps: + - name: Fail if branch is not master + if: github.ref != 'refs/heads/master' + run: | + echo "Ref is not master, you must run this job from master." + exit 1 + - uses: actions/checkout@v2 with: node-version: 14.x fetch_depth: 0 + - name: Get the latest budibase release version + id: version + run: | + release_version=$(cat lerna.json | jq -r '.version') + echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV + - name: Tag and release Docker images (Self Host) run: | docker login -u $DOCKER_USER -p $DOCKER_PASSWORD - # Get latest release version - release_version=$(cat lerna.json | jq -r '.version') - echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV - release_tag=v$release_version + release_tag=v${{ env.RELEASE_VERSION }} # Pull apps and worker images docker pull budibase/apps:$release_tag diff --git a/hosting/docker-compose.yaml b/hosting/docker-compose.yaml index 5281155545..7d3e6960dc 100644 --- a/hosting/docker-compose.yaml +++ b/hosting/docker-compose.yaml @@ -75,7 +75,7 @@ services: ports: - "${MAIN_PORT}:10000" container_name: bbproxy - image: proxy-service + image: budibase/proxy environment: - PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND=10 depends_on: diff --git a/lerna.json b/lerna.json index ac767be816..92a1d5913f 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.2.28", + "version": "1.2.38", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index b9d59e2a71..2145ebea9f 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.2.28", + "version": "1.2.38", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -20,7 +20,7 @@ "test:watch": "jest --watchAll" }, "dependencies": { - "@budibase/types": "^1.2.28", + "@budibase/types": "^1.2.38", "@techpass/passport-openidconnect": "0.3.2", "aws-sdk": "2.1030.0", "bcrypt": "5.0.1", diff --git a/packages/backend-core/src/cache/appMetadata.js b/packages/backend-core/src/cache/appMetadata.js index b0d9481cbd..a7ff0d2fc1 100644 --- a/packages/backend-core/src/cache/appMetadata.js +++ b/packages/backend-core/src/cache/appMetadata.js @@ -1,6 +1,6 @@ const redis = require("../redis/init") const { doWithDB } = require("../db") -const { DocumentTypes } = require("../db/constants") +const { DocumentType } = require("../db/constants") const AppState = { INVALID: "invalid", @@ -14,7 +14,7 @@ const populateFromDB = async appId => { return doWithDB( appId, db => { - return db.get(DocumentTypes.APP_METADATA) + return db.get(DocumentType.APP_METADATA) }, { skip_setup: true } ) diff --git a/packages/backend-core/src/context/constants.ts b/packages/backend-core/src/context/constants.ts index ef8dcd7821..937ad8f248 100644 --- a/packages/backend-core/src/context/constants.ts +++ b/packages/backend-core/src/context/constants.ts @@ -1,4 +1,4 @@ -export enum ContextKeys { +export enum ContextKey { TENANT_ID = "tenantId", GLOBAL_DB = "globalDb", APP_ID = "appId", diff --git a/packages/backend-core/src/context/index.ts b/packages/backend-core/src/context/index.ts index 1e430f01de..78ce764d55 100644 --- a/packages/backend-core/src/context/index.ts +++ b/packages/backend-core/src/context/index.ts @@ -1,11 +1,11 @@ import env from "../environment" -import { SEPARATOR, DocumentTypes } from "../db/constants" +import { SEPARATOR, DocumentType } from "../db/constants" import cls from "./FunctionContext" import { dangerousGetDB, closeDB } from "../db" import { baseGlobalDBName } from "../tenancy/utils" import { IdentityContext } from "@budibase/types" import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants" -import { ContextKeys } from "./constants" +import { ContextKey } from "./constants" import { updateUsing, closeWithUsing, @@ -33,8 +33,8 @@ export const closeTenancy = async () => { } await closeDB(db) // clear from context now that database is closed/task is finished - cls.setOnContext(ContextKeys.TENANT_ID, null) - cls.setOnContext(ContextKeys.GLOBAL_DB, null) + cls.setOnContext(ContextKey.TENANT_ID, null) + cls.setOnContext(ContextKey.GLOBAL_DB, null) } // export const isDefaultTenant = () => { @@ -54,7 +54,7 @@ export const getTenantIDFromAppID = (appId: string) => { return null } const split = appId.split(SEPARATOR) - const hasDev = split[1] === DocumentTypes.DEV + const hasDev = split[1] === DocumentType.DEV if ((hasDev && split.length === 3) || (!hasDev && split.length === 2)) { return null } @@ -83,14 +83,14 @@ export const doInTenant = (tenantId: string | null, task: any) => { // invoke the task return await task() } finally { - await closeWithUsing(ContextKeys.TENANCY_IN_USE, () => { + await closeWithUsing(ContextKey.TENANCY_IN_USE, () => { return closeTenancy() }) } } - const existing = cls.getFromContext(ContextKeys.TENANT_ID) === tenantId - return updateUsing(ContextKeys.TENANCY_IN_USE, existing, internal) + const existing = cls.getFromContext(ContextKey.TENANT_ID) === tenantId + return updateUsing(ContextKey.TENANCY_IN_USE, existing, internal) } export const doInAppContext = (appId: string, task: any) => { @@ -108,7 +108,7 @@ export const doInAppContext = (appId: string, task: any) => { setAppTenantId(appId) } // set the app ID - cls.setOnContext(ContextKeys.APP_ID, appId) + cls.setOnContext(ContextKey.APP_ID, appId) // preserve the identity if (identity) { @@ -118,14 +118,14 @@ export const doInAppContext = (appId: string, task: any) => { // invoke the task return await task() } finally { - await closeWithUsing(ContextKeys.APP_IN_USE, async () => { + await closeWithUsing(ContextKey.APP_IN_USE, async () => { await closeAppDBs() await closeTenancy() }) } } - const existing = cls.getFromContext(ContextKeys.APP_ID) === appId - return updateUsing(ContextKeys.APP_IN_USE, existing, internal) + const existing = cls.getFromContext(ContextKey.APP_ID) === appId + return updateUsing(ContextKey.APP_IN_USE, existing, internal) } export const doInIdentityContext = (identity: IdentityContext, task: any) => { @@ -135,7 +135,7 @@ export const doInIdentityContext = (identity: IdentityContext, task: any) => { async function internal(opts = { existing: false }) { if (!opts.existing) { - cls.setOnContext(ContextKeys.IDENTITY, identity) + cls.setOnContext(ContextKey.IDENTITY, identity) // set the tenant so that doInTenant will preserve identity if (identity.tenantId) { updateTenantId(identity.tenantId) @@ -146,27 +146,27 @@ export const doInIdentityContext = (identity: IdentityContext, task: any) => { // invoke the task return await task() } finally { - await closeWithUsing(ContextKeys.IDENTITY_IN_USE, async () => { + await closeWithUsing(ContextKey.IDENTITY_IN_USE, async () => { setIdentity(null) await closeTenancy() }) } } - const existing = cls.getFromContext(ContextKeys.IDENTITY) - return updateUsing(ContextKeys.IDENTITY_IN_USE, existing, internal) + const existing = cls.getFromContext(ContextKey.IDENTITY) + return updateUsing(ContextKey.IDENTITY_IN_USE, existing, internal) } export const getIdentity = (): IdentityContext | undefined => { try { - return cls.getFromContext(ContextKeys.IDENTITY) + return cls.getFromContext(ContextKey.IDENTITY) } catch (e) { // do nothing - identity is not in context } } export const updateTenantId = (tenantId: string | null) => { - cls.setOnContext(ContextKeys.TENANT_ID, tenantId) + cls.setOnContext(ContextKey.TENANT_ID, tenantId) if (env.USE_COUCH) { setGlobalDB(tenantId) } @@ -176,7 +176,7 @@ export const updateAppId = async (appId: string) => { try { // have to close first, before removing the databases from context await closeAppDBs() - cls.setOnContext(ContextKeys.APP_ID, appId) + cls.setOnContext(ContextKey.APP_ID, appId) } catch (err) { if (env.isTest()) { TEST_APP_ID = appId @@ -189,12 +189,12 @@ export const updateAppId = async (appId: string) => { export const setGlobalDB = (tenantId: string | null) => { const dbName = baseGlobalDBName(tenantId) const db = dangerousGetDB(dbName) - cls.setOnContext(ContextKeys.GLOBAL_DB, db) + cls.setOnContext(ContextKey.GLOBAL_DB, db) return db } export const getGlobalDB = () => { - const db = cls.getFromContext(ContextKeys.GLOBAL_DB) + const db = cls.getFromContext(ContextKey.GLOBAL_DB) if (!db) { throw new Error("Global DB not found") } @@ -202,7 +202,7 @@ export const getGlobalDB = () => { } export const isTenantIdSet = () => { - const tenantId = cls.getFromContext(ContextKeys.TENANT_ID) + const tenantId = cls.getFromContext(ContextKey.TENANT_ID) return !!tenantId } @@ -210,7 +210,7 @@ export const getTenantId = () => { if (!isMultiTenant()) { return DEFAULT_TENANT_ID } - const tenantId = cls.getFromContext(ContextKeys.TENANT_ID) + const tenantId = cls.getFromContext(ContextKey.TENANT_ID) if (!tenantId) { throw new Error("Tenant id not found") } @@ -218,7 +218,7 @@ export const getTenantId = () => { } export const getAppId = () => { - const foundId = cls.getFromContext(ContextKeys.APP_ID) + const foundId = cls.getFromContext(ContextKey.APP_ID) if (!foundId && env.isTest() && TEST_APP_ID) { return TEST_APP_ID } else { @@ -231,7 +231,7 @@ export const getAppId = () => { * contained, dev or prod. */ export const getAppDB = (opts?: any) => { - return getContextDB(ContextKeys.CURRENT_DB, opts) + return getContextDB(ContextKey.CURRENT_DB, opts) } /** @@ -239,7 +239,7 @@ export const getAppDB = (opts?: any) => { * contained a development app ID, this will open the prod one. */ export const getProdAppDB = (opts?: any) => { - return getContextDB(ContextKeys.PROD_DB, opts) + return getContextDB(ContextKey.PROD_DB, opts) } /** @@ -247,5 +247,5 @@ export const getProdAppDB = (opts?: any) => { * contained a prod app ID, this will open the dev one. */ export const getDevAppDB = (opts?: any) => { - return getContextDB(ContextKeys.DEV_DB, opts) + return getContextDB(ContextKey.DEV_DB, opts) } diff --git a/packages/backend-core/src/context/utils.ts b/packages/backend-core/src/context/utils.ts index 62693f18e8..6e7100b594 100644 --- a/packages/backend-core/src/context/utils.ts +++ b/packages/backend-core/src/context/utils.ts @@ -6,7 +6,7 @@ import { } from "./index" import cls from "./FunctionContext" import { IdentityContext } from "@budibase/types" -import { ContextKeys } from "./constants" +import { ContextKey } from "./constants" import { dangerousGetDB, closeDB } from "../db" import { isEqual } from "lodash" import { getDevelopmentAppID, getProdAppID } from "../db/conversions" @@ -47,17 +47,13 @@ export const setAppTenantId = (appId: string) => { } export const setIdentity = (identity: IdentityContext | null) => { - cls.setOnContext(ContextKeys.IDENTITY, identity) + cls.setOnContext(ContextKey.IDENTITY, identity) } // this function makes sure the PouchDB objects are closed and // fully deleted when finished - this protects against memory leaks export async function closeAppDBs() { - const dbKeys = [ - ContextKeys.CURRENT_DB, - ContextKeys.PROD_DB, - ContextKeys.DEV_DB, - ] + const dbKeys = [ContextKey.CURRENT_DB, ContextKey.PROD_DB, ContextKey.DEV_DB] for (let dbKey of dbKeys) { const db = cls.getFromContext(dbKey) if (!db) { @@ -68,16 +64,16 @@ export async function closeAppDBs() { cls.setOnContext(dbKey, null) } // clear the app ID now that the databases are closed - if (cls.getFromContext(ContextKeys.APP_ID)) { - cls.setOnContext(ContextKeys.APP_ID, null) + if (cls.getFromContext(ContextKey.APP_ID)) { + cls.setOnContext(ContextKey.APP_ID, null) } - if (cls.getFromContext(ContextKeys.DB_OPTS)) { - cls.setOnContext(ContextKeys.DB_OPTS, null) + if (cls.getFromContext(ContextKey.DB_OPTS)) { + cls.setOnContext(ContextKey.DB_OPTS, null) } } export function getContextDB(key: string, opts: any) { - const dbOptsKey = `${key}${ContextKeys.DB_OPTS}` + const dbOptsKey = `${key}${ContextKey.DB_OPTS}` let storedOpts = cls.getFromContext(dbOptsKey) let db = cls.getFromContext(key) if (db && isEqual(opts, storedOpts)) { @@ -88,13 +84,13 @@ export function getContextDB(key: string, opts: any) { let toUseAppId switch (key) { - case ContextKeys.CURRENT_DB: + case ContextKey.CURRENT_DB: toUseAppId = appId break - case ContextKeys.PROD_DB: + case ContextKey.PROD_DB: toUseAppId = getProdAppID(appId) break - case ContextKeys.DEV_DB: + case ContextKey.DEV_DB: toUseAppId = getDevelopmentAppID(appId) break } diff --git a/packages/backend-core/src/db/constants.ts b/packages/backend-core/src/db/constants.ts index 9c6be25424..460476da24 100644 --- a/packages/backend-core/src/db/constants.ts +++ b/packages/backend-core/src/db/constants.ts @@ -4,13 +4,13 @@ export const UNICODE_MAX = "\ufff0" /** * Can be used to create a few different forms of querying a view. */ -export enum AutomationViewModes { +export enum AutomationViewMode { ALL = "all", AUTOMATION = "automation", STATUS = "status", } -export enum ViewNames { +export enum ViewName { USER_BY_APP = "by_app", USER_BY_EMAIL = "by_email2", BY_API_KEY = "by_api_key", @@ -21,13 +21,13 @@ export enum ViewNames { } export const DeprecatedViews = { - [ViewNames.USER_BY_EMAIL]: [ + [ViewName.USER_BY_EMAIL]: [ // removed due to inaccuracy in view doc filter logic "by_email", ], } -export enum DocumentTypes { +export enum DocumentType { USER = "us", GROUP = "gr", WORKSPACE = "workspace", @@ -62,6 +62,6 @@ export const StaticDatabases = { }, } -export const APP_PREFIX = exports.DocumentTypes.APP + exports.SEPARATOR -export const APP_DEV = exports.DocumentTypes.APP_DEV + exports.SEPARATOR +export const APP_PREFIX = DocumentType.APP + SEPARATOR +export const APP_DEV = DocumentType.APP_DEV + SEPARATOR export const APP_DEV_PREFIX = APP_DEV diff --git a/packages/backend-core/src/db/utils.ts b/packages/backend-core/src/db/utils.ts index 8ab6fa6e98..41479c2b31 100644 --- a/packages/backend-core/src/db/utils.ts +++ b/packages/backend-core/src/db/utils.ts @@ -1,7 +1,7 @@ import { newid } from "../hashing" import { DEFAULT_TENANT_ID, Configs } from "../constants" import env from "../environment" -import { SEPARATOR, DocumentTypes, UNICODE_MAX, ViewNames } from "./constants" +import { SEPARATOR, DocumentType, UNICODE_MAX, ViewName } from "./constants" import { getTenantId, getGlobalDBName, getGlobalDB } from "../tenancy" import fetch from "node-fetch" import { doWithDB, allDbs } from "./index" @@ -58,7 +58,7 @@ export function getDocParams( /** * Retrieve the correct index for a view based on default design DB. */ -export function getQueryIndex(viewName: ViewNames) { +export function getQueryIndex(viewName: ViewName) { return `database/${viewName}` } @@ -67,7 +67,7 @@ export function getQueryIndex(viewName: ViewNames) { * @returns {string} The new workspace ID which the workspace doc can be stored under. */ export function generateWorkspaceID() { - return `${DocumentTypes.WORKSPACE}${SEPARATOR}${newid()}` + return `${DocumentType.WORKSPACE}${SEPARATOR}${newid()}` } /** @@ -76,8 +76,8 @@ export function generateWorkspaceID() { export function getWorkspaceParams(id = "", otherProps = {}) { return { ...otherProps, - startkey: `${DocumentTypes.WORKSPACE}${SEPARATOR}${id}`, - endkey: `${DocumentTypes.WORKSPACE}${SEPARATOR}${id}${UNICODE_MAX}`, + startkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}`, + endkey: `${DocumentType.WORKSPACE}${SEPARATOR}${id}${UNICODE_MAX}`, } } @@ -86,7 +86,7 @@ export function getWorkspaceParams(id = "", otherProps = {}) { * @returns {string} The new user ID which the user doc can be stored under. */ export function generateGlobalUserID(id?: any) { - return `${DocumentTypes.USER}${SEPARATOR}${id || newid()}` + return `${DocumentType.USER}${SEPARATOR}${id || newid()}` } /** @@ -102,8 +102,8 @@ export function getGlobalUserParams(globalId: any, otherProps: any = {}) { // need to include this incase pagination startkey: startkey ? startkey - : `${DocumentTypes.USER}${SEPARATOR}${globalId}`, - endkey: `${DocumentTypes.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`, + : `${DocumentType.USER}${SEPARATOR}${globalId}`, + endkey: `${DocumentType.USER}${SEPARATOR}${globalId}${UNICODE_MAX}`, } } @@ -121,7 +121,7 @@ export function getUsersByAppParams(appId: any, otherProps: any = {}) { * @param ownerId The owner/user of the template, this could be global or a workspace level. */ export function generateTemplateID(ownerId: any) { - return `${DocumentTypes.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}` + return `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}` } export function generateAppUserID(prodAppId: string, userId: string) { @@ -143,7 +143,7 @@ export function getTemplateParams( if (templateId) { final = templateId } else { - final = `${DocumentTypes.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}` + final = `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}` } return { ...otherProps, @@ -157,14 +157,14 @@ export function getTemplateParams( * @returns {string} The new role ID which the role doc can be stored under. */ export function generateRoleID(id: any) { - return `${DocumentTypes.ROLE}${SEPARATOR}${id || newid()}` + return `${DocumentType.ROLE}${SEPARATOR}${id || newid()}` } /** * Gets parameters for retrieving a role, this is a utility function for the getDocParams function. */ export function getRoleParams(roleId = null, otherProps = {}) { - return getDocParams(DocumentTypes.ROLE, roleId, otherProps) + return getDocParams(DocumentType.ROLE, roleId, otherProps) } export function getStartEndKeyURL(base: any, baseKey: any, tenantId = null) { @@ -211,9 +211,9 @@ export async function getAllDbs(opts = { efficient: false }) { await addDbs(couchUrl) } else { // get prod apps - await addDbs(getStartEndKeyURL(couchUrl, DocumentTypes.APP, tenantId)) + await addDbs(getStartEndKeyURL(couchUrl, DocumentType.APP, tenantId)) // get dev apps - await addDbs(getStartEndKeyURL(couchUrl, DocumentTypes.APP_DEV, tenantId)) + await addDbs(getStartEndKeyURL(couchUrl, DocumentType.APP_DEV, tenantId)) // add global db name dbs.push(getGlobalDBName(tenantId)) } @@ -235,12 +235,12 @@ export async function getAllApps({ dev, all, idsOnly, efficient }: any = {}) { const appDbNames = dbs.filter((dbName: any) => { const split = dbName.split(SEPARATOR) // it is an app, check the tenantId - if (split[0] === DocumentTypes.APP) { + if (split[0] === DocumentType.APP) { // tenantId is always right before the UUID const possibleTenantId = split[split.length - 2] const noTenantId = - split.length === 2 || possibleTenantId === DocumentTypes.DEV + split.length === 2 || possibleTenantId === DocumentType.DEV return ( (tenantId === DEFAULT_TENANT_ID && noTenantId) || @@ -326,7 +326,7 @@ export async function dbExists(dbName: any) { export const generateConfigID = ({ type, workspace, user }: any) => { const scope = [type, workspace, user].filter(Boolean).join(SEPARATOR) - return `${DocumentTypes.CONFIG}${SEPARATOR}${scope}` + return `${DocumentType.CONFIG}${SEPARATOR}${scope}` } /** @@ -340,8 +340,8 @@ export const getConfigParams = ( return { ...otherProps, - startkey: `${DocumentTypes.CONFIG}${SEPARATOR}${scope}`, - endkey: `${DocumentTypes.CONFIG}${SEPARATOR}${scope}${UNICODE_MAX}`, + startkey: `${DocumentType.CONFIG}${SEPARATOR}${scope}`, + endkey: `${DocumentType.CONFIG}${SEPARATOR}${scope}${UNICODE_MAX}`, } } @@ -350,7 +350,7 @@ export const getConfigParams = ( * @returns {string} The new dev info ID which info for dev (like api key) can be stored under. */ export const generateDevInfoID = (userId: any) => { - return `${DocumentTypes.DEV_INFO}${SEPARATOR}${userId}` + return `${DocumentType.DEV_INFO}${SEPARATOR}${userId}` } /** diff --git a/packages/backend-core/src/db/views.js b/packages/backend-core/src/db/views.js index baf1807ca5..3a45611a8f 100644 --- a/packages/backend-core/src/db/views.js +++ b/packages/backend-core/src/db/views.js @@ -1,6 +1,6 @@ const { - DocumentTypes, - ViewNames, + DocumentType, + ViewName, DeprecatedViews, SEPARATOR, } = require("./utils") @@ -44,14 +44,14 @@ exports.createNewUserEmailView = async () => { const view = { // if using variables in a map function need to inject them before use map: `function(doc) { - if (doc._id.startsWith("${DocumentTypes.USER}${SEPARATOR}")) { + if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}")) { emit(doc.email.toLowerCase(), doc._id) } }`, } designDoc.views = { ...designDoc.views, - [ViewNames.USER_BY_EMAIL]: view, + [ViewName.USER_BY_EMAIL]: view, } await db.put(designDoc) } @@ -68,7 +68,7 @@ exports.createUserAppView = async () => { const view = { // if using variables in a map function need to inject them before use map: `function(doc) { - if (doc._id.startsWith("${DocumentTypes.USER}${SEPARATOR}") && doc.roles) { + if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}") && doc.roles) { for (let prodAppId of Object.keys(doc.roles)) { let emitted = prodAppId + "${SEPARATOR}" + doc._id emit(emitted, null) @@ -78,7 +78,7 @@ exports.createUserAppView = async () => { } designDoc.views = { ...designDoc.views, - [ViewNames.USER_BY_APP]: view, + [ViewName.USER_BY_APP]: view, } await db.put(designDoc) } @@ -93,14 +93,14 @@ exports.createApiKeyView = async () => { } const view = { map: `function(doc) { - if (doc._id.startsWith("${DocumentTypes.DEV_INFO}") && doc.apiKey) { + if (doc._id.startsWith("${DocumentType.DEV_INFO}") && doc.apiKey) { emit(doc.apiKey, doc.userId) } }`, } designDoc.views = { ...designDoc.views, - [ViewNames.BY_API_KEY]: view, + [ViewName.BY_API_KEY]: view, } await db.put(designDoc) } @@ -123,17 +123,17 @@ exports.createUserBuildersView = async () => { } designDoc.views = { ...designDoc.views, - [ViewNames.USER_BY_BUILDERS]: view, + [ViewName.USER_BY_BUILDERS]: view, } await db.put(designDoc) } exports.queryGlobalView = async (viewName, params, db = null) => { const CreateFuncByName = { - [ViewNames.USER_BY_EMAIL]: exports.createNewUserEmailView, - [ViewNames.BY_API_KEY]: exports.createApiKeyView, - [ViewNames.USER_BY_BUILDERS]: exports.createUserBuildersView, - [ViewNames.USER_BY_APP]: exports.createUserAppView, + [ViewName.USER_BY_EMAIL]: exports.createNewUserEmailView, + [ViewName.BY_API_KEY]: exports.createApiKeyView, + [ViewName.USER_BY_BUILDERS]: exports.createUserBuildersView, + [ViewName.USER_BY_APP]: exports.createUserAppView, } // can pass DB in if working with something specific if (!db) { diff --git a/packages/backend-core/src/index.ts b/packages/backend-core/src/index.ts index e585d4b6c3..6d2e8dcd10 100644 --- a/packages/backend-core/src/index.ts +++ b/packages/backend-core/src/index.ts @@ -1,4 +1,5 @@ import errors from "./errors" + const errorClasses = errors.errors import * as events from "./events" import * as migrations from "./migrations" diff --git a/packages/backend-core/src/middleware/authenticated.ts b/packages/backend-core/src/middleware/authenticated.ts index 3406b00812..b51ead46b9 100644 --- a/packages/backend-core/src/middleware/authenticated.ts +++ b/packages/backend-core/src/middleware/authenticated.ts @@ -4,7 +4,7 @@ import { getUser } from "../cache/user" import { getSession, updateSessionTTL } from "../security/sessions" import { buildMatcherRegex, matches } from "./matchers" import { SEPARATOR } from "../db/constants" -import { ViewNames } from "../db/utils" +import { ViewName } from "../db/utils" import { queryGlobalView } from "../db/views" import { getGlobalDB, doInTenant } from "../tenancy" import { decrypt } from "../security/encryption" @@ -43,7 +43,7 @@ async function checkApiKey(apiKey: string, populateUser?: Function) { const db = getGlobalDB() // api key is encrypted in the database const userId = await queryGlobalView( - ViewNames.BY_API_KEY, + ViewName.BY_API_KEY, { key: apiKey, }, diff --git a/packages/backend-core/src/migrations/migrations.ts b/packages/backend-core/src/migrations/migrations.ts index 2e4ef0da76..ca238ff80e 100644 --- a/packages/backend-core/src/migrations/migrations.ts +++ b/packages/backend-core/src/migrations/migrations.ts @@ -1,6 +1,6 @@ import { DEFAULT_TENANT_ID } from "../constants" import { doWithDB } from "../db" -import { DocumentTypes, StaticDatabases } from "../db/constants" +import { DocumentType, StaticDatabases } from "../db/constants" import { getAllApps } from "../db/utils" import environment from "../environment" import { @@ -21,10 +21,10 @@ import { export const getMigrationsDoc = async (db: any) => { // get the migrations doc try { - return await db.get(DocumentTypes.MIGRATIONS) + return await db.get(DocumentType.MIGRATIONS) } catch (err: any) { if (err.status && err.status === 404) { - return { _id: DocumentTypes.MIGRATIONS } + return { _id: DocumentType.MIGRATIONS } } else { console.error(err) throw err diff --git a/packages/backend-core/src/security/roles.js b/packages/backend-core/src/security/roles.js index 30869da68e..983aebf676 100644 --- a/packages/backend-core/src/security/roles.js +++ b/packages/backend-core/src/security/roles.js @@ -3,7 +3,7 @@ const { BUILTIN_PERMISSION_IDS, PermissionLevels } = require("./permissions") const { generateRoleID, getRoleParams, - DocumentTypes, + DocumentType, SEPARATOR, } = require("../db/utils") const { getAppDB } = require("../context") @@ -338,7 +338,7 @@ class AccessController { * Adds the "role_" for builtin role IDs which are to be written to the DB (for permissions). */ exports.getDBRoleID = roleId => { - if (roleId.startsWith(DocumentTypes.ROLE)) { + if (roleId.startsWith(DocumentType.ROLE)) { return roleId } return generateRoleID(roleId) @@ -349,8 +349,8 @@ exports.getDBRoleID = roleId => { */ exports.getExternalRoleID = roleId => { // for built in roles we want to remove the DB role ID element (role_) - if (roleId.startsWith(DocumentTypes.ROLE) && isBuiltin(roleId)) { - return roleId.split(`${DocumentTypes.ROLE}${SEPARATOR}`)[1] + if (roleId.startsWith(DocumentType.ROLE) && isBuiltin(roleId)) { + return roleId.split(`${DocumentType.ROLE}${SEPARATOR}`)[1] } return roleId } diff --git a/packages/backend-core/src/users.js b/packages/backend-core/src/users.js index 34d546a8bb..de5ce238c1 100644 --- a/packages/backend-core/src/users.js +++ b/packages/backend-core/src/users.js @@ -1,5 +1,5 @@ const { - ViewNames, + ViewName, getUsersByAppParams, getProdAppID, generateAppUserID, @@ -18,7 +18,7 @@ exports.getGlobalUserByEmail = async email => { throw "Must supply an email address to view" } - return await queryGlobalView(ViewNames.USER_BY_EMAIL, { + return await queryGlobalView(ViewName.USER_BY_EMAIL, { key: email.toLowerCase(), include_docs: true, }) @@ -32,7 +32,7 @@ exports.searchGlobalUsersByApp = async (appId, opts) => { include_docs: true, }) params.startkey = opts && opts.startkey ? opts.startkey : params.startkey - let response = await queryGlobalView(ViewNames.USER_BY_APP, params) + let response = await queryGlobalView(ViewName.USER_BY_APP, params) if (!response) { response = [] } @@ -56,7 +56,7 @@ exports.searchGlobalUsersByEmail = async (email, opts) => { const lcEmail = email.toLowerCase() // handle if passing up startkey for pagination const startkey = opts && opts.startkey ? opts.startkey : lcEmail - let response = await queryGlobalView(ViewNames.USER_BY_EMAIL, { + let response = await queryGlobalView(ViewName.USER_BY_EMAIL, { ...opts, startkey, endkey: `${lcEmail}${UNICODE_MAX}`, diff --git a/packages/backend-core/src/utils.js b/packages/backend-core/src/utils.js index 1e143968d9..0587267e9a 100644 --- a/packages/backend-core/src/utils.js +++ b/packages/backend-core/src/utils.js @@ -1,9 +1,4 @@ -const { - DocumentTypes, - SEPARATOR, - ViewNames, - getAllApps, -} = require("./db/utils") +const { DocumentType, SEPARATOR, ViewName, getAllApps } = require("./db/utils") const jwt = require("jsonwebtoken") const { options } = require("./middleware/passport/jwt") const { queryGlobalView } = require("./db/views") @@ -17,7 +12,7 @@ const { const events = require("./events") const tenancy = require("./tenancy") -const APP_PREFIX = DocumentTypes.APP + SEPARATOR +const APP_PREFIX = DocumentType.APP + SEPARATOR const PROD_APP_PREFIX = "/app/" function confirmAppId(possibleAppId) { @@ -154,7 +149,7 @@ exports.isClient = ctx => { } const getBuilders = async () => { - const builders = await queryGlobalView(ViewNames.USER_BY_BUILDERS, { + const builders = await queryGlobalView(ViewName.USER_BY_BUILDERS, { include_docs: false, }) diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 5762b8acd5..2483b8b662 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.2.28", + "version": "1.2.38", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "^1.2.1", - "@budibase/string-templates": "^1.2.28", + "@budibase/string-templates": "^1.2.38", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/builder/package.json b/packages/builder/package.json index 8c179e07fe..6c8d837a50 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.2.28", + "version": "1.2.38", "license": "GPL-3.0", "private": true, "scripts": { @@ -69,10 +69,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.2.28", - "@budibase/client": "^1.2.28", - "@budibase/frontend-core": "^1.2.28", - "@budibase/string-templates": "^1.2.28", + "@budibase/bbui": "^1.2.38", + "@budibase/client": "^1.2.38", + "@budibase/frontend-core": "^1.2.38", + "@budibase/string-templates": "^1.2.38", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 90e7ab661c..8016283094 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -79,7 +79,7 @@ automationStore.actions.addTestDataToAutomation({ body: { [key]: e.detail, - ...$automationStore.selectedAutomation.automation.testData.body, + ...$automationStore.selectedAutomation.automation.testData?.body, }, }) } diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExecuteQuery.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExecuteQuery.svelte index 462ee71cbe..6b9efa76d3 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExecuteQuery.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExecuteQuery.svelte @@ -3,6 +3,7 @@ import { datasources, integrations, queries } from "stores/backend" import BindingBuilder from "components/integration/QueryBindingBuilder.svelte" import IntegrationQueryEditor from "components/integration/index.svelte" + import { BUDIBASE_DATASOURCE_ID } from "constants/backend" export let parameters export let bindings = [] @@ -11,6 +12,10 @@ $: datasource = $datasources.list.find( ds => ds._id === parameters.datasourceId ) + // Executequery must exclude budibase datasource + $: executeQueryDatasources = $datasources.list.filter( + x => x._id !== BUDIBASE_DATASOURCE_ID + ) function fetchQueryDefinition(query) { const source = $datasources.list.find( @@ -24,7 +29,7 @@