Merge pull request #2842 from Budibase/develop

Develop -> master
This commit is contained in:
Martin McKeaveney 2021-10-01 16:32:32 +01:00 committed by GitHub
commit 2bebadcfb4
31 changed files with 249 additions and 936 deletions

View File

@ -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:

View File

@ -1,5 +1,5 @@
{
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"npmClient": "yarn",
"packages": [
"packages/*"

View File

@ -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"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@budibase/auth",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js",
"author": "Budibase",

View File

@ -1,7 +1,7 @@
{
"name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"license": "AGPL-3.0",
"svelte": "src/index.js",
"module": "dist/bbui.es.js",

View File

@ -90,6 +90,7 @@
on:input={onInput}
on:keyup={updateValueOnEnter}
{type}
inputmode={type === "number" ? "decimal" : "text"}
class="spectrum-Textfield-input"
/>
</div>

View File

@ -24,9 +24,7 @@ context("Create a Table", () => {
it("updates a column on the table", () => {
cy.get(".title").click()
cy.get(".spectrum-Table-editIcon > use").click()
cy.get("input")
.eq(1)
.type("updated", { force: true })
cy.get("input").eq(1).type("updated", { force: true })
// Unset table display column
cy.get(".spectrum-Switch-input").eq(1).click()
cy.contains("Save Column").click()
@ -45,9 +43,7 @@ context("Create a Table", () => {
it("deletes a row", () => {
cy.get(".spectrum-Checkbox-input").check({ force: true })
cy.contains("Delete 1 row(s)").click()
cy.get(".spectrum-Modal")
.contains("Delete")
.click()
cy.get(".spectrum-Modal").contains("Delete").click()
cy.contains("RoverUpdated").should("not.exist")
})
@ -56,15 +52,18 @@ context("Create a Table", () => {
cy.get(".spectrum-Table-editIcon > use").click()
cy.contains("Delete").click()
cy.wait(50)
cy.contains("Delete Column")
.click()
cy.contains("Delete Column").click()
cy.contains("nameupdated").should("not.exist")
})
it("deletes a table", () => {
cy.get(".actions > :nth-child(1) > .icon > .spectrum-Icon > use")
.eq(1)
.click({ force: true })
cy.get(".nav-item")
.contains("dog")
.parents(".nav-item")
.first()
.within(() => {
cy.get(".actions .spectrum-Icon").click({ force: true })
})
cy.get(".spectrum-Menu > :nth-child(2)").click()
cy.contains("Delete Table").click()
cy.contains("dog").should("not.exist")

View File

@ -28,11 +28,7 @@ context("Create a View", () => {
const headers = Array.from($headers).map(header =>
header.textContent.trim()
)
expect(removeSpacing(headers)).to.deep.eq([
"group",
"age",
"rating",
])
expect(removeSpacing(headers)).to.deep.eq(["group", "age", "rating"])
})
})
@ -57,11 +53,12 @@ context("Create a View", () => {
})
it("creates a stats calculation view based on age", () => {
cy.wait(1000)
cy.contains("Calculate").click()
cy.get(".modal-inner-wrapper").within(() => {
cy.get(".spectrum-Picker-label").eq(0).click()
cy.contains("Statistics").click()
cy.get(".spectrum-Picker-label").eq(1).click()
cy.contains("age").click({ force: true })
@ -104,20 +101,20 @@ context("Create a View", () => {
cy.get(".spectrum-Table-cell").then($values => {
let values = Array.from($values).map(header => header.textContent.trim())
expect(values).to.deep.eq([
"Students",
"70",
"20",
"25",
"3",
"1650",
"23.333333333333332",
"Teachers",
"85",
"36",
"49",
"2",
"3697",
"42.5",
"Students",
"70",
"20",
"25",
"3",
"1650",
"23.333333333333332",
"Teachers",
"85",
"36",
"49",
"2",
"3697",
"42.5",
])
})
})

View File

@ -1,6 +1,6 @@
{
"name": "@budibase/builder",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"license": "AGPL-3.0",
"private": true,
"scripts": {
@ -65,10 +65,10 @@
}
},
"dependencies": {
"@budibase/bbui": "^0.9.148",
"@budibase/client": "^0.9.148",
"@budibase/bbui": "^0.9.149-alpha.3",
"@budibase/client": "^0.9.149-alpha.3",
"@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^0.9.148",
"@budibase/string-templates": "^0.9.149-alpha.3",
"@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1",

View File

@ -1,12 +1,12 @@
import { cloneDeep } from "lodash/fp"
import { get } from "svelte/store"
import {
findAllMatchingComponents,
findComponent,
findComponentPath,
findAllMatchingComponents,
} from "./storeUtils"
import { store } from "builderStore"
import { tables as tablesStore, queries as queriesStores } from "stores/backend"
import { queries as queriesStores, tables as tablesStore } from "stores/backend"
import { makePropSafe } from "@budibase/string-templates"
import { TableNames } from "../constants"
@ -422,6 +422,10 @@ function shouldReplaceBinding(currentValue, from, convertTo) {
return !invalids.find(invalid => noSpaces?.includes(invalid))
}
function replaceBetween(string, start, end, replacement) {
return string.substring(0, start) + replacement + string.substring(end)
}
/**
* utility function for the readableToRuntimeBinding and runtimeToReadableBinding.
*/
@ -431,6 +435,7 @@ function bindingReplacement(bindableProperties, textWithBindings, convertTo) {
if (typeof textWithBindings !== "string") {
return textWithBindings
}
// work from longest to shortest
const convertFromProps = bindableProperties
.map(el => el[convertFrom])
.sort((a, b) => {
@ -440,12 +445,29 @@ function bindingReplacement(bindableProperties, textWithBindings, convertTo) {
let result = textWithBindings
for (let boundValue of boundValues) {
let newBoundValue = boundValue
// we use a search string, where any time we replace something we blank it out
// in the search, working from longest to shortest so always use best match first
let searchString = newBoundValue
for (let from of convertFromProps) {
if (shouldReplaceBinding(newBoundValue, from, convertTo)) {
const binding = bindableProperties.find(el => el[convertFrom] === from)
while (newBoundValue.includes(from)) {
newBoundValue = newBoundValue.replace(from, binding[convertTo])
}
let idx
do {
// see if any instances of this binding exist in the search string
idx = searchString.indexOf(from)
if (idx !== -1) {
let end = idx + from.length,
searchReplace = Array(binding[convertTo].length).join("*")
// blank out parts of the search string
searchString = replaceBetween(searchString, idx, end, searchReplace)
newBoundValue = replaceBetween(
newBoundValue,
idx,
end,
binding[convertTo]
)
}
} while (idx !== -1)
}
}
result = result.replace(boundValue, newBoundValue)

View File

@ -1,21 +1,10 @@
<script>
import { onMount, onDestroy } from "svelte"
import { Button, Modal, notifications, ModalContent } from "@budibase/bbui"
import api from "builderStore/api"
import analytics, { Events } from "analytics"
import { store } from "builderStore"
const DeploymentStatus = {
SUCCESS: "SUCCESS",
PENDING: "PENDING",
FAILURE: "FAILURE",
}
const POLL_INTERVAL = 10000
let feedbackModal
let deployments = []
let poll
let publishModal
async function deployApp() {
@ -34,62 +23,6 @@
notifications.error(`Error publishing app: ${err}`)
}
}
async function fetchDeployments() {
try {
const response = await api.get(`/api/deployments`)
const json = await response.json()
if (deployments.length > 0) {
checkIncomingDeploymentStatus(deployments, json)
}
deployments = json
} catch (err) {
console.error(err)
clearInterval(poll)
notifications.error(
"Error fetching deployment history. Please try again."
)
}
}
// Required to check any updated deployment statuses between polls
function checkIncomingDeploymentStatus(current, incoming) {
for (let incomingDeployment of incoming) {
if (
incomingDeployment.status === DeploymentStatus.FAILURE ||
incomingDeployment.status === DeploymentStatus.SUCCESS
) {
const currentDeployment = current.find(
deployment => deployment._id === incomingDeployment._id
)
// We have just been notified of an ongoing deployments status change
if (
!currentDeployment ||
currentDeployment.status === DeploymentStatus.PENDING
) {
if (incomingDeployment.status === DeploymentStatus.FAILURE) {
notifications.error(incomingDeployment.err)
} else {
notifications.send(
"Published to Production.",
"success",
"CheckmarkCircle"
)
}
}
}
}
}
onMount(() => {
fetchDeployments()
poll = setInterval(fetchDeployments, POLL_INTERVAL)
})
onDestroy(() => clearInterval(poll))
</script>
<Button secondary on:click={publishModal.show}>Publish</Button>

View File

@ -62,7 +62,7 @@
<Modal bind:this={modal}>
<ModalContent
showConfirmButton={false}
cancelText="Close"
cancelText="View changes"
showCloseIcon={false}
title="Theme settings"
>

View File

@ -21,12 +21,12 @@
<ModalContent
size="M"
{onConfirm}
title="Upgrade to self-hosted"
confirmText="Upgrade"
title="Self-host Budibase"
confirmText="Self-host Budibase"
>
<span
>Upgrade to Budibase self-hosting for free, and get SSO, unlimited apps,
and more - and it only takes a few minutes!</span
>Self-host budibase for free, and get SSO, unlimited apps, and more - and
it only takes a few minutes!</span
>
</ModalContent>
</Modal>

View File

@ -4,9 +4,6 @@
import { onMount } from "svelte"
let loaded = false
// don't react to these
let cloud = $admin.cloud
let shouldRedirect = !cloud || $admin.disableAccountPortal
$: multiTenancyEnabled = $admin.multiTenancy
$: hasAdminUser = $admin?.checklist?.adminUser?.checked
@ -14,17 +11,33 @@
$: cloud = $admin.cloud
$: user = $auth.user
const validateTenantId = async () => {
// set the tenant from the url in the cloud
const tenantId = window.location.host.split(".")[0]
$: useAccountPortal = cloud && !$admin.disableAccountPortal
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)
const validateTenantId = async () => {
const host = window.location.host
if (host.includes("localhost:")) {
// ignore local dev
return
}
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()
}
}
}
@ -33,7 +46,7 @@
await auth.checkAuth()
await admin.init()
if (cloud && multiTenancyEnabled) {
if (useAccountPortal && multiTenancyEnabled) {
await validateTenantId()
}
@ -41,12 +54,11 @@
})
$: {
// We should never see the org or admin user creation screens in the cloud
const apiReady = $admin.loaded && $auth.loaded
// if tenant is not set go to it
if (
loaded &&
shouldRedirect &&
!useAccountPortal &&
apiReady &&
multiTenancyEnabled &&
!tenantSet
@ -54,7 +66,7 @@
$redirect("./auth/org")
}
// Force creation of an admin user if one doesn't exist
else if (loaded && shouldRedirect && apiReady && !hasAdminUser) {
else if (loaded && !useAccountPortal && apiReady && !hasAdminUser) {
$redirect("./admin")
}
// Redirect to log in at any time if the user isn't authenticated

View File

@ -5,8 +5,11 @@
let loaded = false
$: cloud = $admin.cloud
$: useAccountPortal = cloud && !$admin.disableAccountPortal
onMount(() => {
if ($admin?.checklist?.adminUser.checked) {
if ($admin?.checklist?.adminUser.checked || useAccountPortal) {
$redirect("../")
} else {
loaded = true

View File

@ -9,7 +9,8 @@
let tenantId = get(auth).tenantSet ? get(auth).tenantId : ""
$: multiTenancyEnabled = $admin.multiTenancy
$: cloud = $admin.cloud
$: disableAccountPortal = $admin.disableAccountPortal
$: useAccountPortal = cloud && !$admin.disableAccountPortal
async function setOrg() {
if (tenantId == null || tenantId === "") {
@ -27,7 +28,7 @@
onMount(async () => {
await auth.checkQueryString()
if (!multiTenancyEnabled || (cloud && !disableAccountPortal)) {
if (!multiTenancyEnabled || useAccountPortal) {
$goto("../")
} else {
admin.unload()

View File

@ -216,6 +216,7 @@
<div class="filter">
<div class="select">
<Select
autoWidth
bind:value={sortBy}
placeholder={null}
options={[
@ -224,7 +225,9 @@
{ label: "Sort by status", value: "status" },
]}
/>
<Search placeholder="Search" bind:value={searchTerm} />
<div class="desktop-search">
<Search placeholder="Search" bind:value={searchTerm} />
</div>
</div>
<ActionGroup>
<ActionButton
@ -241,6 +244,9 @@
/>
</ActionGroup>
</div>
<div class="mobile-search">
<Search placeholder="Search" bind:value={searchTerm} />
</div>
<div
class:appGrid={layout === "grid"}
class:appTable={layout === "table"}
@ -318,6 +324,7 @@
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 10px;
}
.select {
@ -325,6 +332,12 @@
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
.filter :global(.spectrum-ActionGroup) {
flex-wrap: nowrap;
}
.mobile-search {
display: none;
}
.appGrid {
display: grid;
@ -364,5 +377,11 @@
.appTable {
grid-template-columns: 1fr auto;
}
.desktop-search {
display: none;
}
.mobile-search {
display: block;
}
}
</style>

View File

@ -1,6 +1,6 @@
{
"name": "@budibase/cli",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"description": "Budibase CLI, for developers, self hosting and migrations.",
"main": "src/index.js",
"bin": {

View File

@ -1,6 +1,6 @@
{
"name": "@budibase/client",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"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": "^0.9.148",
"@budibase/bbui": "^0.9.149-alpha.3",
"@budibase/standard-components": "^0.9.139",
"@budibase/string-templates": "^0.9.148",
"@budibase/string-templates": "^0.9.149-alpha.3",
"regexparam": "^1.3.0",
"shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5"

View File

@ -1,7 +1,7 @@
{
"name": "@budibase/server",
"email": "hi@budibase.com",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"description": "Budibase Web Server",
"main": "src/index.js",
"repository": {
@ -64,9 +64,9 @@
"author": "Budibase",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@budibase/auth": "^0.9.148",
"@budibase/client": "^0.9.148",
"@budibase/string-templates": "^0.9.148",
"@budibase/auth": "^0.9.149-alpha.3",
"@budibase/client": "^0.9.149-alpha.3",
"@budibase/string-templates": "^0.9.149-alpha.3",
"@elastic/elasticsearch": "7.10.0",
"@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1",

View File

@ -7,14 +7,19 @@ if (env.POSTHOG_TOKEN && env.ENABLE_ANALYTICS && !env.SELF_HOSTED) {
posthogClient = new PostHog(env.POSTHOG_TOKEN)
}
exports.isEnabled = async function (ctx) {
exports.isEnabled = async ctx => {
ctx.body = {
enabled: !env.SELF_HOSTED && env.ENABLE_ANALYTICS === "true",
}
}
exports.endUserPing = async (ctx, next) => {
if (!posthogClient) return next()
exports.endUserPing = async ctx => {
if (!posthogClient) {
ctx.body = {
ping: false,
}
return
}
posthogClient.capture("budibase:end_user_ping", {
userId: ctx.user && ctx.user._id,

View File

@ -64,6 +64,7 @@ async function storeDeploymentHistory(deployment) {
async function initDeployedApp(prodAppId) {
const db = new CouchDB(prodAppId)
console.log("Reading automation docs")
const automations = (
await db.allDocs(
getAutomationParams(null, {
@ -71,12 +72,17 @@ async function initDeployedApp(prodAppId) {
})
)
).rows.map(row => row.doc)
console.log("You have " + automations.length + " automations")
const promises = []
console.log("Disabling prod crons..")
await disableAllCrons(prodAppId)
console.log("Prod Cron triggers disabled..")
console.log("Enabling cron triggers for deployed app..")
for (let automation of automations) {
promises.push(enableCronTrigger(prodAppId, automation))
}
await Promise.all(promises)
console.log("Enabled cron triggers for deployed app..")
}
async function deployApp(deployment) {
@ -88,13 +94,18 @@ async function deployApp(deployment) {
target: productionAppId,
})
console.log("Replication object created")
await replication.replicate()
console.log("replication complete.. replacing app meta doc")
const db = new CouchDB(productionAppId)
const appDoc = await db.get(DocumentTypes.APP_METADATA)
appDoc.appId = productionAppId
appDoc.instance._id = productionAppId
await db.put(appDoc)
console.log("New app doc written successfully.")
console.log("Setting up live repl between dev and prod")
// Set up live sync between the live and dev instances
const liveReplication = new Replication({
source: productionAppId,
@ -105,8 +116,11 @@ async function deployApp(deployment) {
return doc._id !== DocumentTypes.APP_METADATA
},
})
console.log("Set up live repl between dev and prod")
console.log("Initialising deployed app")
await initDeployedApp(productionAppId)
console.log("Init complete, setting deployment to successful")
deployment.setStatus(DeploymentStatus.SUCCESS)
await storeDeploymentHistory(deployment)
} catch (err) {
@ -153,9 +167,13 @@ exports.deploymentProgress = async function (ctx) {
exports.deployApp = async function (ctx) {
let deployment = new Deployment(ctx.appId)
console.log("Deployment object created")
deployment.setStatus(DeploymentStatus.PENDING)
console.log("Deployment object set to pending")
deployment = await storeDeploymentHistory(deployment)
console.log("Stored deployment history")
console.log("Deploying app...")
await deployApp(deployment)
ctx.body = deployment

View File

@ -403,16 +403,32 @@ exports.fetchEnrichedRow = async ctx => {
rowId,
})
// look up the actual rows based on the ids
const response = await db.allDocs({
include_docs: true,
keys: linkVals.map(linkVal => linkVal.id),
})
// need to include the IDs in these rows for any links they may have
let linkedRows = await outputProcessing(
ctx,
table,
response.rows.map(row => row.doc)
)
let response = (
await db.allDocs({
include_docs: true,
keys: linkVals.map(linkVal => linkVal.id),
})
).rows.map(row => row.doc)
// group responses by table
let groups = {},
tables = {}
for (let row of response) {
const linkedTableId = row.tableId
if (groups[linkedTableId] == null) {
groups[linkedTableId] = [row]
tables[linkedTableId] = await db.get(linkedTableId)
} else {
groups[linkedTableId].push(row)
}
}
let linkedRows = []
for (let [tableId, rows] of Object.entries(groups)) {
// need to include the IDs in these rows for any links they may have
linkedRows = linkedRows.concat(
await outputProcessing(ctx, tables[tableId], rows)
)
}
// insert the link rows in the correct place throughout the main row
for (let fieldName of Object.keys(table.schema)) {
let field = table.schema[fieldName]

View File

@ -3,7 +3,8 @@ const controller = require("../controllers/analytics")
const router = Router()
router.get("/api/analytics", controller.isEnabled)
router.post("/api/analytics/ping", controller.endUserPing)
router
.get("/api/analytics", controller.isEnabled)
.post("/api/analytics/ping", controller.endUserPing)
module.exports = router

View File

@ -99,6 +99,7 @@ function processAutoColumn(
row,
opts = { reprocessing: false, noAutoRelationships: false }
) {
let noUser = !user || !user.userId
let now = new Date().toISOString()
// if a row doesn't have a revision then it doesn't exist yet
const creating = !row._rev
@ -108,7 +109,12 @@ function processAutoColumn(
}
switch (schema.subtype) {
case AutoFieldSubTypes.CREATED_BY:
if (creating && !opts.reprocessing && !opts.noAutoRelationships) {
if (
creating &&
!opts.reprocessing &&
!opts.noAutoRelationships &&
!noUser
) {
row[key] = [user.userId]
}
break
@ -118,7 +124,7 @@ function processAutoColumn(
}
break
case AutoFieldSubTypes.UPDATED_BY:
if (!opts.reprocessing && !opts.noAutoRelationships) {
if (!opts.reprocessing && !opts.noAutoRelationships && !noUser) {
row[key] = [user.userId]
}
break

View File

@ -52,7 +52,8 @@ exports.sendSmtpEmail = async (to, from, subject, contents, automation) => {
)
if (response.status !== 200) {
throw "Unable to send email."
const error = await response.text()
throw `Unable to send email - ${error}`
}
return response.json()
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "@budibase/string-templates",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs",
"module": "dist/bundle.mjs",

View File

@ -1,7 +1,7 @@
{
"name": "@budibase/worker",
"email": "hi@budibase.com",
"version": "0.9.148",
"version": "0.9.149-alpha.3",
"description": "Budibase background service",
"main": "src/index.js",
"repository": {
@ -20,13 +20,15 @@
"multi:enable": "node scripts/multiTenancy.js enable",
"multi:disable": "node scripts/multiTenancy.js disable",
"selfhost:enable": "node scripts/selfhost.js enable",
"selfhost:disable": "node scripts/selfhost.js disable"
"selfhost:disable": "node scripts/selfhost.js disable",
"localdomain:enable": "node scripts/localdomain.js enable",
"localdomain:disable": "node scripts/localdomain.js disable"
},
"author": "Budibase",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@budibase/auth": "^0.9.148",
"@budibase/string-templates": "^0.9.148",
"@budibase/auth": "^0.9.149-alpha.3",
"@budibase/string-templates": "^0.9.149-alpha.3",
"@koa/router": "^8.0.0",
"@techpass/passport-openidconnect": "^0.3.0",
"aws-sdk": "^2.811.0",

View File

@ -0,0 +1,22 @@
#!/usr/bin/env node
const updateDotEnv = require("update-dotenv")
const arg = process.argv.slice(2)[0]
/**
* For testing multi tenancy sub domains locally.
*
* Relies on an entry in /etc/hosts e.g:
*
* 127.0.0.1 local.com
*
* and an entry for each tenant you wish to test locally e.g:
*
* 127.0.0.1 t1.local.com
* 127.0.0.1 t2.local.com
*/
updateDotEnv({
ACCOUNT_PORTAL_URL:
arg === "enable" ? "http://local.com:10001" : "http://localhost:10001",
COOKIE_DOMAIN: arg === "enable" ? ".local.com" : "",
}).then(() => console.log("Updated worker!"))

View File

@ -87,7 +87,7 @@ router
if (ctx.publicEndpoint) {
return next()
}
if (!ctx.isAuthenticated || !ctx.user.budibaseAccess) {
if ((!ctx.isAuthenticated || !ctx.user.budibaseAccess) && !ctx.internal) {
ctx.throw(403, "Unauthorized - no public worker access")
}
return next()