Merge branch 'master' into fixes/user-management

This commit is contained in:
Keviin Åberg Kultalahti 2021-05-21 13:32:55 +02:00
commit a4de6d49c8
39 changed files with 161 additions and 234 deletions

View File

@ -4,10 +4,6 @@ on:
push: push:
branches: branches:
- master - master
pull_request:
branches:
- master
jobs: jobs:
release: release:
@ -36,6 +32,7 @@ jobs:
- name: Build/release Docker images - name: Build/release Docker images
run: | run: |
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
yarn build
yarn build:docker yarn build:docker
env: env:
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}

View File

@ -5,8 +5,7 @@ version: "3"
services: services:
app-service: app-service:
restart: always restart: always
#build: ./build/server image: budibase/apps
image: budibase/budibase-apps
ports: ports:
- "${APP_PORT}:4002" - "${APP_PORT}:4002"
environment: environment:
@ -30,8 +29,7 @@ services:
worker-service: worker-service:
restart: always restart: always
#build: ./build/worker image: budibase/worker
image: budibase/budibase-worker
ports: ports:
- "${WORKER_PORT}:4003" - "${WORKER_PORT}:4003"
environment: environment:

View File

@ -21,15 +21,27 @@ static_resources:
cluster: app-service cluster: app-service
prefix_rewrite: "/" prefix_rewrite: "/"
- match: { path: "/" } - match: { prefix: "/builder/" }
route:
cluster: app-service
- match: { prefix: "/builder" }
route:
cluster: app-service
- match: { prefix: "/app_" }
route: route:
cluster: app-service cluster: app-service
# special case for worker admin API # special case for worker admin API
- match: { path: "/api/admin" } - match: { prefix: "/api/admin/" }
route: route:
cluster: worker-service cluster: worker-service
- match: { path: "/" }
route:
cluster: app-service
# special case for when API requests are made, can just forward, not to minio # special case for when API requests are made, can just forward, not to minio
- match: { prefix: "/api/" } - match: { prefix: "/api/" }
route: route:

View File

@ -3,20 +3,14 @@
tag=$1 tag=$1
tag=${tag:-latest} tag=${tag:-latest}
pushd ../../build
docker-compose build --force app-service
docker-compose build --force worker-service
echo "Tagging images with SHA: $GITHUB_SHA and version: $BUDIBASE_VERSION" echo "Tagging images with SHA: $GITHUB_SHA and version: $BUDIBASE_VERSION"
docker tag build_app-service budibase/apps:$tag docker tag app-service budibase/apps:$tag
docker tag build_worker-service budibase/worker:$tag docker tag worker-service budibase/worker:$tag
# Tag with git sha # Tag with git sha
docker tag build_app-service budibase/apps:$GITHUB_SHA docker tag app-service budibase/apps:$GITHUB_SHA
docker tag build_worker-service budibase/worker:$GITHUB_SHA docker tag worker-service budibase/worker:$GITHUB_SHA
docker push budibase/apps docker push budibase/apps
docker push budibase/worker docker push budibase/worker
popd

View File

@ -1,5 +1,5 @@
{ {
"version": "0.8.18", "version": "0.9.1",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@ -38,7 +38,7 @@
"format": "prettier --write \"{,!(node_modules)/**/}*.{js,jsx,svelte}\"", "format": "prettier --write \"{,!(node_modules)/**/}*.{js,jsx,svelte}\"",
"test:e2e": "lerna run cy:test", "test:e2e": "lerna run cy:test",
"test:e2e:ci": "lerna run cy:ci", "test:e2e:ci": "lerna run cy:ci",
"build:docker": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh && cd -", "build:docker": "lerna run build:docker && cd hosting/scripts/linux/ && ./release-to-docker-hub.sh && cd -",
"build:docker:staging": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh staging && cd -" "build:docker:staging": "cd hosting/scripts/linux/ && ./release-to-docker-hub.sh staging && cd -"
}, },
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/auth", "name": "@budibase/auth",
"version": "0.18.6", "version": "0.9.1",
"description": "Authentication middlewares for budibase builder and apps", "description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js", "main": "src/index.js",
"author": "Budibase", "author": "Budibase",
@ -24,5 +24,6 @@
}, },
"devDependencies": { "devDependencies": {
"ioredis-mock": "^5.5.5" "ioredis-mock": "^5.5.5"
} },
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/bbui", "name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.", "description": "A UI solution used in the different Budibase projects.",
"version": "1.58.13", "version": "0.9.1",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"svelte": "src/index.js", "svelte": "src/index.js",
"module": "dist/bbui.es.js", "module": "dist/bbui.es.js",
@ -77,5 +77,6 @@
"dayjs": "^1.10.4", "dayjs": "^1.10.4",
"svelte-flatpickr": "^3.1.0", "svelte-flatpickr": "^3.1.0",
"svelte-portal": "^1.0.0" "svelte-portal": "^1.0.0"
} },
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
} }

View File

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

View File

@ -1,40 +0,0 @@
<script>
import { Label } from "@budibase/bbui"
import { getBindableProperties } from "builderStore/dataBinding"
import { currentAsset, store } from "builderStore"
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
export let parameters
let bindingDrawer
$: bindings = getBindableProperties($currentAsset, $store.selectedComponentId)
</script>
<div class="root">
<Label small>Email</Label>
<DrawerBindableInput
title="Email"
value={parameters.email}
on:change={value => (parameters.email = value.detail)}
{bindings}
/>
<Label small>Password</Label>
<DrawerBindableInput
title="Password"
value={parameters.password}
on:change={value => (parameters.password = value.detail)}
{bindings}
/>
</div>
<style>
.root {
display: grid;
column-gap: var(--spacing-l);
row-gap: var(--spacing-s);
grid-template-columns: auto 1fr;
align-items: baseline;
max-width: 800px;
margin: 0 auto;
}
</style>

View File

@ -1,14 +0,0 @@
<script>
import { Body } from "@budibase/bbui"
</script>
<div class="root">
<Body size="S">This action doesn't require any additional settings.</Body>
</div>
<style>
.root {
max-width: 800px;
margin: 0 auto;
}
</style>

View File

@ -4,8 +4,6 @@ import DeleteRow from "./DeleteRow.svelte"
import ExecuteQuery from "./ExecuteQuery.svelte" import ExecuteQuery from "./ExecuteQuery.svelte"
import TriggerAutomation from "./TriggerAutomation.svelte" import TriggerAutomation from "./TriggerAutomation.svelte"
import ValidateForm from "./ValidateForm.svelte" import ValidateForm from "./ValidateForm.svelte"
import LogIn from "./LogIn.svelte"
import LogOut from "./LogOut.svelte"
// defines what actions are available, when adding a new one // defines what actions are available, when adding a new one
// the component is the setup panel for the action // the component is the setup panel for the action
@ -37,12 +35,4 @@ export default [
name: "Validate Form", name: "Validate Form",
component: ValidateForm, component: ValidateForm,
}, },
{
name: "Log In",
component: LogIn,
},
{
name: "Log Out",
component: LogOut,
},
] ]

View File

@ -28,7 +28,8 @@
!$isActive("./auth") && !$isActive("./auth") &&
!$isActive("./invite") !$isActive("./invite")
) { ) {
$redirect("./auth/login") const returnUrl = encodeURIComponent(window.location.pathname)
$redirect("./auth/login?", { returnUrl })
} else if ($auth?.user?.forceResetPassword) { } else if ($auth?.user?.forceResetPassword) {
$redirect("./auth/reset") $redirect("./auth/reset")
} }

View File

@ -0,0 +1,18 @@
<script>
import { auth } from "stores/portal"
import { onMount } from "svelte"
import { redirect } from "@roxi/routify"
// If already authenticated, redirect away from the auth section.
// Check this onMount rather than a reactive statement to avoid trumping
// the login return URL functionality.
onMount(() => {
if ($auth.user) {
$redirect("../")
}
})
</script>
{#if !$auth.user}
<slot />
{/if}

View File

@ -37,12 +37,14 @@
onMount(async () => { onMount(async () => {
// Prevent non-builders from accessing the portal // Prevent non-builders from accessing the portal
if ($auth.user) {
if (!$auth.user?.builder?.global) { if (!$auth.user?.builder?.global) {
$redirect("../") $redirect("../")
} else { } else {
await organisation.init() await organisation.init()
loaded = true loaded = true
} }
}
}) })
</script> </script>

View File

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

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/client", "name": "@budibase/client",
"version": "0.8.18", "version": "0.9.1",
"license": "MPL-2.0", "license": "MPL-2.0",
"module": "dist/budibase-client.js", "module": "dist/budibase-client.js",
"main": "dist/budibase-client.js", "main": "dist/budibase-client.js",
@ -18,15 +18,15 @@
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/string-templates": "^0.8.18", "@budibase/string-templates": "^0.9.1",
"regexparam": "^1.3.0", "regexparam": "^1.3.0",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5" "svelte-spa-router": "^3.0.5"
}, },
"devDependencies": { "devDependencies": {
"@budibase/standard-components": "^0.9.1",
"@rollup/plugin-commonjs": "^18.0.0", "@rollup/plugin-commonjs": "^18.0.0",
"@rollup/plugin-node-resolve": "^11.2.1", "@rollup/plugin-node-resolve": "^11.2.1",
"@budibase/standard-components": "^0.8.18",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"jsdom": "^16.0.1", "jsdom": "^16.0.1",
"postcss": "^8.2.9", "postcss": "^8.2.9",
@ -40,5 +40,5 @@
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"svelte": "^3.38.2" "svelte": "^3.38.2"
}, },
"gitHead": "4b6efc42ed3273595c7a129411f4d883733d3321" "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
} }

View File

@ -10,6 +10,8 @@
initialise, initialise,
screenStore, screenStore,
authStore, authStore,
routeStore,
builderStore,
} from "../store" } from "../store"
import { TableNames, ActionTypes } from "../constants" import { TableNames, ActionTypes } from "../constants"
@ -18,13 +20,13 @@
setContext("component", writable({})) setContext("component", writable({}))
setContext("context", createContextStore()) setContext("context", createContextStore())
let loaded = false let dataLoaded = false
// Load app config // Load app config
onMount(async () => { onMount(async () => {
await initialise() await initialise()
await authStore.actions.fetchUser() await authStore.actions.fetchUser()
loaded = true dataLoaded = true
}) })
// Register this as a refreshable datasource so that user changes cause // Register this as a refreshable datasource so that user changes cause
@ -36,9 +38,22 @@
metadata: { dataSource: { type: "table", tableId: TableNames.USERS } }, metadata: { dataSource: { type: "table", tableId: TableNames.USERS } },
}, },
] ]
// Redirect to home layout if no matching route
$: {
if (dataLoaded && $routeStore.routerLoaded && !$routeStore.activeRoute) {
if ($authStore) {
routeStore.actions.navigate("/")
} else {
const returnUrl = `${window.location.pathname}${window.location.hash}`
const encodedUrl = encodeURIComponent(returnUrl)
window.location = `/builder/auth/login?returnUrl=${encodedUrl}`
}
}
}
</script> </script>
{#if loaded && $screenStore.activeLayout} {#if dataLoaded && $screenStore.activeLayout}
<div lang="en" dir="ltr" class="spectrum spectrum--medium spectrum--light"> <div lang="en" dir="ltr" class="spectrum spectrum--medium spectrum--light">
<Provider key="user" data={$authStore} {actions}> <Provider key="user" data={$authStore} {actions}>
<Component definition={$screenStore.activeLayout.props} /> <Component definition={$screenStore.activeLayout.props} />

View File

@ -3,6 +3,7 @@
import Router from "svelte-spa-router" import Router from "svelte-spa-router"
import { routeStore } from "../store" import { routeStore } from "../store"
import Screen from "./Screen.svelte" import Screen from "./Screen.svelte"
import { onMount } from "svelte"
const { styleable } = getContext("sdk") const { styleable } = getContext("sdk")
const component = getContext("component") const component = getContext("component")

View File

@ -1,8 +1,8 @@
<script> <script>
import { fade } from "svelte/transition"
import { screenStore, routeStore } from "../store" import { screenStore, routeStore } from "../store"
import Component from "./Component.svelte" import Component from "./Component.svelte"
import Provider from "./Provider.svelte" import Provider from "./Provider.svelte"
import { onMount } from "svelte"
// Keep route params up to date // Keep route params up to date
export let params = {} export let params = {}
@ -11,8 +11,12 @@
// Get the screen definition for the current route // Get the screen definition for the current route
$: screenDefinition = $screenStore.activeScreen?.props $: screenDefinition = $screenStore.activeScreen?.props
// Redirect to home layout if no matching route // Mark the router as loaded whenever the screen mounts
$: screenDefinition == null && routeStore.actions.navigate("/") onMount(() => {
if (!$routeStore.routerLoaded) {
routeStore.actions.setRouterLoaded()
}
})
</script> </script>
<!-- Ensure to fully remount when screen changes --> <!-- Ensure to fully remount when screen changes -->

View File

@ -8,6 +8,7 @@ const createRouteStore = () => {
routeParams: {}, routeParams: {},
activeRoute: null, activeRoute: null,
routeSessionId: Math.random(), routeSessionId: Math.random(),
routerLoaded: false,
} }
const store = writable(initialState) const store = writable(initialState)
@ -47,10 +48,19 @@ const createRouteStore = () => {
}) })
} }
const navigate = push const navigate = push
const setRouterLoaded = () => {
store.update(state => ({ ...state, routerLoaded: true }))
}
return { return {
subscribe: store.subscribe, subscribe: store.subscribe,
actions: { fetchRoutes, navigate, setRouteParams, setActiveRoute }, actions: {
fetchRoutes,
navigate,
setRouteParams,
setActiveRoute,
setRouterLoaded,
},
} }
} }

View File

@ -18,12 +18,11 @@ const createScreenStore = () => {
activeLayout = $builderStore.layout activeLayout = $builderStore.layout
activeScreen = $builderStore.screen activeScreen = $builderStore.screen
} else { } else {
// Otherwise find the correct screen by matching the current route activeLayout = { props: { _component: "screenslot" } }
// Find the correct screen by matching the current route
const { screens, layouts } = $config const { screens, layouts } = $config
activeLayout = layouts[0] if ($routeStore.activeRoute) {
if (screens.length === 1) {
activeScreen = screens[0]
} else if ($routeStore.activeRoute) {
activeScreen = screens.find( activeScreen = screens.find(
screen => screen._id === $routeStore.activeRoute.screenId screen => screen._id === $routeStore.activeRoute.screenId
) )

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/server", "name": "@budibase/server",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.8.18", "version": "0.9.1",
"description": "Budibase Web Server", "description": "Budibase Web Server",
"main": "src/electron.js", "main": "src/electron.js",
"repository": { "repository": {
@ -35,6 +35,7 @@
"test": "jest --testPathIgnorePatterns=routes && yarn run test:integration", "test": "jest --testPathIgnorePatterns=routes && yarn run test:integration",
"test:integration": "jest --coverage --detectOpenHandles", "test:integration": "jest --coverage --detectOpenHandles",
"test:watch": "jest --watch", "test:watch": "jest --watch",
"build:docker": "docker build . -t app-service",
"run:docker": "node src/index", "run:docker": "node src/index",
"dev:stack:up": "node scripts/dev/manage.js up", "dev:stack:up": "node scripts/dev/manage.js up",
"dev:stack:down": "node scripts/dev/manage.js down", "dev:stack:down": "node scripts/dev/manage.js down",
@ -79,9 +80,9 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.18.6", "@budibase/auth": "^0.9.1",
"@budibase/client": "^0.8.18", "@budibase/client": "^0.9.1",
"@budibase/string-templates": "^0.8.18", "@budibase/string-templates": "^0.9.1",
"@elastic/elasticsearch": "7.10.0", "@elastic/elasticsearch": "7.10.0",
"@koa/router": "8.0.0", "@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1", "@sendgrid/mail": "7.1.1",
@ -131,7 +132,7 @@
"zlib": "1.0.5" "zlib": "1.0.5"
}, },
"devDependencies": { "devDependencies": {
"@budibase/standard-components": "^0.8.18", "@budibase/standard-components": "^0.9.1",
"@jest/test-sequencer": "^24.8.0", "@jest/test-sequencer": "^24.8.0",
"docker-compose": "^0.23.6", "docker-compose": "^0.23.6",
"eslint": "^6.8.0", "eslint": "^6.8.0",
@ -141,5 +142,5 @@
"pouchdb-adapter-memory": "^7.2.1", "pouchdb-adapter-memory": "^7.2.1",
"supertest": "^4.0.2" "supertest": "^4.0.2"
}, },
"gitHead": "4b6efc42ed3273595c7a129411f4d883733d3321" "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
} }

View File

@ -22,10 +22,7 @@ const {
} = require("../../db/utils") } = require("../../db/utils")
const { BUILTIN_ROLE_IDS, AccessController } = require("@budibase/auth/roles") const { BUILTIN_ROLE_IDS, AccessController } = require("@budibase/auth/roles")
const { BASE_LAYOUTS } = require("../../constants/layouts") const { BASE_LAYOUTS } = require("../../constants/layouts")
const { const { createHomeScreen } = require("../../constants/screens")
createHomeScreen,
createLoginScreen,
} = require("../../constants/screens")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
const { processObject } = require("@budibase/string-templates") const { processObject } = require("@budibase/string-templates")
const { getAllApps } = require("../../utilities") const { getAllApps } = require("../../utilities")
@ -208,7 +205,6 @@ exports.create = async function (ctx) {
ctx.status = 200 ctx.status = 200
ctx.body = newApplication ctx.body = newApplication
ctx.message = `Application ${ctx.request.body.name} created successfully`
} }
exports.update = async function (ctx) { exports.update = async function (ctx) {
@ -229,13 +225,11 @@ exports.update = async function (ctx) {
data._rev = response.rev data._rev = response.rev
ctx.status = 200 ctx.status = 200
ctx.message = `Application ${application.name} updated successfully.`
ctx.body = response ctx.body = response
} }
exports.delete = async function (ctx) { exports.delete = async function (ctx) {
const db = new CouchDB(ctx.params.appId) const db = new CouchDB(ctx.params.appId)
const app = await db.get(DocumentTypes.APP_METADATA)
const result = await db.destroy() const result = await db.destroy()
/* istanbul ignore next */ /* istanbul ignore next */
if (!env.isTest()) { if (!env.isTest()) {
@ -243,7 +237,6 @@ exports.delete = async function (ctx) {
} }
ctx.status = 200 ctx.status = 200
ctx.message = `Application ${app.name} deleted successfully.`
ctx.body = result ctx.body = result
} }
@ -260,9 +253,5 @@ const createEmptyAppPackage = async (ctx, app) => {
homeScreen._id = generateScreenID() homeScreen._id = generateScreenID()
screensAndLayouts.push(homeScreen) screensAndLayouts.push(homeScreen)
const loginScreen = createLoginScreen(app)
loginScreen._id = generateScreenID()
screensAndLayouts.push(loginScreen)
await db.bulkDocs(screensAndLayouts) await db.bulkDocs(screensAndLayouts)
} }

View File

@ -4,9 +4,6 @@ const { InternalTables } = require("../../db/utils")
const { getFullUser } = require("../../utilities/users") const { getFullUser } = require("../../utilities/users")
exports.fetchSelf = async ctx => { exports.fetchSelf = async ctx => {
if (!ctx.user) {
ctx.throw(403, "No user logged in")
}
const appId = ctx.appId const appId = ctx.appId
const { userId } = ctx.user const { userId } = ctx.user
/* istanbul ignore next */ /* istanbul ignore next */

View File

@ -28,7 +28,6 @@ describe("/applications", () => {
.set(config.defaultHeaders()) .set(config.defaultHeaders())
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
expect(res.res.statusMessage).toEqual("Application My App created successfully")
expect(res.body._id).toBeDefined() expect(res.body._id).toBeDefined()
}) })
@ -74,7 +73,7 @@ describe("/applications", () => {
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
// should have empty packages // should have empty packages
expect(res.body.screens.length).toEqual(2) expect(res.body.screens.length).toEqual(1)
expect(res.body.layouts.length).toEqual(2) expect(res.body.layouts.length).toEqual(2)
}) })
}) })
@ -87,7 +86,7 @@ describe("/applications", () => {
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
expect(res.body.application).toBeDefined() expect(res.body.application).toBeDefined()
expect(res.body.screens.length).toEqual(2) expect(res.body.screens.length).toEqual(1)
expect(res.body.layouts.length).toEqual(2) expect(res.body.layouts.length).toEqual(2)
}) })
}) })

View File

@ -21,7 +21,7 @@ describe("/screens", () => {
.set(config.defaultHeaders()) .set(config.defaultHeaders())
.expect("Content-Type", /json/) .expect("Content-Type", /json/)
.expect(200) .expect(200)
expect(res.body.length).toEqual(3) expect(res.body.length).toEqual(2)
expect(res.body.some(s => s._id === screen._id)).toEqual(true) expect(res.body.some(s => s._id === screen._id)).toEqual(true)
}) })

View File

@ -1,6 +1,5 @@
const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles") const { BUILTIN_ROLE_IDS } = require("@budibase/auth/roles")
const { BASE_LAYOUT_PROP_IDS } = require("./layouts") const { BASE_LAYOUT_PROP_IDS } = require("./layouts")
const { LOGO_URL } = require("../constants")
exports.createHomeScreen = () => ({ exports.createHomeScreen = () => ({
description: "", description: "",
@ -49,60 +48,3 @@ exports.createHomeScreen = () => ({
}, },
name: "home-screen", name: "home-screen",
}) })
exports.createLoginScreen = app => ({
description: "",
url: "",
layoutId: BASE_LAYOUT_PROP_IDS.PUBLIC,
props: {
_instanceName: "LoginScreenContainer",
_id: "5beb4c7b-3c8b-49b2-b8b3-d447dc76dda7",
_component: "@budibase/standard-components/container",
_styles: {
normal: {
flex: "1 1 auto",
display: "flex",
"flex-direction": "column",
"justify-content": "center",
"align-items": "center",
},
hover: {},
active: {},
selected: {},
},
_transition: "fade",
type: "div",
_children: [
{
_id: "781e497e-2e7c-11eb-adc1-0242ac120002",
_component: "@budibase/standard-components/login",
_styles: {
normal: {
padding: "64px",
background: "rgba(255, 255, 255, 0.4)",
"border-radius": "0.5rem",
"margin-top": "0px",
"box-shadow":
"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
"font-size": "16px",
"font-family": "Inter",
flex: "0 1 auto",
},
hover: {},
active: {},
selected: {},
},
logo: LOGO_URL,
title: `Log in to ${app.name}`,
buttonText: "Log In",
_children: [],
_instanceName: "Login",
},
],
},
routing: {
route: "/",
roleId: BUILTIN_ROLE_IDS.PUBLIC,
},
name: "login-screen",
})

View File

@ -12,7 +12,6 @@ PouchDB.adapter("writableStream", replicationStream.adapters.writableStream)
let POUCH_DB_DEFAULTS = { let POUCH_DB_DEFAULTS = {
prefix: COUCH_DB_URL, prefix: COUCH_DB_URL,
skip_setup: env.isProd(),
} }
if (env.isTest()) { if (env.isTest()) {

View File

@ -160,7 +160,7 @@ exports.generateUserMetadataID = globalId => {
*/ */
exports.getGlobalIDFromUserMetadataID = id => { exports.getGlobalIDFromUserMetadataID = id => {
const prefix = `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}` const prefix = `${DocumentTypes.ROW}${SEPARATOR}${InternalTables.USER_METADATA}${SEPARATOR}`
if (!id.includes(prefix)) { if (!id || !id.includes(prefix)) {
return id return id
} }
return id.split(prefix)[1] return id.split(prefix)[1]

View File

@ -1,4 +1,6 @@
const { Client } = require("pg") const { Pool } = require("pg")
let pool
const SCHEMA = { const SCHEMA = {
docs: "https://node-postgres.com", docs: "https://node-postgres.com",
@ -51,31 +53,39 @@ const SCHEMA = {
class PostgresIntegration { class PostgresIntegration {
constructor(config) { constructor(config) {
this.config = config this.config = config
this.client = new Client(config) if (!pool) {
this.connect() pool = new Pool(this.config)
}
} }
async connect() { async query(sql) {
return this.client.connect() try {
this.client = await pool.connect()
return await this.client.query(sql)
} catch (err) {
throw new Error(err)
} finally {
this.client.release()
}
} }
async create({ sql }) { async create({ sql }) {
const response = await this.client.query(sql) const response = await this.query(sql)
return response.rows.length ? response.rows : [{ created: true }] return response.rows.length ? response.rows : [{ created: true }]
} }
async read({ sql }) { async read({ sql }) {
const response = await this.client.query(sql) const response = await this.query(sql)
return response.rows return response.rows
} }
async update({ sql }) { async update({ sql }) {
const response = await this.client.query(sql) const response = await this.query(sql)
return response.rows.length ? response.rows : [{ updated: true }] return response.rows.length ? response.rows : [{ updated: true }]
} }
async delete({ sql }) { async delete({ sql }) {
const response = await this.client.query(sql) const response = await this.query(sql)
return response.rows.length ? response.rows : [{ deleted: true }] return response.rows.length ? response.rows : [{ deleted: true }]
} }
} }

View File

@ -18,6 +18,11 @@ const WEBHOOK_ENDPOINTS = new RegExp(
async function checkDevAppLocks(ctx) { async function checkDevAppLocks(ctx) {
const appId = ctx.appId const appId = ctx.appId
// if any public usage, don't proceed
if (!ctx.user._id && !ctx.user.userId) {
return
}
// not a development app, don't need to do anything // not a development app, don't need to do anything
if (!appId || !appId.startsWith(APP_DEV_PREFIX)) { if (!appId || !appId.startsWith(APP_DEV_PREFIX)) {
return return

View File

@ -108,6 +108,7 @@ describe("Authorization middleware", () => {
it("passes on to next() middleware if user is an admin", async () => { it("passes on to next() middleware if user is an admin", async () => {
config.setUser({ config.setUser({
_id: "user",
role: { role: {
_id: "ADMIN", _id: "ADMIN",
} }

View File

@ -29,11 +29,11 @@
"keywords": [ "keywords": [
"svelte" "svelte"
], ],
"version": "0.8.18", "version": "0.9.1",
"license": "MIT", "license": "MIT",
"gitHead": "4b6efc42ed3273595c7a129411f4d883733d3321", "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
"dependencies": { "dependencies": {
"@budibase/bbui": "^1.58.13", "@budibase/bbui": "^0.9.1",
"@spectrum-css/page": "^3.0.1", "@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1", "@spectrum-css/vars": "^3.0.1",
"apexcharts": "^3.22.1", "apexcharts": "^3.22.1",

View File

@ -5,13 +5,6 @@
const component = getContext("component") const component = getContext("component")
export let logoUrl export let logoUrl
const logOut = async () => {
if ($builderStore.inBuilder) {
return
}
await authStore.actions.logOut()
}
</script> </script>
<div class="nav" use:styleable={$component.styles}> <div class="nav" use:styleable={$component.styles}>
@ -21,9 +14,6 @@
<img class="logo" alt="logo" src={logoUrl} height="48" /> <img class="logo" alt="logo" src={logoUrl} height="48" />
{/if} {/if}
</a> </a>
<div class="nav__controls">
<div on:click={logOut}>Log out</div>
</div>
</div> </div>
<div class="nav__menu"> <div class="nav__menu">
<slot /> <slot />

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/string-templates", "name": "@budibase/string-templates",
"version": "0.8.18", "version": "0.9.1",
"description": "Handlebars wrapper for Budibase templating.", "description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs", "main": "src/index.cjs",
"module": "dist/bundle.mjs", "module": "dist/bundle.mjs",
@ -39,5 +39,5 @@
"rollup-plugin-terser": "^7.0.2", "rollup-plugin-terser": "^7.0.2",
"typescript": "^4.1.3" "typescript": "^4.1.3"
}, },
"gitHead": "4b6efc42ed3273595c7a129411f4d883733d3321" "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/worker", "name": "@budibase/worker",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.8.18", "version": "0.9.1",
"description": "Budibase background service", "description": "Budibase background service",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -13,6 +13,7 @@
], ],
"scripts": { "scripts": {
"run:docker": "node src/index.js", "run:docker": "node src/index.js",
"build:docker": "docker build . -t worker-service",
"dev:stack:init": "node ./scripts/dev/manage.js init", "dev:stack:init": "node ./scripts/dev/manage.js init",
"dev:builder": "npm run dev:stack:init && nodemon src/index.js", "dev:builder": "npm run dev:stack:init && nodemon src/index.js",
"test": "jest --runInBand" "test": "jest --runInBand"
@ -20,8 +21,8 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.18.6", "@budibase/auth": "^0.9.1",
"@budibase/string-templates": "^0.8.16", "@budibase/string-templates": "^0.9.1",
"@koa/router": "^8.0.0", "@koa/router": "^8.0.0",
"aws-sdk": "^2.811.0", "aws-sdk": "^2.811.0",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
@ -57,5 +58,6 @@
"setupFiles": [ "setupFiles": [
"./scripts/jestSetup.js" "./scripts/jestSetup.js"
] ]
} },
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"
} }

View File

@ -33,6 +33,10 @@ const PUBLIC_ENDPOINTS = [
route: "/api/admin/configs/checklist", route: "/api/admin/configs/checklist",
method: "GET", method: "GET",
}, },
{
route: "/api/apps",
method: "GET",
},
] ]
const router = new Router() const router = new Router()

View File

@ -7,7 +7,6 @@ const COUCH_DB_URL = env.COUCH_DB_URL || "http://localhost:10000/db/"
let POUCH_DB_DEFAULTS = { let POUCH_DB_DEFAULTS = {
prefix: COUCH_DB_URL, prefix: COUCH_DB_URL,
skip_setup: env.isProd(),
} }
if (env.isTest()) { if (env.isTest()) {