Merge branch 'feature/sql-relationship-filtering' of github.com:Budibase/budibase into feature/sql-relationship-filtering
This commit is contained in:
commit
54ce8d8386
|
@ -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 }}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "1.0.27-alpha.17",
|
"version": "1.0.27-alpha.20",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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=/;`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -35,12 +35,8 @@
|
||||||
if ($auth?.user?.forceResetPassword) {
|
if ($auth?.user?.forceResetPassword) {
|
||||||
$goto("./reset")
|
$goto("./reset")
|
||||||
} else {
|
} else {
|
||||||
if ($params["?returnUrl"]) {
|
notifications.success("Logged in successfully")
|
||||||
window.location = decodeURIComponent($params["?returnUrl"])
|
$goto("../portal")
|
||||||
} else {
|
|
||||||
notifications.success("Logged in successfully")
|
|
||||||
$goto("../portal")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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": {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue