From 27fc3a3c5e93d64c05af7dc3da82e4241e1a8a56 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 21 May 2021 16:30:37 +0100 Subject: [PATCH 1/7] Adding ability to create new admins. --- .../portal/manage/users/[userId].svelte | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte index bbd2e079e0..9ad2d1c09f 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte @@ -17,7 +17,7 @@ notifications, } from "@budibase/bbui" import { fetchData } from "helpers" - import { users } from "stores/portal" + import { users, auth } from "stores/portal" import TagsRenderer from "./_components/TagsTableRenderer.svelte" import UpdateRolesModal from "./_components/UpdateRolesModal.svelte" @@ -56,13 +56,21 @@ let toggleDisabled = false - async function toggleBuilderAccess({ detail }) { + async function toggleFlag(flagName, detail) { toggleDisabled = true - await users.save({ ...$userFetch?.data, builder: { global: detail } }) + await users.save({ ...$userFetch?.data, [flagName]: { global: detail } }) await userFetch.refresh() toggleDisabled = false } + async function toggleBuilderAccess({ detail }) { + return toggleFlag("builder", detail) + } + + async function toggleAdminAccess({ detail }) { + return toggleFlag("admin", detail) + } + async function openUpdateRolesModal({ detail }) { selectedApp = detail editRolesModal.show() @@ -107,15 +115,27 @@ -
- - -
+ + {#if userId !== $auth.user._id} +
+ + +
+
+ + +
+ {/if}
Date: Fri, 21 May 2021 16:43:01 +0100 Subject: [PATCH 2/7] Updating administration middleware so that internal requests allowed through automatically. --- packages/auth/src/middleware/authenticated.js | 1 + .../builder/portal/manage/users/index.svelte | 2 ++ packages/worker/src/api/routes/admin/email.js | 2 ++ packages/worker/src/api/routes/admin/users.js | 19 ++++++++++--------- packages/worker/src/middleware/adminOnly.js | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/auth/src/middleware/authenticated.js b/packages/auth/src/middleware/authenticated.js index 34ed0ec186..5d9056b19a 100644 --- a/packages/auth/src/middleware/authenticated.js +++ b/packages/auth/src/middleware/authenticated.js @@ -43,6 +43,7 @@ module.exports = (noAuthPatterns = [], opts) => { // this is an internal request, no user made it if (apiKey && apiKey === env.INTERNAL_API_KEY) { ctx.isAuthenticated = true + ctx.internal = true } else if (authCookie) { try { const db = database.getDB(StaticDatabases.GLOBAL.name) diff --git a/packages/builder/src/pages/builder/portal/manage/users/index.svelte b/packages/builder/src/pages/builder/portal/manage/users/index.svelte index d88577c91b..0c136574d7 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/index.svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/index.svelte @@ -22,6 +22,7 @@ const schema = { email: {}, developmentAccess: { displayName: "Development Access", type: "boolean" }, + adminAccess: { displayName: "Admin Access", type: "boolean" }, // role: { type: "options" }, group: {}, // access: {}, @@ -36,6 +37,7 @@ ...user, group: ["All users"], developmentAccess: user.builder.global, + adminAccess: user.admin.global, })) let createUserModal diff --git a/packages/worker/src/api/routes/admin/email.js b/packages/worker/src/api/routes/admin/email.js index d3d0d4faae..a36dc5de91 100644 --- a/packages/worker/src/api/routes/admin/email.js +++ b/packages/worker/src/api/routes/admin/email.js @@ -2,6 +2,7 @@ const Router = require("@koa/router") const controller = require("../../controllers/admin/email") const { EmailTemplatePurpose } = require("../../../constants") const joiValidator = require("../../../middleware/joi-validator") +const adminOnly = require("../../../middleware/adminOnly") const Joi = require("joi") const router = Router() @@ -21,6 +22,7 @@ function buildEmailSendValidation() { router.post( "/api/admin/email/send", buildEmailSendValidation(), + adminOnly, controller.sendEmail ) diff --git a/packages/worker/src/api/routes/admin/users.js b/packages/worker/src/api/routes/admin/users.js index 1e7461fd26..6a6654f5e6 100644 --- a/packages/worker/src/api/routes/admin/users.js +++ b/packages/worker/src/api/routes/admin/users.js @@ -54,16 +54,9 @@ router buildUserSaveValidation(), controller.save ) - .get("/api/admin/users", controller.fetch) - .post("/api/admin/users/init", controller.adminUser) - .get("/api/admin/users/self", controller.getSelf) - .post( - "/api/admin/users/self", - buildUserSaveValidation(true), - controller.updateSelf - ) + .get("/api/admin/users", adminOnly, controller.fetch) .delete("/api/admin/users/:id", adminOnly, controller.destroy) - .get("/api/admin/users/:id", controller.find) + .get("/api/admin/users/:id", adminOnly, controller.find) .get("/api/admin/roles/:appId") .post( "/api/admin/users/invite", @@ -71,10 +64,18 @@ router buildInviteValidation(), controller.invite ) + // non-admin endpoints + .post( + "/api/admin/users/self", + buildUserSaveValidation(true), + controller.updateSelf + ) .post( "/api/admin/users/invite/accept", buildInviteAcceptValidation(), controller.inviteAccept ) + .post("/api/admin/users/init", controller.adminUser) + .get("/api/admin/users/self", controller.getSelf) module.exports = router diff --git a/packages/worker/src/middleware/adminOnly.js b/packages/worker/src/middleware/adminOnly.js index 507fbda9a2..8f56eb7943 100644 --- a/packages/worker/src/middleware/adminOnly.js +++ b/packages/worker/src/middleware/adminOnly.js @@ -1,5 +1,5 @@ module.exports = async (ctx, next) => { - if (!ctx.user || !ctx.user.admin || !ctx.user.admin.global) { + if (!ctx.internal && (!ctx.user || !ctx.user.admin || !ctx.user.admin.global)) { ctx.throw(403, "Admin user only endpoint.") } return next() From 59de40c4ef93c677cde7456f03575f17e685ae29 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 21 May 2021 17:12:25 +0100 Subject: [PATCH 3/7] Formatting and adding routing checks to push the user out of admin menus when they are not an admin. --- .../pages/builder/portal/manage/auth/_layout.svelte | 7 +++++++ .../pages/builder/portal/manage/email/_layout.svelte | 9 ++++++++- .../pages/builder/portal/manage/users/[userId].svelte | 8 ++++---- .../pages/builder/portal/manage/users/_layout.svelte | 7 +++++++ .../src/pages/builder/portal/settings/index.svelte | 2 +- .../pages/builder/portal/settings/organisation.svelte | 8 +++++++- packages/builder/src/stores/portal/auth.js | 11 ++++++++++- packages/worker/src/api/routes/admin/users.js | 3 ++- packages/worker/src/middleware/adminOnly.js | 5 ++++- 9 files changed, 50 insertions(+), 10 deletions(-) diff --git a/packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte b/packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte index f9c2067a94..12cbf48b22 100644 --- a/packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte +++ b/packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte @@ -1,5 +1,12 @@ diff --git a/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte b/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte index 188f0bb016..22e786bcb9 100644 --- a/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte +++ b/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte @@ -1,5 +1,12 @@ diff --git a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte index b9cfe1cc7d..983b31168c 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/[userId].svelte @@ -129,10 +129,10 @@
{/if} diff --git a/packages/builder/src/pages/builder/portal/manage/users/_layout.svelte b/packages/builder/src/pages/builder/portal/manage/users/_layout.svelte index f9c2067a94..8b8295d2a3 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/_layout.svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/_layout.svelte @@ -1,5 +1,12 @@ diff --git a/packages/builder/src/pages/builder/portal/settings/index.svelte b/packages/builder/src/pages/builder/portal/settings/index.svelte index 9e264e0583..57825a095b 100644 --- a/packages/builder/src/pages/builder/portal/settings/index.svelte +++ b/packages/builder/src/pages/builder/portal/settings/index.svelte @@ -1,4 +1,4 @@ diff --git a/packages/builder/src/pages/builder/portal/settings/organisation.svelte b/packages/builder/src/pages/builder/portal/settings/organisation.svelte index ec278fa0e4..938e48039e 100644 --- a/packages/builder/src/pages/builder/portal/settings/organisation.svelte +++ b/packages/builder/src/pages/builder/portal/settings/organisation.svelte @@ -11,10 +11,16 @@ Dropzone, notifications, } from "@budibase/bbui" - import { organisation } from "stores/portal" + import { auth, organisation } from "stores/portal" import { post } from "builderStore/api" import analytics from "analytics" import { writable } from "svelte/store" + import { redirect } from "@roxi/routify" + + // only admins allowed here + if (!$auth.isAdmin) { + $redirect("../../portal") + } const values = writable({ analytics: !analytics.disabled(), diff --git a/packages/builder/src/stores/portal/auth.js b/packages/builder/src/stores/portal/auth.js index 517aad9fc4..d0739f2a0f 100644 --- a/packages/builder/src/stores/portal/auth.js +++ b/packages/builder/src/stores/portal/auth.js @@ -5,19 +5,27 @@ export function createAuthStore() { const user = writable(null) const store = derived(user, $user => { let initials = null + let isAdmin = false + let isBuilder = false if ($user) { if ($user.firstName) { initials = $user.firstName[0] if ($user.lastName) { initials += $user.lastName[0] } - } else { + } else if ($user.email) { initials = $user.email[0] + } else { + initials = "Unknown" } + isAdmin = !!$user.admin?.global + isBuilder = !!$user.builder?.global } return { user: $user, initials, + isAdmin, + isBuilder, } }) @@ -29,6 +37,7 @@ export function createAuthStore() { user.set(null) } else { const json = await response.json() + console.log(json) user.set(json) } }, diff --git a/packages/worker/src/api/routes/admin/users.js b/packages/worker/src/api/routes/admin/users.js index 6a6654f5e6..f334f05e7d 100644 --- a/packages/worker/src/api/routes/admin/users.js +++ b/packages/worker/src/api/routes/admin/users.js @@ -56,7 +56,6 @@ router ) .get("/api/admin/users", adminOnly, controller.fetch) .delete("/api/admin/users/:id", adminOnly, controller.destroy) - .get("/api/admin/users/:id", adminOnly, controller.find) .get("/api/admin/roles/:appId") .post( "/api/admin/users/invite", @@ -77,5 +76,7 @@ router ) .post("/api/admin/users/init", controller.adminUser) .get("/api/admin/users/self", controller.getSelf) + // admin endpoint but needs to come at end (blocks other endpoints otherwise) + .get("/api/admin/users/:id", adminOnly, controller.find) module.exports = router diff --git a/packages/worker/src/middleware/adminOnly.js b/packages/worker/src/middleware/adminOnly.js index 8f56eb7943..4bfdf83848 100644 --- a/packages/worker/src/middleware/adminOnly.js +++ b/packages/worker/src/middleware/adminOnly.js @@ -1,5 +1,8 @@ module.exports = async (ctx, next) => { - if (!ctx.internal && (!ctx.user || !ctx.user.admin || !ctx.user.admin.global)) { + if ( + !ctx.internal && + (!ctx.user || !ctx.user.admin || !ctx.user.admin.global) + ) { ctx.throw(403, "Admin user only endpoint.") } return next() From 0838a45efc91f70ef5ec532b2eaf29c50b0348c9 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 21 May 2021 17:19:13 +0100 Subject: [PATCH 4/7] Fixing issue with users that don't have admin structure. --- .../src/pages/builder/portal/manage/users/index.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/pages/builder/portal/manage/users/index.svelte b/packages/builder/src/pages/builder/portal/manage/users/index.svelte index 284591c4e6..6d2134ad02 100644 --- a/packages/builder/src/pages/builder/portal/manage/users/index.svelte +++ b/packages/builder/src/pages/builder/portal/manage/users/index.svelte @@ -36,8 +36,8 @@ .map(user => ({ ...user, group: ["All users"], - developmentAccess: user.builder.global, - adminAccess: user.admin.global, + developmentAccess: !!user.builder?.global, + adminAccess: !!user.admin?.global, })) let createUserModal From 1f1431344ccf31734a39b95c68b5f4f40e14268e Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Mon, 24 May 2021 12:40:36 +0100 Subject: [PATCH 5/7] Prevent flashing and intermittent errors when navigating to admin screens as a non admin --- .../builder/portal/manage/_layout.svelte | 18 +++ .../builder/portal/manage/auth/_layout.svelte | 14 --- .../portal/manage/email/_layout.svelte | 8 +- .../portal/manage/users/_layout.svelte | 14 --- .../portal/settings/organisation.svelte | 118 +++++++++--------- 5 files changed, 80 insertions(+), 92 deletions(-) create mode 100644 packages/builder/src/pages/builder/portal/manage/_layout.svelte delete mode 100644 packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte delete mode 100644 packages/builder/src/pages/builder/portal/manage/users/_layout.svelte diff --git a/packages/builder/src/pages/builder/portal/manage/_layout.svelte b/packages/builder/src/pages/builder/portal/manage/_layout.svelte new file mode 100644 index 0000000000..356b362b0b --- /dev/null +++ b/packages/builder/src/pages/builder/portal/manage/_layout.svelte @@ -0,0 +1,18 @@ + + +{#if $auth.isAdmin} + + + +{/if} diff --git a/packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte b/packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte deleted file mode 100644 index 12cbf48b22..0000000000 --- a/packages/builder/src/pages/builder/portal/manage/auth/_layout.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte b/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte index 22e786bcb9..410a7d4ff2 100644 --- a/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte +++ b/packages/builder/src/pages/builder/portal/manage/email/_layout.svelte @@ -1,11 +1,5 @@ diff --git a/packages/builder/src/pages/builder/portal/manage/users/_layout.svelte b/packages/builder/src/pages/builder/portal/manage/users/_layout.svelte deleted file mode 100644 index 8b8295d2a3..0000000000 --- a/packages/builder/src/pages/builder/portal/manage/users/_layout.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/packages/builder/src/pages/builder/portal/settings/organisation.svelte b/packages/builder/src/pages/builder/portal/settings/organisation.svelte index 938e48039e..046f55615b 100644 --- a/packages/builder/src/pages/builder/portal/settings/organisation.svelte +++ b/packages/builder/src/pages/builder/portal/settings/organisation.svelte @@ -17,9 +17,11 @@ import { writable } from "svelte/store" import { redirect } from "@roxi/routify" - // only admins allowed here - if (!$auth.isAdmin) { - $redirect("../../portal") + // Only admins allowed here + $: { + if (!$auth.isAdmin) { + $redirect("../../portal") + } } const values = writable({ @@ -70,68 +72,70 @@ } - - - Organisation - - Organisation settings is where you can edit your organisation name and - logo. You can also configure your platform URL and enable or disable - analytics. - - - - - Information - Here you can update your logo and organization name. - -
-
- - -
- -
- - - Platform - Here you can set up general platform settings. - -
-
- - -
-
- - +{#if $auth.isAdmin} + - Analytics - - If you would like to send analytics that help us make Budibase better, - please let us know below. + Organisation + + Organisation settings is where you can edit your organisation name and + logo. You can also configure your platform URL and enable or disable + analytics. + + + Information + Here you can update your logo and organization name. +
- - + + +
+
+ + + Platform + Here you can set up general platform settings. + +
+
+ + +
+
+ + + + Analytics + + If you would like to send analytics that help us make Budibase better, + please let us know below. + + +
+
+ + +
+
+
+
+ +
-
- -
-
+{/if}