diff --git a/hosting/kubernetes/budibase/templates/worker-service-deployment.yaml b/hosting/kubernetes/budibase/templates/worker-service-deployment.yaml
index 98a921a8a6..08b40d3b6b 100644
--- a/hosting/kubernetes/budibase/templates/worker-service-deployment.yaml
+++ b/hosting/kubernetes/budibase/templates/worker-service-deployment.yaml
@@ -89,6 +89,8 @@ spec:
value: {{ .Values.globals.selfHosted | quote }}
- name: ACCOUNT_PORTAL_URL
value: {{ .Values.globals.accountPortalUrl | quote }}
+ - name: ACCOUNT_PORTAL_API_KEY
+ value: {{ .Values.globals.accountPortalApiKey | quote }}
- name: COOKIE_DOMAIN
value: {{ .Values.globals.cookieDomain | quote }}
image: budibase/worker
diff --git a/hosting/kubernetes/budibase/values.yaml b/hosting/kubernetes/budibase/values.yaml
index c9b2549b30..5999f9c4bc 100644
--- a/hosting/kubernetes/budibase/values.yaml
+++ b/hosting/kubernetes/budibase/values.yaml
@@ -90,6 +90,7 @@ globals:
logLevel: info
selfHosted: 1
accountPortalUrL: ""
+ accountPortalApiKey: ""
cookieDomain: ""
createSecrets: true # creates an internal API key, JWT secrets and redis password for you
diff --git a/hosting/kubernetes/envoy/envoy.yaml b/hosting/kubernetes/envoy/envoy.yaml
index 4bf751b3a3..25a774dc7e 100644
--- a/hosting/kubernetes/envoy/envoy.yaml
+++ b/hosting/kubernetes/envoy/envoy.yaml
@@ -50,6 +50,11 @@ static_resources:
route:
cluster: app-service
+ - match: { path: "/api/deploy" }
+ route:
+ timeout: 60s
+ cluster: app-service
+
# special case for when API requests are made, can just forward, not to minio
- match: { prefix: "/api/" }
route:
diff --git a/lerna.json b/lerna.json
index 0a0da9c300..31acac22a6 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "0.9.148-alpha.7",
+ "version": "0.9.150-alpha.0",
"npmClient": "yarn",
"packages": [
"packages/*"
diff --git a/package.json b/package.json
index 3df577ca58..3596ec7800 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,8 @@
"multi:disable": "lerna run multi:disable",
"selfhost:enable": "lerna run selfhost:enable",
"selfhost:disable": "lerna run selfhost:disable",
+ "localdomain:enable": "lerna run localdomain:enable",
+ "localdomain:disable": "lerna run localdomain:disable",
"postinstall": "husky install"
}
}
diff --git a/packages/auth/package.json b/packages/auth/package.json
index b5acd8c467..e84b5a7029 100644
--- a/packages/auth/package.json
+++ b/packages/auth/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/auth",
- "version": "0.9.148-alpha.7",
+ "version": "0.9.150-alpha.0",
"description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js",
"author": "Budibase",
diff --git a/packages/auth/src/cloud/accounts.js b/packages/auth/src/cloud/accounts.js
index a102df8920..a02fe60926 100644
--- a/packages/auth/src/cloud/accounts.js
+++ b/packages/auth/src/cloud/accounts.js
@@ -1,16 +1,18 @@
const API = require("./api")
const env = require("../environment")
+const { Headers } = require("../constants")
const api = new API(env.ACCOUNT_PORTAL_URL)
-// TODO: Authorization
-
exports.getAccount = async email => {
const payload = {
email,
}
const response = await api.post(`/api/accounts/search`, {
body: payload,
+ headers: {
+ [Headers.API_KEY]: env.ACCOUNT_PORTAL_API_KEY,
+ },
})
const json = await response.json()
diff --git a/packages/auth/src/environment.js b/packages/auth/src/environment.js
index 7f822090d7..c36b469c4e 100644
--- a/packages/auth/src/environment.js
+++ b/packages/auth/src/environment.js
@@ -21,6 +21,7 @@ module.exports = {
INTERNAL_API_KEY: process.env.INTERNAL_API_KEY,
MULTI_TENANCY: process.env.MULTI_TENANCY,
ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL,
+ ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY,
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
SELF_HOSTED: !!parseInt(process.env.SELF_HOSTED),
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
diff --git a/packages/auth/src/middleware/matchers.js b/packages/auth/src/middleware/matchers.js
index a555823136..3d5065c069 100644
--- a/packages/auth/src/middleware/matchers.js
+++ b/packages/auth/src/middleware/matchers.js
@@ -7,6 +7,7 @@ exports.buildMatcherRegex = patterns => {
return patterns.map(pattern => {
const isObj = typeof pattern === "object" && pattern.route
const method = isObj ? pattern.method : "GET"
+ const strict = pattern.strict ? pattern.strict : false
let route = isObj ? pattern.route : pattern
const matches = route.match(PARAM_REGEX)
@@ -16,13 +17,19 @@ exports.buildMatcherRegex = patterns => {
route = route.replace(match, pattern)
}
}
- return { regex: new RegExp(route), method }
+ return { regex: new RegExp(route), method, strict, route }
})
}
exports.matches = (ctx, options) => {
- return options.find(({ regex, method }) => {
- const urlMatch = regex.test(ctx.request.url)
+ return options.find(({ regex, method, strict, route }) => {
+ let urlMatch
+ if (strict) {
+ urlMatch = ctx.request.url === route
+ } else {
+ urlMatch = regex.test(ctx.request.url)
+ }
+
const methodMatch =
method === "ALL"
? true
diff --git a/packages/bbui/package.json b/packages/bbui/package.json
index 53220fe02a..62e1c68278 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": "0.9.148-alpha.7",
+ "version": "0.9.150-alpha.0",
"license": "AGPL-3.0",
"svelte": "src/index.js",
"module": "dist/bbui.es.js",
diff --git a/packages/builder/package.json b/packages/builder/package.json
index deca819917..3cbf160cbf 100644
--- a/packages/builder/package.json
+++ b/packages/builder/package.json
@@ -1,6 +1,6 @@
{
"name": "@budibase/builder",
- "version": "0.9.148-alpha.7",
+ "version": "0.9.150-alpha.0",
"license": "AGPL-3.0",
"private": true,
"scripts": {
@@ -65,10 +65,10 @@
}
},
"dependencies": {
- "@budibase/bbui": "^0.9.148-alpha.7",
- "@budibase/client": "^0.9.148-alpha.7",
+ "@budibase/bbui": "^0.9.150-alpha.0",
+ "@budibase/client": "^0.9.150-alpha.0",
"@budibase/colorpicker": "1.1.2",
- "@budibase/string-templates": "^0.9.148-alpha.7",
+ "@budibase/string-templates": "^0.9.150-alpha.0",
"@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/Shared/WebhookDisplay.svelte b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte
index fc5e20f241..857640896c 100644
--- a/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte
+++ b/packages/builder/src/components/automation/Shared/WebhookDisplay.svelte
@@ -1,22 +1,14 @@
diff --git a/packages/builder/src/components/design/PropertiesPanel/ScreenSettingsSection.svelte b/packages/builder/src/components/design/PropertiesPanel/ScreenSettingsSection.svelte
index d782d1cd44..efe51ebdac 100644
--- a/packages/builder/src/components/design/PropertiesPanel/ScreenSettingsSection.svelte
+++ b/packages/builder/src/components/design/PropertiesPanel/ScreenSettingsSection.svelte
@@ -7,6 +7,7 @@
import RoleSelect from "./PropertyControls/RoleSelect.svelte"
import { currentAsset, store } from "builderStore"
import { FrontendTypes } from "constants"
+ import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
export let componentInstance
export let bindings
@@ -37,7 +38,12 @@
key: "routing.route",
label: "Route",
control: Input,
- parser: val => val.replace(/ +/g, "-"),
+ parser: val => {
+ if (!val.startsWith("/")) {
+ val = "/" + val
+ }
+ return sanitizeUrl(val)
+ },
},
{ key: "routing.roleId", label: "Access", control: RoleSelect },
{ key: "layoutId", label: "Layout", control: LayoutSelect },
diff --git a/packages/builder/src/components/upgrade/UpgradeModal.svelte b/packages/builder/src/components/upgrade/UpgradeModal.svelte
index 9ceef1ddf8..7571e6d773 100644
--- a/packages/builder/src/components/upgrade/UpgradeModal.svelte
+++ b/packages/builder/src/components/upgrade/UpgradeModal.svelte
@@ -1,10 +1,11 @@
@@ -25,8 +26,8 @@
confirmText="Self-host Budibase"
>
- Self-host Budibase for free, and get SSO, unlimited apps, and more - and
- it only takes a few minutes!
+ Self-host budibase for free to get unlimited apps and more - and it only
+ takes a few minutes!
diff --git a/packages/builder/src/pages/builder/_layout.svelte b/packages/builder/src/pages/builder/_layout.svelte
index 6cb78aa9da..625071c07e 100644
--- a/packages/builder/src/pages/builder/_layout.svelte
+++ b/packages/builder/src/pages/builder/_layout.svelte
@@ -14,16 +14,30 @@
$: useAccountPortal = cloud && !$admin.disableAccountPortal
const validateTenantId = async () => {
- // set the tenant from the url in the cloud
- const tenantId = window.location.host.split(".")[0]
+ const host = window.location.host
+ if (host.includes("localhost:")) {
+ // ignore local dev
+ return
+ }
- if (!tenantId.includes("localhost:")) {
- // user doesn't have permission to access this tenant - kick them out
- if (user && user.tenantId !== tenantId) {
- await auth.logout()
- await auth.setOrganisation(null)
+ if (user && user.tenantId) {
+ let urlTenantId
+ const hostParts = host.split(".")
+
+ // only run validation when we know we are in a tenant url
+ // not when we visit the root budibase.app domain
+ // e.g. ['tenant', 'budibase', 'app'] vs ['budibase', 'app']
+ if (hostParts.length > 2) {
+ urlTenantId = hostParts[0]
} else {
- await auth.setOrganisation(tenantId)
+ // no tenant in the url - send to account portal to fix this
+ window.location.href = $admin.accountPortalUrl
+ return
+ }
+
+ if (user.tenantId !== urlTenantId) {
+ // user should not be here - play it safe and log them out
+ await auth.logout()
}
}
}
@@ -32,7 +46,7 @@
await auth.checkAuth()
await admin.init()
- if (cloud && multiTenancyEnabled) {
+ if (useAccountPortal && multiTenancyEnabled) {
await validateTenantId()
}
diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte
index ae21a9dbb9..aaf948883d 100644
--- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte
@@ -92,7 +92,7 @@
- {#if $admin.cloud}
+ {#if $admin.cloud && $auth.user.account}
{/if}
diff --git a/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/CreateEditRelationship/CreateEditRelationship.svelte b/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/CreateEditRelationship/CreateEditRelationship.svelte
index fbc2b401ef..583ca5e887 100644
--- a/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/CreateEditRelationship/CreateEditRelationship.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/CreateEditRelationship/CreateEditRelationship.svelte
@@ -156,6 +156,8 @@
...relateTo,
through: through._id,
fieldName: fromTable.primary[0],
+ throughFrom: relateFrom.throughTo,
+ throughTo: relateFrom.throughFrom,
}
} else {
// the relateFrom.fieldName should remain the same, as it is the foreignKey in the other
@@ -251,6 +253,22 @@
bind:error={errors.through}
bind:value={fromRelationship.through}
/>
+ {#if fromTable && toTable && through}
+