diff --git a/.github/workflows/budibase_ci.yml b/.github/workflows/budibase_ci.yml index b351d6edbf..eb9eeebb37 100644 --- a/.github/workflows/budibase_ci.yml +++ b/.github/workflows/budibase_ci.yml @@ -42,15 +42,3 @@ jobs: name: codecov-umbrella verbose: true - run: yarn test:e2e:ci - - - name: Build and Push Development Docker Image - # Only run on push - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' }} - run: | - docker login -u $DOCKER_USER -p $DOCKER_PASSWORD - yarn build - yarn build:docker:develop - env: - DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} - diff --git a/.github/workflows/release-develop.yml b/.github/workflows/release-develop.yml new file mode 100644 index 0000000000..ce41fcc3e6 --- /dev/null +++ b/.github/workflows/release-develop.yml @@ -0,0 +1,52 @@ +name: Budibase Release Staging + +on: + push: + branches: + - develop + +env: + POSTHOG_TOKEN: ${{ secrets.POSTHOG_TOKEN }} + POSTHOG_URL: ${{ secrets.POSTHOG_URL }} + SENTRY_DSN: ${{ secrets.SENTRY_DSN }} + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12.x + - run: yarn + - run: yarn bootstrap + - run: yarn lint + - run: yarn build + - run: yarn test + + - 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: Publish budibase packages to NPM + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + # setup the username and email. I tend to use 'GitHub Actions Bot' with no email by default + git config user.name "Budibase Staging Release Bot" + git config user.email "<>" + echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} >> .npmrc + yarn release:develop + + - name: Build/release Docker images + run: | + docker login -u $DOCKER_USER -p $DOCKER_PASSWORD + yarn build + yarn build:docker:develop + env: + DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_API_KEY }} diff --git a/lerna.json b/lerna.json index 27fbed5858..94018c3177 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "0.9.78", + "version": "0.9.80-alpha.7", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/package.json b/package.json index 61ff67b076..4f545d935f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "publishdev": "lerna run publishdev", "publishnpm": "yarn build && lerna publish --force-publish", "release": "yarn build && lerna publish patch --yes --force-publish", + "release:develop": "yarn build && lerna publish prerelease --yes --force-publish --dist-tag develop", "restore": "yarn run clean && yarn run bootstrap && yarn run build", "nuke": "yarn run nuke:packages && yarn run nuke:docker", "nuke:packages": "yarn run restore", diff --git a/packages/auth/constants.js b/packages/auth/constants.js new file mode 100644 index 0000000000..4abb7703db --- /dev/null +++ b/packages/auth/constants.js @@ -0,0 +1 @@ +module.exports = require("./src/constants") diff --git a/packages/auth/package.json b/packages/auth/package.json index 6ad144687a..9af14c6398 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/auth", - "version": "0.9.78", + "version": "0.9.80-alpha.7", "description": "Authentication middlewares for budibase builder and apps", "main": "src/index.js", "author": "Budibase", @@ -10,6 +10,7 @@ "test:watch": "jest --watchAll" }, "dependencies": { + "@techpass/passport-openidconnect": "^0.3.0", "aws-sdk": "^2.901.0", "bcryptjs": "^2.4.3", "ioredis": "^4.27.1", @@ -17,7 +18,6 @@ "koa-passport": "^4.1.4", "lodash": "^4.17.21", "node-fetch": "^2.6.1", - "@techpass/passport-openidconnect": "^0.3.0", "passport-google-auth": "^1.0.2", "passport-google-oauth": "^2.0.0", "passport-jwt": "^4.0.0", @@ -35,8 +35,8 @@ "devDependencies": { "ioredis-mock": "^5.5.5", "jest": "^26.6.3", - "pouchdb-adapter-memory": "^7.2.2", "pouchdb": "^7.2.1", + "pouchdb-adapter-memory": "^7.2.2", "pouchdb-all-dbs": "^1.0.2" }, "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" diff --git a/packages/auth/src/constants.js b/packages/auth/src/constants.js index df7fbf5c3f..c8cc34e937 100644 --- a/packages/auth/src/constants.js +++ b/packages/auth/src/constants.js @@ -9,6 +9,13 @@ exports.Cookies = { OIDC_CONFIG: "budibase:oidc:config", } +exports.Headers = { + API_KEY: "x-budibase-api-key", + API_VER: "x-budibase-api-version", + APP_ID: "x-budibase-app-id", + TYPE: "x-budibase-type", +} + exports.GlobalRoles = { OWNER: "owner", ADMIN: "admin", diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js index db1fdfacd9..647ec659f5 100644 --- a/packages/auth/src/middleware/authenticated.js +++ b/packages/auth/src/middleware/authenticated.js @@ -1,4 +1,4 @@ -const { Cookies } = require("../constants") +const { Cookies, Headers } = require("../constants") const { getCookie, clearCookie } = require("../utils") const { getUser } = require("../cache/user") const { getSession, updateSessionTTL } = require("../security/sessions") @@ -22,15 +22,17 @@ function buildNoAuthRegex(patterns) { }) } -function finalise(ctx, { authenticated, user, internal } = {}) { +function finalise(ctx, { authenticated, user, internal, version } = {}) { ctx.isAuthenticated = authenticated || false ctx.user = user ctx.internal = internal || false + ctx.version = version } module.exports = (noAuthPatterns = [], opts) => { const noAuthOptions = noAuthPatterns ? buildNoAuthRegex(noAuthPatterns) : [] return async (ctx, next) => { + const version = ctx.request.headers[Headers.API_VER] // the path is not authenticated const found = noAuthOptions.find(({ regex, method }) => { return ( @@ -71,7 +73,7 @@ module.exports = (noAuthPatterns = [], opts) => { await updateSessionTTL(session) } } - const apiKey = ctx.request.headers["x-budibase-api-key"] + const apiKey = ctx.request.headers[Headers.API_KEY] // this is an internal request, no user made it if (!authenticated && apiKey && apiKey === env.INTERNAL_API_KEY) { authenticated = true @@ -82,12 +84,12 @@ module.exports = (noAuthPatterns = [], opts) => { authenticated = false } // isAuthenticated is a function, so use a variable to be able to check authed state - finalise(ctx, { authenticated, user, internal }) + finalise(ctx, { authenticated, user, internal, version }) return next() } catch (err) { // allow configuring for public access if (opts && opts.publicAllowed) { - finalise(ctx, { authenticated: false }) + finalise(ctx, { authenticated: false, version }) } else { ctx.throw(err.status || 403, err) } diff --git a/packages/auth/src/utils.js b/packages/auth/src/utils.js index 8bd635e2e3..6bc1e0e3a6 100644 --- a/packages/auth/src/utils.js +++ b/packages/auth/src/utils.js @@ -8,6 +8,7 @@ const jwt = require("jsonwebtoken") const { options } = require("./middleware/passport/jwt") const { createUserEmailView } = require("./db/views") const { getDB } = require("./db") +const { Headers } = require("./constants") const APP_PREFIX = DocumentTypes.APP + SEPARATOR @@ -23,7 +24,7 @@ function confirmAppId(possibleAppId) { * @returns {string|undefined} If an appId was found it will be returned. */ exports.getAppId = ctx => { - const options = [ctx.headers["x-budibase-app-id"], ctx.params.appId] + const options = [ctx.headers[Headers.APP_ID], ctx.params.appId] if (ctx.subdomains) { options.push(ctx.subdomains[1]) } @@ -97,7 +98,7 @@ exports.clearCookie = (ctx, name) => { * @return {boolean} returns true if the call is from the client lib (a built app rather than the builder). */ exports.isClient = ctx => { - return ctx.headers["x-budibase-type"] === "client" + return ctx.headers[Headers.TYPE] === "client" } /** diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 5e11c19012..b63c8f734b 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": "0.9.78", + "version": "0.9.80-alpha.7", "license": "AGPL-3.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", diff --git a/packages/builder/package.json b/packages/builder/package.json index aa6b165731..3219577fc3 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "0.9.78", + "version": "0.9.80-alpha.7", "license": "AGPL-3.0", "private": true, "scripts": { @@ -65,10 +65,10 @@ } }, "dependencies": { - "@budibase/bbui": "^0.9.78", - "@budibase/client": "^0.9.78", + "@budibase/bbui": "^0.9.80-alpha.7", + "@budibase/client": "^0.9.80-alpha.7", "@budibase/colorpicker": "1.1.2", - "@budibase/string-templates": "^0.9.78", + "@budibase/string-templates": "^0.9.80-alpha.7", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte b/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte index 8b7417c41f..588a3a8486 100644 --- a/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/EditRoles.svelte @@ -6,8 +6,10 @@ import ErrorsBox from "components/common/ErrorsBox.svelte" import { roles } from "stores/backend" + const BASE_ROLE = { _id: "", inherits: "BASIC", permissionId: "Read/Write" } + let basePermissions = [] - let selectedRole = {} + let selectedRole = BASE_ROLE let errors = [] let builtInRoles = ["Admin", "Power", "Basic", "Public"] // Don't allow editing of public role @@ -15,6 +17,11 @@ $: selectedRoleId = selectedRole._id $: otherRoles = editableRoles.filter(role => role._id !== selectedRoleId) $: isCreating = selectedRoleId == null || selectedRoleId === "" + $: valid = + selectedRole.name && + selectedRole.inherits && + selectedRole.permissionId && + !builtInRoles.includes(selectedRole.name) const fetchBasePermissions = async () => { const permissionsResponse = await api.get("/api/permission/builtin") @@ -32,7 +39,7 @@ permissionId: role.permissionId ?? "", } } else { - selectedRole = { _id: "", inherits: "", permissionId: "" } + selectedRole = BASE_ROLE } errors = [] } @@ -88,6 +95,7 @@ title="Edit Roles" confirmText={isCreating ? "Create" : "Save"} onConfirm={saveRole} + disabled={!valid} > {#if errors.length} @@ -115,7 +123,7 @@ options={otherRoles} getOptionValue={role => role._id} getOptionLabel={role => role.name} - placeholder="None" + disabled={builtInRoles.includes(selectedRole.name)} />