diff --git a/.github/workflows/deploy-release.yml b/.github/workflows/deploy-release.yml index 0fb8a5fea0..551b417c58 100644 --- a/.github/workflows/deploy-release.yml +++ b/.github/workflows/deploy-release.yml @@ -68,6 +68,18 @@ jobs: ] env: KUBECONFIG_FILE: '${{ secrets.RELEASE_KUBECONFIG }}' + + - name: Set the base64 kubeconfig + run: | + base64_kubeconfig=$(echo ${{ secrets.RELEASE_KUBECONFIG }} | base64) + echo "RELEASE_KUBECONFIG=$base64_kubeconfig" >> $GITHUB_ENV + + - name: Re roll the services + uses: actions-hub/kubectl@master + env: + KUBE_CONFIG: ${{ env.RELEASE_KUBECONFIG }} + with: + args: rollout restart deployment proxy-service -n budibase && kubectl rollout restart deployment app-service -n budibase && kubectl rollout restart deployment worker-service -n budibase - name: Discord Webhook Action uses: tsickert/discord-webhook@v4.0.0 diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml index 772fcf933d..69d3b1410a 100644 --- a/.github/workflows/release-develop.yml +++ b/.github/workflows/release-develop.yml @@ -120,6 +120,18 @@ jobs: ] env: KUBECONFIG_FILE: '${{ secrets.RELEASE_KUBECONFIG }}' + + - name: Set the base64 kubeconfig + run: | + base64_kubeconfig=$(echo ${{ secrets.RELEASE_KUBECONFIG }} | base64) + echo "RELEASE_KUBECONFIG=$base64_kubeconfig" >> $GITHUB_ENV + + - name: Re roll the services + uses: actions-hub/kubectl@master + env: + KUBE_CONFIG: ${{ env.RELEASE_KUBECONFIG }} + with: + args: rollout restart deployment proxy-service -n budibase && kubectl rollout restart deployment app-service -n budibase && kubectl rollout restart deployment worker-service -n budibase - name: Discord Webhook Action uses: tsickert/discord-webhook@v4.0.0 diff --git a/.github/workflows/smoke_test.yaml b/.github/workflows/smoke_test.yaml index 7002c8335b..cffb914aaf 100644 --- a/.github/workflows/smoke_test.yaml +++ b/.github/workflows/smoke_test.yaml @@ -1,4 +1,4 @@ -name: Budibase Smoke Test +name: Budibase Nightly Tests on: workflow_dispatch: @@ -6,7 +6,7 @@ on: - cron: "0 5 * * *" # every day at 5AM jobs: - release: + nightly: runs-on: ubuntu-latest steps: @@ -43,6 +43,18 @@ jobs: name: Test Reports path: packages/builder/cypress/reports/testReport.html + # TODO: enable once running in QA test env + # - 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 + + # - name: Upload test results HTML + # uses: aws-actions/configure-aws-credentials@v1 + # run: aws s3 cp packages/builder/cypress/reports/testReport.html s3://{{ secrets.BUDI_QA_REPORTS_BUCKET_NAME }}/$GITHUB_RUN_ID/index.html + - name: Cypress Discord Notify run: yarn test:e2e:ci:notify env: diff --git a/hosting/nginx.dev.conf.hbs b/hosting/nginx.dev.conf.hbs index 9398b7e719..e08516c9d3 100644 --- a/hosting/nginx.dev.conf.hbs +++ b/hosting/nginx.dev.conf.hbs @@ -62,6 +62,10 @@ http { proxy_pass http://{{ address }}:4001; } + location /preview { + proxy_pass http://{{ address }}:4001; + } + location /builder { proxy_pass http://{{ address }}:3000; rewrite ^/builder(.*)$ /builder/$1 break; diff --git a/hosting/nginx.prod.conf.hbs b/hosting/nginx.prod.conf.hbs index 4213626309..eaff214187 100644 --- a/hosting/nginx.prod.conf.hbs +++ b/hosting/nginx.prod.conf.hbs @@ -85,6 +85,10 @@ http { proxy_pass http://$apps:4002; } + location /preview { + proxy_pass http://$apps:4002; + } + location = / { proxy_pass http://$apps:4002; } @@ -94,6 +98,7 @@ http { proxy_pass http://$watchtower:8080; } {{/if}} + location ~ ^/(builder|app_) { proxy_http_version 1.1; proxy_set_header Connection $connection_upgrade; diff --git a/hosting/scripts/build-target-paths.sh b/hosting/scripts/build-target-paths.sh index 6d5a8429f8..ee314c1ce4 100644 --- a/hosting/scripts/build-target-paths.sh +++ b/hosting/scripts/build-target-paths.sh @@ -11,6 +11,10 @@ if [[ "${TARGETBUILD}" = "aas" ]]; then apt-get install -y openssh-server sed -i "s/#Port 22/Port 2222/" /etc/ssh/sshd_config /etc/init.d/ssh restart -fi + sed -i "s#DATA_DIR#/home#g" /opt/clouseau/clouseau.ini + sed -i "s#DATA_DIR#/home#g" /opt/couchdb/etc/local.ini +else + sed -i "s#DATA_DIR#/data#g" /opt/clouseau/clouseau.ini + sed -i "s#DATA_DIR#/data#g" /opt/couchdb/etc/local.ini -sed -i 's#DATA_DIR#$DATA_DIR#' /opt/clouseau/clouseau.ini /opt/couchdb/etc/local.ini +fi \ No newline at end of file diff --git a/hosting/single/couch/local.ini b/hosting/single/couch/local.ini index 266c0d4b60..35f0383dfc 100644 --- a/hosting/single/couch/local.ini +++ b/hosting/single/couch/local.ini @@ -1,5 +1,5 @@ ; CouchDB Configuration Settings [couchdb] -database_dir = DATA_DIR/couch/dbs -view_index_dir = DATA_DIR/couch/views +database_dir = DATA_DIR/couchdb/dbs +view_index_dir = DATA_DIR/couchdb/views diff --git a/hosting/single/healthcheck.sh b/hosting/single/healthcheck.sh index b92cd153a3..592b3e94fa 100644 --- a/hosting/single/healthcheck.sh +++ b/hosting/single/healthcheck.sh @@ -3,6 +3,11 @@ healthy=true if [ -f "/data/.env" ]; then export $(cat /data/.env | xargs) +elif [ -f "/home/.env" ]; then + export $(cat /home/.env | xargs) +else + echo "No .env file found" + healthy=false fi if [[ $(curl -Lfk -s -w "%{http_code}\n" http://localhost/ -o /dev/null) -ne 200 ]]; then diff --git a/lerna.json b/lerna.json index 74c71b7201..9247be8016 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index f64d277b8d..cc8aa483cf 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -20,7 +20,7 @@ "test:watch": "jest --watchAll" }, "dependencies": { - "@budibase/types": "1.2.39-alpha.6", + "@budibase/types": "1.2.44-alpha.2", "@techpass/passport-openidconnect": "0.3.2", "aws-sdk": "2.1030.0", "bcrypt": "5.0.1", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 38c2222c7a..c9cabd4ae2 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": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "^1.2.1", - "@budibase/string-templates": "1.2.39-alpha.6", + "@budibase/string-templates": "1.2.44-alpha.2", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/bbui/src/Form/Core/Dropzone.svelte b/packages/bbui/src/Form/Core/Dropzone.svelte index 36515acbc5..ffdac08402 100644 --- a/packages/bbui/src/Form/Core/Dropzone.svelte +++ b/packages/bbui/src/Form/Core/Dropzone.svelte @@ -17,6 +17,7 @@ export let disabled = false export let fileSizeLimit = BYTES_IN_MB * 20 export let processFiles = null + export let deleteAttachments = null export let handleFileTooLarge = null export let handleTooManyFiles = null export let gallery = true @@ -94,6 +95,11 @@ "change", value.filter((x, idx) => idx !== selectedImageIdx) ) + if (deleteAttachments) { + await deleteAttachments( + value.filter((x, idx) => idx === selectedImageIdx).map(item => item.key) + ) + } selectedImageIdx = 0 } diff --git a/packages/bbui/src/Form/Dropzone.svelte b/packages/bbui/src/Form/Dropzone.svelte index f1b548f7f1..5b82c0ebea 100644 --- a/packages/bbui/src/Form/Dropzone.svelte +++ b/packages/bbui/src/Form/Dropzone.svelte @@ -10,6 +10,7 @@ export let error = null export let fileSizeLimit = undefined export let processFiles = undefined + export let deleteAttachments = undefined export let handleFileTooLarge = undefined export let handleTooManyFiles = undefined export let gallery = true @@ -30,6 +31,7 @@ {value} {fileSizeLimit} {processFiles} + {deleteAttachments} {handleFileTooLarge} {handleTooManyFiles} {gallery} diff --git a/packages/bbui/src/Icon/Icon.svelte b/packages/bbui/src/Icon/Icon.svelte index 9c99178fdb..f2cae14f0b 100644 --- a/packages/bbui/src/Icon/Icon.svelte +++ b/packages/bbui/src/Icon/Icon.svelte @@ -83,4 +83,9 @@ transform: translateX(-50%); text-align: center; } + + .spectrum-Icon--sizeXS { + width: 10px; + height: 10px; + } diff --git a/packages/bbui/src/Menu/Item.svelte b/packages/bbui/src/Menu/Item.svelte index a5609683a8..dfe61c1736 100644 --- a/packages/bbui/src/Menu/Item.svelte +++ b/packages/bbui/src/Menu/Item.svelte @@ -1,5 +1,6 @@ - + Import diff --git a/packages/builder/src/components/common/Dropzone.svelte b/packages/builder/src/components/common/Dropzone.svelte index 9a86554b49..fd2359fd91 100644 --- a/packages/builder/src/components/common/Dropzone.svelte +++ b/packages/builder/src/components/common/Dropzone.svelte @@ -27,6 +27,14 @@ return [] } } + + async function deleteAttachments(fileList) { + try { + return await API.deleteBuilderAttachments(fileList) + } catch (error) { + return [] + } + } diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte index 31962077fc..69d5fe60b4 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/ButtonActionDrawer.svelte @@ -11,7 +11,7 @@ } from "@budibase/bbui" import { getAvailableActions } from "./index" import { generate } from "shortid" - import { getButtonContextBindings } from "builderStore/dataBinding" + import { getEventContextBindings } from "builderStore/dataBinding" import { currentAsset, store } from "builderStore" const flipDurationMs = 150 @@ -41,14 +41,14 @@ }, {}) // These are ephemeral bindings which only exist while executing actions - $: buttonContextBindings = getButtonContextBindings( + $: eventContexBindings = getEventContextBindings( $currentAsset, $store.selectedComponentId, key, actions, selectedAction?.id ) - $: allBindings = buttonContextBindings.concat(bindings) + $: allBindings = eventContexBindings.concat(bindings) // Assign a unique ID to each action $: { diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ShowNotification.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ShowNotification.svelte new file mode 100644 index 0000000000..55b00d215d --- /dev/null +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ShowNotification.svelte @@ -0,0 +1,61 @@ + + +
+ + - import { notifications, Slider, Icon } from "@budibase/bbui" + import { notifications } from "@budibase/bbui" import { store } from "builderStore" + import { Constants } from "@budibase/frontend-core" - const ThemeOptions = [ - "spectrum--darkest", - "spectrum--dark", - "spectrum--light", - "spectrum--lightest", - ] - - $: themeIndex = ThemeOptions.indexOf($store.theme) ?? 2 - - const onChangeTheme = async e => { + const onChangeTheme = async theme => { try { - const theme = ThemeOptions[e.detail] ?? ThemeOptions[2] - await store.actions.theme.save(theme) + await store.actions.theme.save(`spectrum--${theme}`) } catch (error) { notifications.error("Error updating theme") } @@ -22,26 +13,52 @@
- - - + {#each Constants.Themes as theme} +
onChangeTheme(theme.class)} + > +
+ {theme.name} +
+ {/each}
diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/theme/_components/ButtonRoundnessSelect.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/theme/_components/ButtonRoundnessSelect.svelte new file mode 100644 index 0000000000..21b04f694f --- /dev/null +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/theme/_components/ButtonRoundnessSelect.svelte @@ -0,0 +1,38 @@ + + +
+ +
+ +
+
+ + diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/theme/_components/ThemeSettingsPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/theme/_components/ThemeSettingsPanel.svelte index 4bad3b7bc4..1c86a51f67 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/theme/_components/ThemeSettingsPanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/theme/_components/ThemeSettingsPanel.svelte @@ -1,35 +1,11 @@
- logo + logo - Accept Invitation + Invitation to {company} - Please enter a password to set up your user. + Please enter a password to get started. @@ -46,7 +57,7 @@ } .container { margin: 0 auto; - width: 260px; + width: 300px; display: flex; flex-direction: column; justify-content: flex-start; diff --git a/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte b/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte index d0662e7b41..5d2a381187 100644 --- a/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte +++ b/packages/builder/src/pages/builder/portal/apps/_components/AcessFilter.svelte @@ -22,7 +22,7 @@ if (!detail) return const groupSelected = $groups.find(x => x._id === detail) - const appIds = groupSelected?.apps.map(x => x.appId) || null + const appIds = groupSelected?.apps || null dispatch("change", appIds) } diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index a089664d2e..13d23f6a51 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -20,7 +20,7 @@ import { store, automationStore } from "builderStore" import { API } from "api" import { onMount } from "svelte" - import { apps, auth, admin, templates, groups } from "stores/portal" + import { apps, auth, admin, templates } from "stores/portal" import download from "downloadjs" import { goto } from "@roxi/routify" import AppRow from "components/start/AppRow.svelte" @@ -355,7 +355,7 @@ {/if}
- {#if $auth.groupsEnabled && $groups.length} + {#if $auth.groupsEnabled} {/if} { + if (!scopesFields[0].inputText) { + scopesFields[0].error = null + } + if ( + e.key === "Enter" || + e.keyCode === 13 || + e.code == "Space" || + e.keyCode == 32 + ) { + let scopes = providers.oidc.config.configs[0]["scopes"] + ? providers.oidc.config.configs[0]["scopes"] + : [...defaultScopes] + + let update = scopesFields[0].inputText.trim() + + if (HasSpacesRegex.test(update)) { + scopesFields[0].error = + "Auth scopes cannot contain spaces, double quotes or backslashes" + return + } else if (scopes.indexOf(update) > -1) { + scopesFields[0].error = "Auth scope already exists" + return + } else if (!update.length) { + scopesFields[0].inputText = null + scopesFields[0].error = null + return + } else { + scopesFields[0].error = null + scopes.push(update) + providers.oidc.config.configs[0]["scopes"] = scopes + scopesFields[0].inputText = null + } + } + }} + /> + +
+ + + openid + {#each providers.oidc.config.configs[0]["scopes"] || [...defaultScopes] as tag, idx} + { + let idxScopes = providers.oidc.config.configs[0]["scopes"] + if (idxScopes.length == 1) { + idxScopes.pop() + } else { + idxScopes.splice(idx, 1) + refreshScopes(0) + } + }} + > + {tag} + + {/each} + +
+
+
+ {/if} diff --git a/packages/client/src/components/app/forms/AttachmentField.svelte b/packages/client/src/components/app/forms/AttachmentField.svelte index 5023e77ae5..8a98f92d83 100644 --- a/packages/client/src/components/app/forms/AttachmentField.svelte +++ b/packages/client/src/components/app/forms/AttachmentField.svelte @@ -47,6 +47,17 @@ } } + const deleteAttachments = async fileList => { + try { + return await API.deleteAttachments({ + keys: fileList, + tableId: formContext?.dataSource?.tableId, + }) + } catch (error) { + return [] + } + } + const handleChange = e => { fieldApi.setValue(e.detail) if (onChange) { @@ -72,6 +83,7 @@ error={fieldState.error} on:change={handleChange} {processFiles} + {deleteAttachments} {handleFileTooLarge} {handleTooManyFiles} {maximum} diff --git a/packages/client/src/components/app/index.js b/packages/client/src/components/app/index.js index c7b8f18643..1c0d868433 100644 --- a/packages/client/src/components/app/index.js +++ b/packages/client/src/components/app/index.js @@ -5,6 +5,8 @@ import "@spectrum-css/vars/dist/spectrum-darkest.css" import "@spectrum-css/vars/dist/spectrum-dark.css" import "@spectrum-css/vars/dist/spectrum-light.css" import "@spectrum-css/vars/dist/spectrum-lightest.css" +import "@budibase/frontend-core/src/themes/nord.css" +import "@budibase/frontend-core/src/themes/midnight.css" import "@spectrum-css/page/dist/index-vars.css" // Non user-facing components diff --git a/packages/client/src/components/preview/KeyboardManager.svelte b/packages/client/src/components/preview/KeyboardManager.svelte index c0358088c5..1eedb0fde7 100644 --- a/packages/client/src/components/preview/KeyboardManager.svelte +++ b/packages/client/src/components/preview/KeyboardManager.svelte @@ -16,20 +16,20 @@ }) const onKeyDown = e => { - if (e.key === "Delete" || e.key === "Backspace") { - deleteSelectedComponent() - } - } - - const deleteSelectedComponent = () => { const state = get(builderStore) - if (!state.inBuilder || !state.selectedComponentId || state.editMode) { + if (!state.inBuilder || state.editMode) { return } const activeTag = document.activeElement?.tagName.toLowerCase() if (["input", "textarea"].indexOf(activeTag) !== -1) { return } - builderStore.actions.deleteComponent(state.selectedComponentId) + + // Need to manually block certain keys from propagating to the browser + if (e.ctrlKey && e.key === "d") { + e.preventDefault() + } + + builderStore.actions.keyDown(e.key, e.ctrlKey) } diff --git a/packages/client/src/stores/builder.js b/packages/client/src/stores/builder.js index be748f0d81..32eb956d52 100644 --- a/packages/client/src/stores/builder.js +++ b/packages/client/src/stores/builder.js @@ -40,8 +40,8 @@ const createBuilderStore = () => { updateProp: (prop, value) => { dispatchEvent("update-prop", { prop, value }) }, - deleteComponent: id => { - dispatchEvent("delete-component", { id }) + keyDown: (key, ctrlKey) => { + dispatchEvent("key-down", { key, ctrlKey }) }, duplicateComponent: id => { dispatchEvent("duplicate-component", { id }) diff --git a/packages/client/src/stores/notification.js b/packages/client/src/stores/notification.js index 9c3dfd1523..bbde660fd4 100644 --- a/packages/client/src/stores/notification.js +++ b/packages/client/src/stores/notification.js @@ -62,10 +62,14 @@ const createNotificationStore = () => { subscribe: store.subscribe, actions: { send, - info: msg => send(msg, "info", "Info"), - success: msg => send(msg, "success", "CheckmarkCircle"), - warning: msg => send(msg, "warning", "Alert"), - error: msg => send(msg, "error", "Alert", false), + info: (msg, autoDismiss) => + send(msg, "info", "Info", autoDismiss ?? true), + success: (msg, autoDismiss) => + send(msg, "success", "CheckmarkCircle", autoDismiss ?? true), + warning: (msg, autoDismiss) => + send(msg, "warning", "Alert", autoDismiss ?? true), + error: (msg, autoDismiss) => + send(msg, "error", "Alert", autoDismiss ?? false), blockNotifications, dismiss, }, diff --git a/packages/client/src/stores/theme.js b/packages/client/src/stores/theme.js index 995dafbedc..8877556f0c 100644 --- a/packages/client/src/stores/theme.js +++ b/packages/client/src/stores/theme.js @@ -1,6 +1,7 @@ import { derived } from "svelte/store" import { appStore } from "./app" import { builderStore } from "./builder" +import { Constants } from "@budibase/frontend-core" // This is the good old acorn bug where having the word "g l o b a l" makes it // think that this is not ES6 compatible and starts throwing errors when using @@ -28,6 +29,13 @@ const createThemeStore = () => { // Ensure theme is set theme = theme || defaultTheme + // Get base theme + let base = + Constants.Themes.find(x => `spectrum--${x.class}` === theme)?.base || "" + if (base) { + base = `spectrum--${base}` + } + // Delete and nullish keys from the custom theme if (customTheme) { Object.entries(customTheme).forEach(([key, value]) => { @@ -51,6 +59,7 @@ const createThemeStore = () => { return { theme, + baseTheme: base, customTheme, customThemeCss, } diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index c6f46d1c67..a534ee8326 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -300,6 +300,14 @@ const continueIfHandler = action => { } } +const showNotificationHandler = action => { + const { message, type, autoDismiss } = action.parameters + if (!message || !type) { + return + } + notificationStore.actions[type]?.(message, autoDismiss) +} + const handlerMap = { ["Save Row"]: saveRowHandler, ["Duplicate Row"]: duplicateRowHandler, @@ -318,6 +326,7 @@ const handlerMap = { ["Upload File to S3"]: s3UploadHandler, ["Export Data"]: exportDataHandler, ["Continue if / Stop if"]: continueIfHandler, + ["Show Notification"]: showNotificationHandler, } const confirmTextMap = { @@ -334,8 +343,8 @@ const confirmTextMap = { */ export const enrichButtonActions = (actions, context) => { // Prevent button actions in the builder preview - if (!actions || get(builderStore).inBuilder) { - return () => {} + if (!actions?.length || get(builderStore).inBuilder) { + return null } // If this is a function then it has already been enriched diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 8948820e22..aa75268abe 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "1.2.39-alpha.6", + "@budibase/bbui": "1.2.44-alpha.2", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/frontend-core/src/api/attachments.js b/packages/frontend-core/src/api/attachments.js index e3b1b74e5b..f79b461574 100644 --- a/packages/frontend-core/src/api/attachments.js +++ b/packages/frontend-core/src/api/attachments.js @@ -61,5 +61,32 @@ export const buildAttachmentEndpoints = API => { }) return { publicUrl } }, + + /** + * Deletes attachments from the bucket. + * @param keys the attachments to delete + * @param tableId the associated table ID + */ + deleteAttachments: async ({ keys, tableId }) => { + return await API.post({ + url: `/api/attachments/${tableId}/delete`, + body: { + keys, + }, + }) + }, + + /** + * Deletes attachments from the builder bucket. + * @param keys the attachments to delete + */ + deleteBuilderAttachments: async keys => { + return await API.post({ + url: `/api/attachments/delete`, + body: { + keys, + }, + }) + }, } } diff --git a/packages/frontend-core/src/themes/midnight.css b/packages/frontend-core/src/themes/midnight.css index 528d847702..f2b4650ebf 100644 --- a/packages/frontend-core/src/themes/midnight.css +++ b/packages/frontend-core/src/themes/midnight.css @@ -12,5 +12,7 @@ --spectrum-global-color-gray-700: hsl(var(--hue), var(--sat), 70%); --spectrum-global-color-gray-800: hsl(var(--hue), var(--sat), 80%); --spectrum-global-color-gray-900: hsl(var(--hue), var(--sat), 95%); + + --modal-background: var(--spectrum-global-color-gray-50); } diff --git a/packages/frontend-core/src/themes/nord.css b/packages/frontend-core/src/themes/nord.css index ebcf7efaf9..c5a9b13640 100644 --- a/packages/frontend-core/src/themes/nord.css +++ b/packages/frontend-core/src/themes/nord.css @@ -43,4 +43,7 @@ --spectrum-alias-highlight-hover: rgba(169, 177, 193, 0.1); --spectrum-alias-highlight-active: rgba(169, 177, 193, 0.1); + --spectrum-alias-background-color-hover-overlay: rgba(169, 177, 193, 0.1); + + --modal-background: var(--spectrum-global-color-gray-50); } diff --git a/packages/frontend-core/src/utils/lucene.js b/packages/frontend-core/src/utils/lucene.js index 6c0c2035d3..08c7d9f79b 100644 --- a/packages/frontend-core/src/utils/lucene.js +++ b/packages/frontend-core/src/utils/lucene.js @@ -119,7 +119,7 @@ export const buildLuceneQuery = filter => { return } } - if (type === "number" && !Array.isArray(value)) { + if (type === "number" && typeof value === "string") { if (operator === "oneOf") { value = value.split(",").map(item => parseFloat(item)) } else if (!isHbs) { diff --git a/packages/server/package.json b/packages/server/package.json index 3b1dbe9ecb..072252915a 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -77,11 +77,11 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "1.2.39-alpha.6", - "@budibase/client": "1.2.39-alpha.6", - "@budibase/pro": "1.2.39-alpha.6", - "@budibase/string-templates": "1.2.39-alpha.6", - "@budibase/types": "1.2.39-alpha.6", + "@budibase/backend-core": "1.2.44-alpha.2", + "@budibase/client": "1.2.44-alpha.2", + "@budibase/pro": "1.2.44-alpha.2", + "@budibase/string-templates": "1.2.44-alpha.2", + "@budibase/types": "1.2.44-alpha.2", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", @@ -93,7 +93,7 @@ "arangojs": "7.2.0", "aws-sdk": "2.1030.0", "bcryptjs": "2.4.3", - "bull": "3.29.3", + "bull": "4.8.5", "chmodr": "1.2.0", "csvtojson": "2.0.10", "curlconverter": "3.21.0", diff --git a/packages/server/src/api/controllers/static/index.ts b/packages/server/src/api/controllers/static/index.ts index 7aeea98adc..3b748a6591 100644 --- a/packages/server/src/api/controllers/static/index.ts +++ b/packages/server/src/api/controllers/static/index.ts @@ -12,7 +12,7 @@ const { } = require("../../../utilities/fileSystem") const env = require("../../../environment") const { clientLibraryPath } = require("../../../utilities") -const { upload } = require("../../../utilities/fileSystem") +const { upload, deleteFiles } = require("../../../utilities/fileSystem") const { attachmentsRelativeURL } = require("../../../utilities") const { DocumentType } = require("../../../db/utils") const { getAppDB, getAppId } = require("@budibase/backend-core/context") @@ -97,6 +97,10 @@ export const uploadFile = async function (ctx: any) { ctx.body = await Promise.all(uploads) } +export const deleteObjects = async function (ctx: any) { + ctx.body = await deleteFiles(ObjectStoreBuckets.APPS, ctx.request.body.keys) +} + export const serveApp = async function (ctx: any) { const db = getAppDB({ skip_setup: true }) const appInfo = await db.get(DocumentType.APP_METADATA) @@ -124,6 +128,22 @@ export const serveApp = async function (ctx: any) { } } +export const serveBuilderPreview = async function (ctx: any) { + const db = getAppDB({ skip_setup: true }) + const appInfo = await db.get(DocumentType.APP_METADATA) + + if (!env.isJest()) { + let appId = getAppId() + const previewHbs = loadHandlebarsFile(`${__dirname}/templates/preview.hbs`) + ctx.body = await processString(previewHbs, { + clientLibPath: clientLibraryPath(appId, appInfo.version, ctx), + }) + } else { + // just return the app info for jest to assert on + ctx.body = { ...appInfo, builderPreview: true } + } +} + export const serveClientLibrary = async function (ctx: any) { return send(ctx, "budibase-client.js", { root: join(NODE_MODULES_PATH, "@budibase", "client", "dist"), diff --git a/packages/server/src/api/controllers/static/templates/preview.hbs b/packages/server/src/api/controllers/static/templates/preview.hbs new file mode 100644 index 0000000000..28908df507 --- /dev/null +++ b/packages/server/src/api/controllers/static/templates/preview.hbs @@ -0,0 +1,103 @@ + + + Budibase Builder Preview + + + + + + + + + + \ No newline at end of file diff --git a/packages/server/src/api/controllers/view/utils.js b/packages/server/src/api/controllers/view/utils.js index 97a179532e..7ce7d324e4 100644 --- a/packages/server/src/api/controllers/view/utils.js +++ b/packages/server/src/api/controllers/view/utils.js @@ -20,8 +20,17 @@ exports.getView = async viewName => { return null } - const viewDoc = await db.get(generateMemoryViewID(viewName)) - return viewDoc.view + try { + const viewDoc = await db.get(generateMemoryViewID(viewName)) + return viewDoc.view + } catch (err) { + // Return null when PouchDB doesn't found the view + if (err.status === 404) { + return null + } + + throw err + } } } diff --git a/packages/server/src/api/routes/static.ts b/packages/server/src/api/routes/static.ts index 61cf2b1245..9a53486689 100644 --- a/packages/server/src/api/routes/static.ts +++ b/packages/server/src/api/routes/static.ts @@ -38,6 +38,11 @@ router // TODO: for now this builder endpoint is not authorized/secured, will need to be .get("/builder/:file*", controller.serveBuilder) .post("/api/attachments/process", authorized(BUILDER), controller.uploadFile) + .post( + "/api/attachments/delete", + authorized(BUILDER), + controller.deleteObjects + ) .post("/api/beta/:feature", controller.toggleBetaUiFeature) .post( "/api/attachments/:tableId/upload", @@ -45,6 +50,13 @@ router authorized(PermissionTypes.TABLE, PermissionLevels.WRITE), controller.uploadFile ) + .post( + "/api/attachments/:tableId/delete", + paramResource("tableId"), + authorized(PermissionTypes.TABLE, PermissionLevels.WRITE), + controller.deleteObjects + ) + .get("/preview", authorized(BUILDER), controller.serveBuilderPreview) .get("/:appId/:path*", controller.serveApp) .get("/app/:appUrl/:path*", controller.serveApp) .post( diff --git a/packages/server/src/api/routes/tests/static.spec.js b/packages/server/src/api/routes/tests/static.spec.js index 37176f5cf5..812b88329b 100644 --- a/packages/server/src/api/routes/tests/static.spec.js +++ b/packages/server/src/api/routes/tests/static.spec.js @@ -40,7 +40,6 @@ describe("/static", () => { }) describe("/app", () => { - beforeEach(() => { jest.clearAllMocks() }) @@ -60,7 +59,7 @@ describe("/static", () => { it("should serve the app by url", async () => { const headers = config.defaultHeaders() delete headers[constants.Headers.APP_ID] - + const res = await request .get(`/app${config.prodApp.url}`) .set(headers) @@ -82,7 +81,7 @@ describe("/static", () => { describe("/attachments", () => { describe("generateSignedUrls", () => { let datasource - + beforeEach(async () => { datasource = await config.createDatasource({ datasource: { @@ -93,7 +92,7 @@ describe("/static", () => { }, }) }) - + it("should be able to generate a signed upload URL", async () => { const bucket = "foo" const key = "bar" @@ -108,7 +107,7 @@ describe("/static", () => { `https://${bucket}.s3.eu-west-1.amazonaws.com/${key}` ) }) - + it("should handle an invalid datasource ID", async () => { const res = await request .post(`/api/attachments/foo/url`) @@ -123,7 +122,7 @@ describe("/static", () => { "The specified datasource could not be found" ) }) - + it("should require a bucket parameter", async () => { const res = await request .post(`/api/attachments/${datasource._id}/url`) @@ -136,7 +135,7 @@ describe("/static", () => { .expect(400) expect(res.body.message).toEqual("bucket and key values are required") }) - + it("should require a key parameter", async () => { const res = await request .post(`/api/attachments/${datasource._id}/url`) @@ -151,4 +150,17 @@ describe("/static", () => { }) }) + describe("/preview", () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + it("should serve the builder preview", async () => { + const headers = config.defaultHeaders() + const res = await request.get(`/preview`).set(headers).expect(200) + + expect(res.body.appId).toBe(config.appId) + expect(res.body.builderPreview).toBe(true) + }) + }) }) diff --git a/packages/server/src/utilities/fileSystem/index.js b/packages/server/src/utilities/fileSystem/index.js index f4aebd11a8..1223ea55f0 100644 --- a/packages/server/src/utilities/fileSystem/index.js +++ b/packages/server/src/utilities/fileSystem/index.js @@ -15,6 +15,7 @@ const { streamUpload, deleteFolder, downloadTarball, + deleteFiles, } = require("./utilities") const { updateClientLibrary } = require("./clientLibrary") const env = require("../../environment") @@ -327,5 +328,6 @@ exports.cleanup = appIds => { exports.upload = upload exports.retrieve = retrieve exports.retrieveToTmp = retrieveToTmp +exports.deleteFiles = deleteFiles exports.TOP_LEVEL_PATH = TOP_LEVEL_PATH exports.NODE_MODULES_PATH = NODE_MODULES_PATH diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 1b53951615..adf135a3da 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1094,12 +1094,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.2.39-alpha.6": - version "1.2.39-alpha.6" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.2.39-alpha.6.tgz#ebfddd4fa74fff043a60df7cba335b5fcdb84d51" - integrity sha512-1kz9K3MSe5E4d/dSm6jD4BMIX/SSW58d8U787N+1BfzvSkIEd32j7HFs5ij0w9sromvK9FEjpFBfZKqSDRp+5g== +"@budibase/backend-core@1.2.44-alpha.2": + version "1.2.44-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.2.44-alpha.2.tgz#89de0626821308629628d703bc1ee98bc5ae1e8a" + integrity sha512-ZV5ZuuPccPN21Z99XjNvNFVPTRuZC061NOuxAXaX4LIE+o5cwRKStU7mVMVEnj+UPrwAQDYEjON2vTQ5CZd1/w== dependencies: - "@budibase/types" "1.2.39-alpha.6" + "@budibase/types" "1.2.44-alpha.2" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" bcrypt "5.0.1" @@ -1178,13 +1178,13 @@ svelte-flatpickr "^3.2.3" svelte-portal "^1.0.0" -"@budibase/pro@1.2.39-alpha.6": - version "1.2.39-alpha.6" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.2.39-alpha.6.tgz#94a19338c6f59755f34b4bf181ba15ac5eba5404" - integrity sha512-l5IcibGGpd9VCIzY5vZU6rYeJa+1AYNCsWWKMnm7ZeZQgiD62Hyus53pv9GvT4pwpUF60pxybAoTWhbbityCPQ== +"@budibase/pro@1.2.44-alpha.2": + version "1.2.44-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.2.44-alpha.2.tgz#0f6b3bdd0226f0b077f886ac7cb75cd9207e6909" + integrity sha512-OVNJWFL82z08O3rpE7sTnYa/nrslNMblLgd+M5mo155Q+Lk6tmXFxg49Azoo51AB/S4VLruebt5fVVMGTdQngA== dependencies: - "@budibase/backend-core" "1.2.39-alpha.6" - "@budibase/types" "1.2.39-alpha.6" + "@budibase/backend-core" "1.2.44-alpha.2" + "@budibase/types" "1.2.44-alpha.2" "@koa/router" "8.0.8" joi "17.6.0" node-fetch "^2.6.1" @@ -1207,10 +1207,10 @@ svelte-apexcharts "^1.0.2" svelte-flatpickr "^3.1.0" -"@budibase/types@1.2.39-alpha.6": - version "1.2.39-alpha.6" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.2.39-alpha.6.tgz#5c6dc1a130913fb1c7ac6999fc6e03d970d0142f" - integrity sha512-0FHmwsfvAL80PGQM0OSJ6n9CDCtQQrbX8PRdcWOSIhRNlJXNcTsPcBsPbQpZPbgT57GHX/86Fo1rljiMWDwNpw== +"@budibase/types@1.2.44-alpha.2": + version "1.2.44-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.2.44-alpha.2.tgz#9f266436715806bf42a2ab9c21b0af089ce443f3" + integrity sha512-TXZwDsHs6RLA8aIM3MC+MKwpSHZG7hZ9DigKgzpD9UugTPChq+GT+zadKPBe5/bbLuhrhAORqnPea3JLm8P7XQ== "@bull-board/api@3.7.0": version "3.7.0" @@ -2026,6 +2026,36 @@ semver "^7.3.5" tar "^6.1.11" +"@msgpackr-extract/msgpackr-extract-darwin-arm64@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.1.2.tgz#9571b87be3a3f2c46de05585470bc4f3af2f6f00" + integrity sha512-TyVLn3S/+ikMDsh0gbKv2YydKClN8HaJDDpONlaZR+LVJmsxLFUgA+O7zu59h9+f9gX1aj/ahw9wqa6rosmrYQ== + +"@msgpackr-extract/msgpackr-extract-darwin-x64@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.1.2.tgz#bfbc6936ede2955218f5621a675679a5fe8e6f4c" + integrity sha512-YPXtcVkhmVNoMGlqp81ZHW4dMxK09msWgnxtsDpSiZwTzUBG2N+No2bsr7WMtBKCVJMSD6mbAl7YhKUqkp/Few== + +"@msgpackr-extract/msgpackr-extract-linux-arm64@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.1.2.tgz#22555e28382af2922e7450634c8a2f240bb9eb82" + integrity sha512-vHZ2JiOWF2+DN9lzltGbhtQNzDo8fKFGrf37UJrgqxU0yvtERrzUugnfnX1wmVfFhSsF8OxrfqiNOUc5hko1Zg== + +"@msgpackr-extract/msgpackr-extract-linux-arm@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.1.2.tgz#ffb6ae1beea7ac572b6be6bf2a8e8162ebdd8be7" + integrity sha512-42R4MAFeIeNn+L98qwxAt360bwzX2Kf0ZQkBBucJ2Ircza3asoY4CDbgiu9VWklq8gWJVSJSJBwDI+c/THiWkA== + +"@msgpackr-extract/msgpackr-extract-linux-x64@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.1.2.tgz#7caf62eebbfb1345de40f75e89666b3d4194755f" + integrity sha512-RjRoRxg7Q3kPAdUSC5EUUPlwfMkIVhmaRTIe+cqHbKrGZ4M6TyCA/b5qMaukQ/1CHWrqYY2FbKOAU8Hg0pQFzg== + +"@msgpackr-extract/msgpackr-extract-win32-x64@2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.1.2.tgz#f2d8b9ddd8d191205ed26ce54aba3dfc5ae3e7c9" + integrity sha512-rIZVR48zA8hGkHIK7ED6+ZiXsjRCcAVBJbm8o89OKAMTmEAQ2QvoOxoiu3w2isAaWwzgtQIOFIqHwvZDyLKCvw== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -4246,20 +4276,19 @@ buffer@^5.1.0, buffer@^5.2.0, buffer@^5.2.1, buffer@^5.5.0, buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" -bull@3.29.3: - version "3.29.3" - resolved "https://registry.yarnpkg.com/bull/-/bull-3.29.3.tgz#5b0059b172685b0d6f011d56214e1898ff3a7a0b" - integrity sha512-MOqV1dKLy1YQgP9m3lFolyMxaU+1+o4afzYYf0H4wNM+x/S0I1QPQfkgGlLiH00EyFrvSmeubeCYFP47rTfpjg== +bull@4.8.5: + version "4.8.5" + resolved "https://registry.yarnpkg.com/bull/-/bull-4.8.5.tgz#eebafddc3249d6d5e8ced1c42b8bfa8efcc274aa" + integrity sha512-2Z630e4f6VsLJnWMAtfEHwIqJYmND4W3dcG48RIbXeWpvb4UnYtpe/zxEdslJu0PKrltB4IkFj5YtBsdeQRn8w== dependencies: - cron-parser "^2.13.0" + cron-parser "^4.2.1" debuglog "^1.0.0" get-port "^5.1.1" - ioredis "^4.27.0" + ioredis "^4.28.5" lodash "^4.17.21" + msgpackr "^1.5.2" p-timeout "^3.2.0" - promise.prototype.finally "^3.1.2" semver "^7.3.2" - util.promisify "^1.0.1" uuid "^8.3.0" bytes@3.1.2, bytes@^3.0.0: @@ -4826,13 +4855,12 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cron-parser@^2.13.0: - version "2.18.0" - resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.18.0.tgz#de1bb0ad528c815548371993f81a54e5a089edcf" - integrity sha512-s4odpheTyydAbTBQepsqd2rNWGa2iV3cyo8g7zbI2QQYGLVsfbhmwukayS1XHppe02Oy1fg7mg6xoaraVJeEcg== +cron-parser@^4.2.1: + version "4.6.0" + resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.6.0.tgz#404c3fdbff10ae80eef6b709555d577ef2fd2e0d" + integrity sha512-guZNLMGUgg6z4+eGhmHGw7ft+v6OQeuHzd1gcLxCo9Yg/qoxmG3nindp2/uwGCLizEisf2H0ptqeVXeoCpP6FA== dependencies: - is-nan "^1.3.0" - moment-timezone "^0.5.31" + luxon "^3.0.1" cross-spawn@^4.0.0: version "4.0.2" @@ -5483,7 +5511,7 @@ error-inject@^1.0.0: resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" integrity sha512-JM8N6PytDbmIYm1IhPWlo8vr3NtfjhDY/1MhD/a5b/aad/USE8a0+NsqE9d5n+GVGmuNkPQWm4bFQWv18d8tMg== -es-abstract@^1.17.5, es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.0, es-abstract@^1.20.1: +es-abstract@^1.17.5, es-abstract@^1.19.0, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.0, es-abstract@^1.20.1: version "1.20.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== @@ -7397,7 +7425,7 @@ ioredis@4.28.0: redis-parser "^3.0.0" standard-as-callback "^2.1.0" -ioredis@^4.27.0: +ioredis@^4.28.5: version "4.28.5" resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.5.tgz#5c149e6a8d76a7f8fa8a504ffc85b7d5b6797f9f" integrity sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A== @@ -7605,14 +7633,6 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" -is-nan@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" - integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - is-natural-number@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" @@ -9653,6 +9673,11 @@ ltgt@2.2.1, ltgt@^2.1.2, ltgt@~2.2.0: resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5" integrity sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA== +luxon@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.0.1.tgz#6901111d10ad06fd267ad4e4128a84bef8a77299" + integrity sha512-hF3kv0e5gwHQZKz4wtm4c+inDtyc7elkanAsBq+fundaCdUBNJB1dHEGUZIM6SfSBUlbVFduPwEtNjFK8wLtcw== + make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -9935,7 +9960,7 @@ mock-require@^3.0.3: get-caller-file "^1.0.2" normalize-path "^2.1.1" -moment-timezone@^0.5.15, moment-timezone@^0.5.31: +moment-timezone@^0.5.15: version "0.5.34" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c" integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg== @@ -9985,6 +10010,27 @@ ms@^2.1.1, ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +msgpackr-extract@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-2.1.2.tgz#56272030f3e163e1b51964ef8b1cd5e7240c03ed" + integrity sha512-cmrmERQFb19NX2JABOGtrKdHMyI6RUyceaPBQ2iRz9GnDkjBWFjNJC0jyyoOfZl2U/LZE3tQCCQc4dlRyA8mcA== + dependencies: + node-gyp-build-optional-packages "5.0.3" + optionalDependencies: + "@msgpackr-extract/msgpackr-extract-darwin-arm64" "2.1.2" + "@msgpackr-extract/msgpackr-extract-darwin-x64" "2.1.2" + "@msgpackr-extract/msgpackr-extract-linux-arm" "2.1.2" + "@msgpackr-extract/msgpackr-extract-linux-arm64" "2.1.2" + "@msgpackr-extract/msgpackr-extract-linux-x64" "2.1.2" + "@msgpackr-extract/msgpackr-extract-win32-x64" "2.1.2" + +msgpackr@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.6.2.tgz#176cd9f6b4437dad87a839b37f23c2dfee408d9a" + integrity sha512-bqSQ0DYJbXbrJcrZFmMygUZmqQiDfI2ewFVWcrZY12w5XHWtPuW4WppDT/e63Uu311ajwkRRXSoF0uILroBeTA== + optionalDependencies: + msgpackr-extract "^2.0.2" + mssql@6.2.3: version "6.2.3" resolved "https://registry.yarnpkg.com/mssql/-/mssql-6.2.3.tgz#1d15bbe8c3057e32ee6e98596b6c323b097a6cba" @@ -10131,6 +10177,11 @@ node-forge@^1.3.1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== +node-gyp-build-optional-packages@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17" + integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== + node-gyp-build@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb" @@ -11354,15 +11405,6 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -promise.prototype.finally@^3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz#d3186e58fcf4df1682a150f934ccc27b7893389c" - integrity sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -13733,7 +13775,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@^1.0.0, util.promisify@^1.0.1: +util.promisify@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index d4584d2361..391323aa2f 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/types/package.json b/packages/types/package.json index c64986ac55..83e2eab138 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "description": "Budibase types", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/worker/package.json b/packages/worker/package.json index 01560d6775..ae674d6847 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "1.2.39-alpha.6", + "version": "1.2.44-alpha.2", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -35,10 +35,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "1.2.39-alpha.6", - "@budibase/pro": "1.2.39-alpha.6", - "@budibase/string-templates": "1.2.39-alpha.6", - "@budibase/types": "1.2.39-alpha.6", + "@budibase/backend-core": "1.2.44-alpha.2", + "@budibase/pro": "1.2.44-alpha.2", + "@budibase/string-templates": "1.2.44-alpha.2", + "@budibase/types": "1.2.44-alpha.2", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/packages/worker/src/api/controllers/global/auth.ts b/packages/worker/src/api/controllers/global/auth.ts index dc96554cb2..834531cd78 100644 --- a/packages/worker/src/api/controllers/global/auth.ts +++ b/packages/worker/src/api/controllers/global/auth.ts @@ -227,9 +227,22 @@ export const oidcPreAuth = async (ctx: any, next: any) => { setCookie(ctx, configId, Cookies.OIDC_CONFIG) + const db = getGlobalDB() + const config = await core.db.getScopedConfig(db, { + type: Configs.OIDC, + group: ctx.query.group, + }) + + const chosenConfig = config.configs.filter((c: any) => c.uuid === configId)[0] + + let authScopes = + chosenConfig.scopes?.length > 0 + ? chosenConfig.scopes + : ["profile", "email", "offline_access"] + return passport.authenticate(strategy, { // required 'openid' scope is added by oidc strategy factory - scope: ["profile", "email", "offline_access"], //auth0 offline_access scope required for the refresh token behaviour. + scope: authScopes, })(ctx, next) } diff --git a/packages/worker/src/api/routes/global/configs.js b/packages/worker/src/api/routes/global/configs.js index c4beb57600..e08611b73a 100644 --- a/packages/worker/src/api/routes/global/configs.js +++ b/packages/worker/src/api/routes/global/configs.js @@ -53,6 +53,7 @@ function oidcValidation() { name: Joi.string().allow("", null), uuid: Joi.string().required(), activated: Joi.boolean().required(), + scopes: Joi.array().optional() }) ).required(true) }).unknown(true) diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index 5636a7f2a3..f38fda779a 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -291,12 +291,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.2.39-alpha.6": - version "1.2.39-alpha.6" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.2.39-alpha.6.tgz#ebfddd4fa74fff043a60df7cba335b5fcdb84d51" - integrity sha512-1kz9K3MSe5E4d/dSm6jD4BMIX/SSW58d8U787N+1BfzvSkIEd32j7HFs5ij0w9sromvK9FEjpFBfZKqSDRp+5g== +"@budibase/backend-core@1.2.44-alpha.2": + version "1.2.44-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.2.44-alpha.2.tgz#89de0626821308629628d703bc1ee98bc5ae1e8a" + integrity sha512-ZV5ZuuPccPN21Z99XjNvNFVPTRuZC061NOuxAXaX4LIE+o5cwRKStU7mVMVEnj+UPrwAQDYEjON2vTQ5CZd1/w== dependencies: - "@budibase/types" "1.2.39-alpha.6" + "@budibase/types" "1.2.44-alpha.2" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" bcrypt "5.0.1" @@ -325,21 +325,21 @@ uuid "8.3.2" zlib "1.0.5" -"@budibase/pro@1.2.39-alpha.6": - version "1.2.39-alpha.6" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.2.39-alpha.6.tgz#94a19338c6f59755f34b4bf181ba15ac5eba5404" - integrity sha512-l5IcibGGpd9VCIzY5vZU6rYeJa+1AYNCsWWKMnm7ZeZQgiD62Hyus53pv9GvT4pwpUF60pxybAoTWhbbityCPQ== +"@budibase/pro@1.2.44-alpha.2": + version "1.2.44-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.2.44-alpha.2.tgz#0f6b3bdd0226f0b077f886ac7cb75cd9207e6909" + integrity sha512-OVNJWFL82z08O3rpE7sTnYa/nrslNMblLgd+M5mo155Q+Lk6tmXFxg49Azoo51AB/S4VLruebt5fVVMGTdQngA== dependencies: - "@budibase/backend-core" "1.2.39-alpha.6" - "@budibase/types" "1.2.39-alpha.6" + "@budibase/backend-core" "1.2.44-alpha.2" + "@budibase/types" "1.2.44-alpha.2" "@koa/router" "8.0.8" joi "17.6.0" node-fetch "^2.6.1" -"@budibase/types@1.2.39-alpha.6": - version "1.2.39-alpha.6" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.2.39-alpha.6.tgz#5c6dc1a130913fb1c7ac6999fc6e03d970d0142f" - integrity sha512-0FHmwsfvAL80PGQM0OSJ6n9CDCtQQrbX8PRdcWOSIhRNlJXNcTsPcBsPbQpZPbgT57GHX/86Fo1rljiMWDwNpw== +"@budibase/types@1.2.44-alpha.2": + version "1.2.44-alpha.2" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.2.44-alpha.2.tgz#9f266436715806bf42a2ab9c21b0af089ce443f3" + integrity sha512-TXZwDsHs6RLA8aIM3MC+MKwpSHZG7hZ9DigKgzpD9UugTPChq+GT+zadKPBe5/bbLuhrhAORqnPea3JLm8P7XQ== "@cspotcode/source-map-consumer@0.8.0": version "0.8.0"