Merge branch 'develop' of github.com:Budibase/budibase into feature/sql-relationship-filtering

This commit is contained in:
mike12345567 2022-01-17 13:34:16 +00:00
commit 29fbfe7b95
18 changed files with 145 additions and 36 deletions

46
.github/workflows/smoke_test.yaml vendored Normal file
View File

@ -0,0 +1,46 @@
name: Budibase Smoke Test
on:
workflow_dispatch:
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x
- run: yarn
- run: yarn bootstrap
- run: yarn build
- name: Pull cypress.env.yaml from budibase-infra
run: |
curl -H "Authorization: token ${{ secrets.GH_PERSONAL_TOKEN }}" \
-H 'Accept: application/vnd.github.v3.raw' \
-o packages/builder/cypress.env.json \
-L https://api.github.com/repos/budibase/budibase-infra/contents/test/cypress.env.json
wc -l packages/builder/cypress.env.json
- run: yarn test:e2e:ci
env:
CI: true
name: Budibase CI
# TODO: upload recordings to s3
# - name: Configure AWS Credentials
# uses: aws-actions/configure-aws-credentials@v1
# with:
# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# aws-region: eu-west-1
# TODO look at cypress reporters
# - name: Discord Webhook Action
# uses: tsickert/discord-webhook@v4.0.0
# with:
# webhook-url: ${{ secrets.PROD_DEPLOY_WEBHOOK_URL }}
# content: "Production Deployment Complete: ${{ env.RELEASE_VERSION }} deployed to Budibase Cloud."
# embed-title: ${{ env.RELEASE_VERSION }}

View File

@ -1,5 +1,5 @@
{ {
"version": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/backend-core", "name": "@budibase/backend-core",
"version": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"description": "Budibase backend core libraries used in server and worker", "description": "Budibase backend core libraries used in server and worker",
"main": "src/index.js", "main": "src/index.js",
"author": "Budibase", "author": "Budibase",

View File

@ -8,6 +8,7 @@ exports.Cookies = {
Auth: "budibase:auth", Auth: "budibase:auth",
Init: "budibase:init", Init: "budibase:init",
OIDC_CONFIG: "budibase:oidc:config", OIDC_CONFIG: "budibase:oidc:config",
RETURN_URL: "budibase:returnurl",
} }
exports.Headers = { exports.Headers = {

View File

@ -96,7 +96,12 @@ exports.getCookie = (ctx, name) => {
* @param {string|object} value The value of cookie which will be set. * @param {string|object} value The value of cookie which will be set.
* @param {object} opts options like whether to sign. * @param {object} opts options like whether to sign.
*/ */
exports.setCookie = (ctx, value, name = "builder", opts = { sign: true }) => { exports.setCookie = (
ctx,
value,
name = "builder",
opts = { sign: true, requestDomain: false }
) => {
if (value && opts && opts.sign) { if (value && opts && opts.sign) {
value = jwt.sign(value, options.secretOrKey) value = jwt.sign(value, options.secretOrKey)
} }
@ -108,7 +113,7 @@ exports.setCookie = (ctx, value, name = "builder", opts = { sign: true }) => {
overwrite: true, overwrite: true,
} }
if (environment.COOKIE_DOMAIN) { if (environment.COOKIE_DOMAIN && !opts.requestDomain) {
config.domain = environment.COOKIE_DOMAIN config.domain = environment.COOKIE_DOMAIN
} }

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.0.27-alpha.17", "version": "1.0.27-alpha.20",
"license": "MPL-2.0", "license": "MPL-2.0",
"svelte": "src/index.js", "svelte": "src/index.js",
"module": "dist/bbui.es.js", "module": "dist/bbui.es.js",

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/builder", "name": "@budibase/builder",
"version": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"license": "GPL-3.0", "license": "GPL-3.0",
"private": true, "private": true,
"scripts": { "scripts": {
@ -65,10 +65,10 @@
} }
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^1.0.27-alpha.17", "@budibase/bbui": "^1.0.27-alpha.20",
"@budibase/client": "^1.0.27-alpha.17", "@budibase/client": "^1.0.27-alpha.20",
"@budibase/colorpicker": "1.1.2", "@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^1.0.27-alpha.17", "@budibase/string-templates": "^1.0.27-alpha.20",
"@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,16 +1,26 @@
export const Cookies = { export const Cookies = {
Auth: "budibase:auth", Auth: "budibase:auth",
CurrentApp: "budibase:currentapp", CurrentApp: "budibase:currentapp",
ReturnUrl: "budibase:returnurl",
}
export function setCookie(name, value) {
if (getCookie(name)) {
removeCookie(name)
}
window.document.cookie = `${name}=${value}; Path=/;`
} }
export function getCookie(cookieName) { export function getCookie(cookieName) {
return document.cookie.split(";").some(cookie => { const value = `; ${document.cookie}`
return cookie.trim().startsWith(`${cookieName}=`) const parts = value.split(`; ${cookieName}=`)
}) if (parts.length === 2) {
return parts[1].split(";").shift()
}
} }
export function removeCookie(cookieName) { export function removeCookie(cookieName) {
if (getCookie(cookieName)) { if (getCookie(cookieName)) {
document.cookie = `${cookieName}=; Max-Age=-99999999;` document.cookie = `${cookieName}=; Max-Age=-99999999; Path=/;`
} }
} }

View File

@ -2,6 +2,12 @@
import { isActive, redirect, params } from "@roxi/routify" import { isActive, redirect, params } from "@roxi/routify"
import { admin, auth } from "stores/portal" import { admin, auth } from "stores/portal"
import { onMount } from "svelte" import { onMount } from "svelte"
import {
Cookies,
getCookie,
removeCookie,
setCookie,
} from "builderStore/cookies"
let loaded = false let loaded = false
@ -67,6 +73,24 @@
$: { $: {
const apiReady = $admin.loaded && $auth.loaded const apiReady = $admin.loaded && $auth.loaded
// firstly, set the return url
if (
loaded &&
apiReady &&
!$auth.user &&
!getCookie(Cookies.ReturnUrl) &&
// logout triggers a page refresh, so we don't want to set the return url
!$auth.postLogout &&
// don't set the return url on pre-login pages
!$isActive("./auth") &&
!$isActive("./invite") &&
!$isActive("./admin")
) {
const url = window.location.pathname
setCookie(Cookies.ReturnUrl, url)
}
// if tenant is not set go to it // if tenant is not set go to it
if ( if (
loaded && loaded &&
@ -90,13 +114,20 @@
!$isActive("./invite") && !$isActive("./invite") &&
!$isActive("./admin") !$isActive("./admin")
) { ) {
const returnUrl = encodeURIComponent(window.location.pathname) $redirect("./auth")
$redirect("./auth?", { returnUrl })
} }
// check if password reset required for user // check if password reset required for user
else if ($auth.user?.forceResetPassword) { else if ($auth.user?.forceResetPassword) {
$redirect("./auth/reset") $redirect("./auth/reset")
} }
// lastly, redirect to the return url if it has been set
else if (loaded && apiReady && $auth.user) {
const returnUrl = getCookie(Cookies.ReturnUrl)
if (returnUrl) {
removeCookie(Cookies.ReturnUrl)
window.location.href = returnUrl
}
}
} }
</script> </script>

View File

@ -10,7 +10,7 @@
notifications, notifications,
Link, Link,
} from "@budibase/bbui" } from "@budibase/bbui"
import { goto, params } from "@roxi/routify" import { goto } from "@roxi/routify"
import { auth, organisation, oidc, admin } from "stores/portal" import { auth, organisation, oidc, admin } from "stores/portal"
import GoogleButton from "./_components/GoogleButton.svelte" import GoogleButton from "./_components/GoogleButton.svelte"
import OIDCButton from "./_components/OIDCButton.svelte" import OIDCButton from "./_components/OIDCButton.svelte"
@ -34,14 +34,10 @@
if ($auth?.user?.forceResetPassword) { if ($auth?.user?.forceResetPassword) {
$goto("./reset") $goto("./reset")
} else {
if ($params["?returnUrl"]) {
window.location = decodeURIComponent($params["?returnUrl"])
} else { } else {
notifications.success("Logged in successfully") notifications.success("Logged in successfully")
$goto("../portal") $goto("../portal")
} }
}
} catch (err) { } catch (err) {
console.error(err) console.error(err)
notifications.error(err.message ? err.message : "Invalid Credentials") notifications.error(err.message ? err.message : "Invalid Credentials")

View File

@ -9,6 +9,7 @@ export function createAuthStore() {
tenantId: "default", tenantId: "default",
tenantSet: false, tenantSet: false,
loaded: false, loaded: false,
postLogout: false,
}) })
const store = derived(auth, $store => { const store = derived(auth, $store => {
let initials = null let initials = null
@ -34,6 +35,7 @@ export function createAuthStore() {
tenantId: $store.tenantId, tenantId: $store.tenantId,
tenantSet: $store.tenantSet, tenantSet: $store.tenantSet,
loaded: $store.loaded, loaded: $store.loaded,
postLogout: $store.postLogout,
initials, initials,
isAdmin, isAdmin,
isBuilder, isBuilder,
@ -89,6 +91,13 @@ export function createAuthStore() {
return info return info
} }
async function setPostLogout() {
auth.update(store => {
store.postLogout = true
return store
})
}
async function getInitInfo() { async function getInitInfo() {
const response = await api.get(`/api/global/auth/init`) const response = await api.get(`/api/global/auth/init`)
const json = response.json() const json = response.json()
@ -145,6 +154,7 @@ export function createAuthStore() {
await response.json() await response.json()
await setInitInfo({}) await setInitInfo({})
setUser(null) setUser(null)
setPostLogout()
}, },
updateSelf: async fields => { updateSelf: async fields => {
const newUser = { ...get(auth).user, ...fields } const newUser = { ...get(auth).user, ...fields }

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/cli", "name": "@budibase/cli",
"version": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"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": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"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",
@ -19,9 +19,9 @@
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^1.0.27-alpha.17", "@budibase/bbui": "^1.0.27-alpha.20",
"@budibase/standard-components": "^0.9.139", "@budibase/standard-components": "^0.9.139",
"@budibase/string-templates": "^1.0.27-alpha.17", "@budibase/string-templates": "^1.0.27-alpha.20",
"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"

View File

@ -63,8 +63,9 @@
} else { } else {
// The user is not logged in, redirect them to login // The user is not logged in, redirect them to login
const returnUrl = `${window.location.pathname}${window.location.hash}` const returnUrl = `${window.location.pathname}${window.location.hash}`
const encodedUrl = encodeURIComponent(returnUrl) // TODO: reuse `Cookies` from builder when frontend-core is added
window.location = `/builder/auth/login?returnUrl=${encodedUrl}` window.document.cookie = `budibase:returnurl=${returnUrl}; Path=/`
window.location = `/builder/auth/login`
} }
} }
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/server", "name": "@budibase/server",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"description": "Budibase Web Server", "description": "Budibase Web Server",
"main": "src/index.ts", "main": "src/index.ts",
"repository": { "repository": {
@ -70,9 +70,9 @@
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@apidevtools/swagger-parser": "^10.0.3", "@apidevtools/swagger-parser": "^10.0.3",
"@budibase/backend-core": "^1.0.27-alpha.17", "@budibase/backend-core": "^1.0.27-alpha.20",
"@budibase/client": "^1.0.27-alpha.17", "@budibase/client": "^1.0.27-alpha.20",
"@budibase/string-templates": "^1.0.27-alpha.17", "@budibase/string-templates": "^1.0.27-alpha.20",
"@bull-board/api": "^3.7.0", "@bull-board/api": "^3.7.0",
"@bull-board/koa": "^3.7.0", "@bull-board/koa": "^3.7.0",
"@elastic/elasticsearch": "7.10.0", "@elastic/elasticsearch": "7.10.0",

View File

@ -47,6 +47,15 @@ module.exports = async (ctx, next) => {
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global) (!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
) { ) {
clearCookie(ctx, Cookies.CurrentApp) clearCookie(ctx, Cookies.CurrentApp)
// have to set the return url on the server side as client side is not available
setCookie(ctx, ctx.url, Cookies.RETURN_URL, {
// don't sign so the browser can easily read
sign: false,
// use the request domain to match how ui handles the return url cookie.
// it's important we don't use the shared domain here as the builder
// can't delete from it without awareness of the domain.
requestDomain: true,
})
return ctx.redirect("/") return ctx.redirect("/")
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/string-templates", "name": "@budibase/string-templates",
"version": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"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",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/worker", "name": "@budibase/worker",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "1.0.27-alpha.17", "version": "1.0.27-alpha.20",
"description": "Budibase background service", "description": "Budibase background service",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -29,8 +29,8 @@
"author": "Budibase", "author": "Budibase",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@budibase/backend-core": "^1.0.27-alpha.17", "@budibase/backend-core": "^1.0.27-alpha.20",
"@budibase/string-templates": "^1.0.27-alpha.17", "@budibase/string-templates": "^1.0.27-alpha.20",
"@koa/router": "^8.0.0", "@koa/router": "^8.0.0",
"@sentry/node": "^6.0.0", "@sentry/node": "^6.0.0",
"@techpass/passport-openidconnect": "^0.3.0", "@techpass/passport-openidconnect": "^0.3.0",