diff --git a/packages/backend-core/src/security/roles.ts b/packages/backend-core/src/security/roles.ts index a64be6b3197..8cc7422fdb4 100644 --- a/packages/backend-core/src/security/roles.ts +++ b/packages/backend-core/src/security/roles.ts @@ -7,27 +7,15 @@ import { doWithDB, } from "../db" import { getAppDB } from "../context" -import { Screen, Role as RoleDoc } from "@budibase/types" +import { Screen, Role as RoleDoc, BuiltInRole } from "@budibase/types" import cloneDeep from "lodash/fp/cloneDeep" -export const BUILTIN_ROLE_IDS = { - ADMIN: "ADMIN", - POWER: "POWER", - BASIC: "BASIC", - PUBLIC: "PUBLIC", -} - -const BUILTIN_IDS = { - ...BUILTIN_ROLE_IDS, - BUILDER: "BUILDER", -} - // exclude internal roles like builder const EXTERNAL_BUILTIN_ROLE_IDS = [ - BUILTIN_IDS.ADMIN, - BUILTIN_IDS.POWER, - BUILTIN_IDS.BASIC, - BUILTIN_IDS.PUBLIC, + BuiltInRole.ADMIN, + BuiltInRole.POWER, + BuiltInRole.BASIC, + BuiltInRole.PUBLIC, ] export const RoleIDVersion = { @@ -62,22 +50,22 @@ export class Role implements RoleDoc { const BUILTIN_ROLES = { ADMIN: new Role( - BUILTIN_IDS.ADMIN, + BuiltInRole.ADMIN, "Admin", BuiltinPermissionID.ADMIN - ).addInheritance(BUILTIN_IDS.POWER), + ).addInheritance(BuiltInRole.POWER), POWER: new Role( - BUILTIN_IDS.POWER, + BuiltInRole.POWER, "Power", BuiltinPermissionID.POWER - ).addInheritance(BUILTIN_IDS.BASIC), + ).addInheritance(BuiltInRole.BASIC), BASIC: new Role( - BUILTIN_IDS.BASIC, + BuiltInRole.BASIC, "Basic", BuiltinPermissionID.WRITE - ).addInheritance(BUILTIN_IDS.PUBLIC), - PUBLIC: new Role(BUILTIN_IDS.PUBLIC, "Public", BuiltinPermissionID.PUBLIC), - BUILDER: new Role(BUILTIN_IDS.BUILDER, "Builder", BuiltinPermissionID.ADMIN), + ).addInheritance(BuiltInRole.PUBLIC), + PUBLIC: new Role(BuiltInRole.PUBLIC, "Public", BuiltinPermissionID.PUBLIC), + BUILDER: new Role(BuiltInRole.BUILDER, "Builder", BuiltinPermissionID.ADMIN), } export function getBuiltinRoles(): { [key: string]: RoleDoc } { @@ -104,7 +92,7 @@ export function getBuiltinRole(roleId: string): Role | undefined { export function builtinRoleToNumber(id: string) { const builtins = getBuiltinRoles() const MAX = Object.values(builtins).length + 1 - if (id === BUILTIN_IDS.ADMIN || id === BUILTIN_IDS.BUILDER) { + if (id === BuiltInRole.ADMIN || id === BuiltInRole.BUILDER) { return MAX } let role = builtins[id], @@ -196,7 +184,7 @@ async function getAllUserRoles( opts?: { defaultPublic?: boolean } ): Promise { // admins have access to all roles - if (userRoleId === BUILTIN_IDS.ADMIN) { + if (userRoleId === BuiltInRole.ADMIN) { return getAllRoles() } let currentRole = await getRole(userRoleId, opts) @@ -338,8 +326,8 @@ export class AccessController { tryingRoleId == null || tryingRoleId === "" || tryingRoleId === userRoleId || - tryingRoleId === BUILTIN_IDS.BUILDER || - userRoleId === BUILTIN_IDS.BUILDER + tryingRoleId === BuiltInRole.BUILDER || + userRoleId === BuiltInRole.BUILDER ) { return true } diff --git a/packages/backend-core/src/security/tests/permissions.spec.ts b/packages/backend-core/src/security/tests/permissions.spec.ts index 39348646fb8..154360ce5e2 100644 --- a/packages/backend-core/src/security/tests/permissions.spec.ts +++ b/packages/backend-core/src/security/tests/permissions.spec.ts @@ -1,6 +1,6 @@ import cloneDeep from "lodash/cloneDeep" import * as permissions from "../permissions" -import { BUILTIN_ROLE_IDS } from "../roles" +import { BuiltInRole } from "@budibase/types" describe("levelToNumber", () => { it("should return 0 for EXECUTE", () => { @@ -76,7 +76,7 @@ describe("doesHaveBasePermission", () => { const permLevel = permissions.PermissionLevel.READ const rolesHierarchy = [ { - roleId: BUILTIN_ROLE_IDS.ADMIN, + roleId: BuiltInRole.ADMIN, permissionId: permissions.BuiltinPermissionID.ADMIN, }, ] @@ -90,7 +90,7 @@ describe("doesHaveBasePermission", () => { const permLevel = permissions.PermissionLevel.READ const rolesHierarchy = [ { - roleId: BUILTIN_ROLE_IDS.PUBLIC, + roleId: BuiltInRole.PUBLIC, permissionId: permissions.BuiltinPermissionID.PUBLIC, }, ] diff --git a/packages/backend-core/src/users/test/utils.spec.ts b/packages/backend-core/src/users/test/utils.spec.ts index cb98b8972bb..bef537d0977 100644 --- a/packages/backend-core/src/users/test/utils.spec.ts +++ b/packages/backend-core/src/users/test/utils.spec.ts @@ -1,4 +1,4 @@ -import { User, UserGroup } from "@budibase/types" +import { BuiltInRole, User, UserGroup } from "@budibase/types" import { generator, structures } from "../../../tests" import { DBTestConfiguration } from "../../../tests/extra" import { getGlobalDB } from "../../context" @@ -28,12 +28,16 @@ describe("Users", () => { }) it("User is a creator if it has CREATOR permission in some application", async () => { - const user: User = structures.users.user({ roles: { app1: "CREATOR" } }) + const user: User = structures.users.user({ + roles: { app1: BuiltInRole.CREATOR }, + }) expect(await isCreator(user)).toBe(true) }) it("User is a creator if it has ADMIN permission in some application", async () => { - const user: User = structures.users.user({ roles: { app1: "ADMIN" } }) + const user: User = structures.users.user({ + roles: { app1: BuiltInRole.ADMIN }, + }) expect(await isCreator(user)).toBe(true) }) @@ -42,7 +46,7 @@ describe("Users", () => { const groupId = "gr_17abffe89e0b40268e755b952f101a59" const group: UserGroup = { ...structures.userGroups.userGroup(), - ...{ _id: groupId, roles: { app1: "ADMIN" } }, + ...{ _id: groupId, roles: { app1: BuiltInRole.ADMIN } }, } const users: User[] = [] for (let i = 0; i < usersInGroup; i++) { diff --git a/packages/backend-core/src/users/utils.ts b/packages/backend-core/src/users/utils.ts index 348ad1532f6..60c075e4ded 100644 --- a/packages/backend-core/src/users/utils.ts +++ b/packages/backend-core/src/users/utils.ts @@ -1,4 +1,10 @@ -import { CloudAccount, ContextUser, User, UserGroup } from "@budibase/types" +import { + CloudAccount, + ContextUser, + User, + UserGroup, + BuiltInRole as BUILTIN_ROLE_IDS, +} from "@budibase/types" import * as accountSdk from "../accounts" import env from "../environment" import { getPlatformUser } from "./lookup" @@ -6,7 +12,6 @@ import { EmailUnavailableError } from "../errors" import { getTenantId } from "../context" import { sdk } from "@budibase/shared-core" import { getAccountByTenantId } from "../accounts" -import { BUILTIN_ROLE_IDS } from "../security/roles" import * as context from "../context" // extract from shared-core to make easily accessible from backend-core diff --git a/packages/builder/src/components/common/RoleSelect.svelte b/packages/builder/src/components/common/RoleSelect.svelte index 4605b0c182d..0f1f4d8edbe 100644 --- a/packages/builder/src/components/common/RoleSelect.svelte +++ b/packages/builder/src/components/common/RoleSelect.svelte @@ -4,6 +4,7 @@ import { licensing } from "stores/portal" import { Constants, RoleUtils } from "@budibase/frontend-core" + import { BuiltInRole } from "@budibase/types" import { createEventDispatcher } from "svelte" import { capitalise } from "helpers" @@ -51,9 +52,9 @@ name: enrichLabel(role.name), _id: role._id, })) - if (allowedRoles.includes(Constants.Roles.CREATOR)) { + if (allowedRoles.includes(BuiltInRole.CREATOR)) { options.push({ - _id: Constants.Roles.CREATOR, + _id: BuiltInRole.CREATOR, name: "Can edit", enabled: false, }) @@ -70,7 +71,7 @@ // Add creator if required if (allowCreator) { options.unshift({ - _id: Constants.Roles.CREATOR, + _id: BuiltInRole.CREATOR, name: "Can edit", tag: !$licensing.perAppBuildersEnabled && @@ -88,7 +89,7 @@ // Remove public if not allowed if (!allowPublic) { - options = options.filter(role => role._id !== Constants.Roles.PUBLIC) + options = options.filter(role => role._id !== BuiltInRole.PUBLIC) } return options @@ -96,7 +97,7 @@ const getColor = role => { // Creator and remove options have no colors - if (role._id === Constants.Roles.CREATOR || role._id === RemoveID) { + if (role._id === BuiltInRole.CREATOR || role._id === RemoveID) { return null } return RoleUtils.getRoleColour(role._id) @@ -135,8 +136,7 @@ getOptionColour={getColor} getOptionIcon={getIcon} isOptionEnabled={option => - option._id !== Constants.Roles.CREATOR || - $licensing.perAppBuildersEnabled} + option._id !== BuiltInRole.CREATOR || $licensing.perAppBuildersEnabled} {placeholder} {error} /> @@ -155,7 +155,7 @@ getOptionColour={getColor} getOptionIcon={getIcon} isOptionEnabled={option => - (option._id !== Constants.Roles.CREATOR || + (option._id !== BuiltInRole.CREATOR || $licensing.perAppBuildersEnabled) && option.enabled !== false} {placeholder} diff --git a/packages/builder/src/components/integration/AccessLevelSelect.svelte b/packages/builder/src/components/integration/AccessLevelSelect.svelte index 05b336c3b3c..68ee85dce17 100644 --- a/packages/builder/src/components/integration/AccessLevelSelect.svelte +++ b/packages/builder/src/components/integration/AccessLevelSelect.svelte @@ -1,7 +1,7 @@ @@ -660,7 +661,7 @@ autoWidth align="right" allowedRoles={user.isAdminOrGlobalBuilder - ? [Constants.Roles.CREATOR] + ? [BuiltInRole.CREATOR] : null} labelPrefix="Can use as" /> @@ -706,7 +707,7 @@ allowRemove={group.role} allowPublic={false} quiet={true} - allowCreator={group.role === Constants.Roles.CREATOR} + allowCreator={group.role === BuiltInRole.CREATOR} on:change={e => { onUpdateGroup(group, e.detail) }} @@ -747,7 +748,7 @@ quiet={true} on:addcreator={() => {}} on:change={e => { - if (e.detail === Constants.Roles.CREATOR) { + if (e.detail === BuiltInRole.CREATOR) { addAppBuilder(user._id) } else { onUpdateUser(user, e.detail) @@ -759,7 +760,7 @@ autoWidth align="right" allowedRoles={user.isAdminOrGlobalBuilder - ? [Constants.Roles.CREATOR] + ? [BuiltInRole.CREATOR] : null} labelPrefix="Can use as" /> @@ -832,7 +833,7 @@ align="right" fancySelect allowedRoles={creationRoleType === Constants.BudibaseRoles.Admin - ? [Constants.Roles.CREATOR] + ? [BuiltInRole.CREATOR] : null} footer={getRoleFooter({ isAdminOrGlobalBuilder: diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/NavItemConfiguration.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/NavItemConfiguration.svelte index db55f501f0a..10cf35246d4 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/NavItemConfiguration.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Navigation/NavItemConfiguration.svelte @@ -4,7 +4,7 @@ import NavItem from "./NavItem.svelte" import { generate } from "shortid" import { getSequentialName } from "helpers/duplicate" - import { Constants } from "@budibase/frontend-core" + import { BuiltInRole } from "@budibase/types" export let bindings @@ -52,7 +52,7 @@ getName: x => x.text, }), url: "", - roleId: Constants.Roles.BASIC, + roleId: BuiltInRole.BASIC, type: "link", }, ]) diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/RoleIndicator.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/RoleIndicator.svelte index 4b7f26709c8..d730549ca59 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/RoleIndicator.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/_components/ScreenList/RoleIndicator.svelte @@ -2,7 +2,7 @@ import { RoleUtils } from "@budibase/frontend-core" import { Tooltip, StatusLight } from "@budibase/bbui" import { roles } from "stores/builder" - import { Roles } from "constants/backend" + import { BuiltInRole } from "@budibase/types" export let roleId @@ -11,7 +11,7 @@ $: color = RoleUtils.getRoleColour(roleId) $: role = $roles.find(role => role._id === roleId) $: tooltip = - roleId === Roles.PUBLIC + roleId === BuiltInRole.PUBLIC ? "Open to the public" : `Requires ${role?.name} access` diff --git a/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte b/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte index 68d74218c8d..fc9955b1536 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/_components/NewScreen/CreateScreenModal.svelte @@ -14,7 +14,7 @@ import { auth } from "stores/portal" import { get } from "svelte/store" import getTemplates from "templates" - import { Roles } from "constants/backend" + import { BuiltInRole } from "@budibase/types" import { capitalise } from "helpers" import { goto } from "@roxi/routify" import { TOUR_KEYS } from "components/portal/onboarding/tours.js" @@ -32,7 +32,7 @@ let formTypeModal // Cache variables for workflow - let screenAccessRole = Roles.BASIC + let screenAccessRole = BuiltInRole.BASIC let templates = null let screens = null @@ -126,7 +126,7 @@ blankScreenUrl = null screenMode = mode pendingScreen = null - screenAccessRole = Roles.BASIC + screenAccessRole = BuiltInRole.BASIC formType = null if (mode === "grid" || mode === "gridDetails" || mode === "form") { diff --git a/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte b/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte index 36ec43b6b39..0700903aa33 100644 --- a/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte +++ b/packages/builder/src/pages/builder/portal/users/groups/[groupId].svelte @@ -21,7 +21,7 @@ import GroupIcon from "./_components/GroupIcon.svelte" import GroupUsers from "./_components/GroupUsers.svelte" import { sdk } from "@budibase/shared-core" - import { Constants } from "@budibase/frontend-core" + import { BuiltInRole } from "@budibase/types" export let groupId @@ -60,7 +60,7 @@ .map(app => ({ ...app, role: group?.builder?.apps.includes(appsStore.getProdAppID(app.devId)) - ? Constants.Roles.CREATOR + ? BuiltInRole.CREATOR : group?.roles?.[appsStore.getProdAppID(app.devId)], })) diff --git a/packages/builder/src/pages/builder/portal/users/users/[userId].svelte b/packages/builder/src/pages/builder/portal/users/users/[userId].svelte index d4e765a4be3..9d1e63efb0c 100644 --- a/packages/builder/src/pages/builder/portal/users/users/[userId].svelte +++ b/packages/builder/src/pages/builder/portal/users/users/[userId].svelte @@ -31,6 +31,7 @@ import AppNameTableRenderer from "./_components/AppNameTableRenderer.svelte" import AppRoleTableRenderer from "./_components/AppRoleTableRenderer.svelte" import { sdk } from "@budibase/shared-core" + import { BuiltInRole } from "@budibase/types" import ActiveDirectoryInfo from "../_components/ActiveDirectoryInfo.svelte" export let userId @@ -136,11 +137,11 @@ const getRole = (prodAppId, roles) => { if (privileged) { - return Constants.Roles.ADMIN + return BuiltInRole.ADMIN } if (user?.builder?.apps?.includes(prodAppId)) { - return Constants.Roles.CREATOR + return BuiltInRole.CREATOR } return roles[prodAppId] diff --git a/packages/builder/src/pages/builder/portal/users/users/_components/AppRoleTableRenderer.svelte b/packages/builder/src/pages/builder/portal/users/users/_components/AppRoleTableRenderer.svelte index 0f19bb3e1f9..878f50b8cd4 100644 --- a/packages/builder/src/pages/builder/portal/users/users/_components/AppRoleTableRenderer.svelte +++ b/packages/builder/src/pages/builder/portal/users/users/_components/AppRoleTableRenderer.svelte @@ -1,20 +1,21 @@ -{#if value === Constants.Roles.CREATOR} +{#if value === BuiltInRole.CREATOR} Can edit {:else} diff --git a/packages/builder/src/stores/builder/tests/screens.test.js b/packages/builder/src/stores/builder/tests/screens.test.js index 51e3a8d830c..37149ed302a 100644 --- a/packages/builder/src/stores/builder/tests/screens.test.js +++ b/packages/builder/src/stores/builder/tests/screens.test.js @@ -1,7 +1,7 @@ import { it, expect, describe, beforeEach, vi } from "vitest" import { get, writable } from "svelte/store" import { API } from "api" -import { Constants } from "@budibase/frontend-core" +import { BuiltInRole } from "@budibase/types" import { componentStore, appStore } from "stores/builder" import { INITIAL_SCREENS_STATE, ScreenStore } from "stores/builder/screens" import { @@ -603,7 +603,7 @@ describe("Screens store", () => { const storeScreens = existingScreens .map(screen => screen.json()) - .filter(screen => screen.routing.roleId == Constants.Roles.BASIC) + .filter(screen => screen.routing.roleId == BuiltInRole.BASIC) // All default screens have the BASIC role expect(storeScreens.length).toBe(3) @@ -645,10 +645,10 @@ describe("Screens store", () => { it("Ensure only one homescreen per role when updating screen setting. Multiple screen roles", async ctx => { const expectedRoles = [ - Constants.Roles.BASIC, - Constants.Roles.POWER, - Constants.Roles.PUBLIC, - Constants.Roles.ADMIN, + BuiltInRole.BASIC, + BuiltInRole.POWER, + BuiltInRole.PUBLIC, + BuiltInRole.ADMIN, ] // Build 12 screens, 3 of each role @@ -708,17 +708,17 @@ describe("Screens store", () => { const screens = ctx.test.store.screens // Should still only be one of each homescreen - expect(results[Constants.Roles.ADMIN].length).toBe(1) + expect(results[BuiltInRole.ADMIN].length).toBe(1) expect(screens[2].routing.homeScreen).toBe(true) - expect(results[Constants.Roles.BASIC].length).toBe(1) + expect(results[BuiltInRole.BASIC].length).toBe(1) expect(screens[4].routing.homeScreen).toBe(true) - expect(results[Constants.Roles.PUBLIC].length).toBe(1) + expect(results[BuiltInRole.PUBLIC].length).toBe(1) expect(screens[9].routing.homeScreen).toBe(true) // Homescreen was never set for POWER - expect(results[Constants.Roles.POWER]).not.toBeDefined() + expect(results[BuiltInRole.POWER]).not.toBeDefined() // Once to update the target screen, once to unset the existing homescreen. expect(patchSpy).toBeCalledTimes(2) diff --git a/packages/client/src/components/app/Layout.svelte b/packages/client/src/components/app/Layout.svelte index 72da3e90120..8235cb256f7 100644 --- a/packages/client/src/components/app/Layout.svelte +++ b/packages/client/src/components/app/Layout.svelte @@ -2,7 +2,7 @@ import { getContext, setContext } from "svelte" import { writable } from "svelte/store" import { Heading, Icon, clickOutside } from "@budibase/bbui" - import { Constants } from "@budibase/frontend-core" + import { BuiltInRole } from "@budibase/types" import NavItem from "./NavItem.svelte" const sdk = getContext("sdk") @@ -130,7 +130,7 @@ } // Filter to only links allowed by the current role - const role = navItem.roleId || Constants.Roles.BASIC + const role = navItem.roleId || BuiltInRole.BASIC return userRoleHierarchy?.find(roleId => roleId === role) }) .map(navItem => { diff --git a/packages/client/src/stores/derived/currentRole.js b/packages/client/src/stores/derived/currentRole.js index 8bb4c5a25d7..69eb9371a45 100644 --- a/packages/client/src/stores/derived/currentRole.js +++ b/packages/client/src/stores/derived/currentRole.js @@ -1,8 +1,8 @@ import { derived } from "svelte/store" -import { Constants } from "@budibase/frontend-core" import { devToolsStore } from "../devTools.js" import { authStore } from "../auth.js" import { devToolsEnabled } from "./devToolsEnabled.js" +import { BuiltInRole } from "@budibase/types" // Derive the current role of the logged-in user export const currentRole = derived( @@ -11,7 +11,7 @@ export const currentRole = derived( return ( ($devToolsEnabled && $devToolsStore.role) || $authStore?.roleId || - Constants.Roles.PUBLIC + BuiltInRole.PUBLIC ) } ) diff --git a/packages/frontend-core/src/constants.js b/packages/frontend-core/src/constants.js index 0d6261f5f89..d278ebd2ce7 100644 --- a/packages/frontend-core/src/constants.js +++ b/packages/frontend-core/src/constants.js @@ -77,16 +77,6 @@ export const PlanType = { */ export const ApiVersion = "1" -// Role IDs -export const Roles = { - ADMIN: "ADMIN", - POWER: "POWER", - BASIC: "BASIC", - PUBLIC: "PUBLIC", - BUILDER: "BUILDER", - CREATOR: "CREATOR", -} - export const Themes = [ { class: "lightest", diff --git a/packages/frontend-core/src/utils/roles.js b/packages/frontend-core/src/utils/roles.js index 1ae9d3ac142..d8fadc2bb9d 100644 --- a/packages/frontend-core/src/utils/roles.js +++ b/packages/frontend-core/src/utils/roles.js @@ -1,18 +1,18 @@ -import { Roles } from "../constants" +import { BuiltInRole } from "@budibase/types" const RolePriorities = { - [Roles.ADMIN]: 5, - [Roles.CREATOR]: 4, - [Roles.POWER]: 3, - [Roles.BASIC]: 2, - [Roles.PUBLIC]: 1, + [BuiltInRole.ADMIN]: 5, + [BuiltInRole.CREATOR]: 4, + [BuiltInRole.POWER]: 3, + [BuiltInRole.BASIC]: 2, + [BuiltInRole.PUBLIC]: 1, } const RoleColours = { - [Roles.ADMIN]: "var(--spectrum-global-color-static-red-400)", - [Roles.CREATOR]: "var(--spectrum-global-color-static-magenta-600)", - [Roles.POWER]: "var(--spectrum-global-color-static-orange-400)", - [Roles.BASIC]: "var(--spectrum-global-color-static-green-400)", - [Roles.PUBLIC]: "var(--spectrum-global-color-static-blue-400)", + [BuiltInRole.ADMIN]: "var(--spectrum-global-color-static-red-400)", + [BuiltInRole.CREATOR]: "var(--spectrum-global-color-static-magenta-600)", + [BuiltInRole.POWER]: "var(--spectrum-global-color-static-orange-400)", + [BuiltInRole.BASIC]: "var(--spectrum-global-color-static-green-400)", + [BuiltInRole.PUBLIC]: "var(--spectrum-global-color-static-blue-400)", } export const getRolePriority = role => { diff --git a/packages/server/src/api/controllers/auth.ts b/packages/server/src/api/controllers/auth.ts index 4ff592534df..2e08cc552b4 100644 --- a/packages/server/src/api/controllers/auth.ts +++ b/packages/server/src/api/controllers/auth.ts @@ -1,13 +1,11 @@ import { outputProcessing } from "../../utilities/rowProcessor" import { InternalTables } from "../../db/utils" import { getFullUser } from "../../utilities/users" -import { roles, context, db as dbCore } from "@budibase/backend-core" -import { ContextUser, Row, UserCtx } from "@budibase/types" +import { context, db as dbCore } from "@budibase/backend-core" +import { BuiltInRole, ContextUser, Row, UserCtx } from "@budibase/types" import sdk from "../../sdk" import { processUser } from "../../utilities/global" -const PUBLIC_ROLE = roles.BUILTIN_ROLE_IDS.PUBLIC - /** * Add the attributes that are session based to the current user. */ @@ -37,7 +35,7 @@ export async function fetchSelf(ctx: UserCtx) { if (appId) { const db = context.getAppDB() // check for group permissions - if (!user.roleId || user.roleId === PUBLIC_ROLE) { + if (!user.roleId || user.roleId === BuiltInRole.PUBLIC) { user = await processUser(user, { appId }) } // remove the full roles structure @@ -49,7 +47,7 @@ export async function fetchSelf(ctx: UserCtx) { } catch (err: any) { let response // user didn't exist in app, don't pretend they do - if (user.roleId === PUBLIC_ROLE) { + if (user.roleId === BuiltInRole.PUBLIC) { response = {} } // user has a role of some sort, return them diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 06921037dda..a85745c9d99 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -1,5 +1,6 @@ import * as setup from "./utilities" import { + BuiltInRole, CreateViewRequest, Datasource, FieldSchema, @@ -22,7 +23,7 @@ import { generator, mocks } from "@budibase/backend-core/tests" import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" import merge from "lodash/merge" import { quotas } from "@budibase/pro" -import { db, roles } from "@budibase/backend-core" +import { db } from "@budibase/backend-core" describe.each([ ["internal", undefined], @@ -1475,7 +1476,7 @@ describe.each([ it("allow public users to fetch when permissions are explicit", async () => { await config.api.permission.add({ - roleId: roles.BUILTIN_ROLE_IDS.PUBLIC, + roleId: BuiltInRole.PUBLIC, level: PermissionLevel.READ, resourceId: view.id, }) @@ -1488,7 +1489,7 @@ describe.each([ it("allow public users to fetch when permissions are inherited", async () => { await config.api.permission.add({ - roleId: roles.BUILTIN_ROLE_IDS.PUBLIC, + roleId: BuiltInRole.PUBLIC, level: PermissionLevel.READ, resourceId: table._id!, }) @@ -1501,12 +1502,12 @@ describe.each([ it("respects inherited permissions, not allowing not public views from public tables", async () => { await config.api.permission.add({ - roleId: roles.BUILTIN_ROLE_IDS.PUBLIC, + roleId: BuiltInRole.PUBLIC, level: PermissionLevel.READ, resourceId: table._id!, }) await config.api.permission.add({ - roleId: roles.BUILTIN_ROLE_IDS.POWER, + roleId: BuiltInRole.POWER, level: PermissionLevel.READ, resourceId: view.id, }) diff --git a/packages/server/src/constants/index.ts b/packages/server/src/constants/index.ts index 60875b3daab..9352139d9db 100644 --- a/packages/server/src/constants/index.ts +++ b/packages/server/src/constants/index.ts @@ -1,9 +1,10 @@ -import { constants, objectStore, roles } from "@budibase/backend-core" +import { constants, objectStore } from "@budibase/backend-core" import { FieldType, INTERNAL_TABLE_SOURCE_ID, Table, TableSourceType, + BuiltInRole, } from "@budibase/types" import env from "../environment" @@ -113,7 +114,7 @@ export const USERS_TABLE_SCHEMA: Table = { constraints: { type: FieldType.STRING, presence: false, - inclusion: Object.values(roles.BUILTIN_ROLE_IDS), + inclusion: Object.values(BuiltInRole), }, }, status: { diff --git a/packages/server/src/middleware/authorized.ts b/packages/server/src/middleware/authorized.ts index ec8a3711cfa..5a59fb97d29 100644 --- a/packages/server/src/middleware/authorized.ts +++ b/packages/server/src/middleware/authorized.ts @@ -5,7 +5,12 @@ import { roles, users, } from "@budibase/backend-core" -import { PermissionLevel, PermissionType, UserCtx } from "@budibase/types" +import { + BuiltInRole, + PermissionLevel, + PermissionType, + UserCtx, +} from "@budibase/types" import builderMiddleware from "./builder" import { isWebhookEndpoint } from "./utils" import { paramResource } from "./resourceId" @@ -61,7 +66,7 @@ const checkAuthorizedResource = async ( permLevel: PermissionLevel ) => { // get the user's roles - const roleId = ctx.roleId || roles.BUILTIN_ROLE_IDS.PUBLIC + const roleId = ctx.roleId || BuiltInRole.PUBLIC const userRoles = await roles.getUserRoleHierarchy(roleId) const permError = "User does not have permission" // check if the user has the required role @@ -139,9 +144,8 @@ const authorized = // if the resource is public, proceed if ( - resourceRoles.includes(roles.BUILTIN_ROLE_IDS.PUBLIC) || - (otherLevelRoles && - otherLevelRoles.includes(roles.BUILTIN_ROLE_IDS.PUBLIC)) + resourceRoles.includes(BuiltInRole.PUBLIC) || + (otherLevelRoles && otherLevelRoles.includes(BuiltInRole.PUBLIC)) ) { return next() } diff --git a/packages/server/src/middleware/currentapp.ts b/packages/server/src/middleware/currentapp.ts index ad6f2afa181..f1d5b85e61a 100644 --- a/packages/server/src/middleware/currentapp.ts +++ b/packages/server/src/middleware/currentapp.ts @@ -11,7 +11,7 @@ import { generateUserMetadataID, isDevAppID } from "../db/utils" import { getCachedSelf } from "../utilities/global" import env from "../environment" import { isWebhookEndpoint } from "./utils" -import { UserCtx, ContextUser } from "@budibase/types" +import { UserCtx, ContextUser, BuiltInRole } from "@budibase/types" import tracer from "dd-trace" export default async (ctx: UserCtx, next: any) => { @@ -38,7 +38,7 @@ export default async (ctx: UserCtx, next: any) => { } let appId: string | undefined, - roleId = roles.BUILTIN_ROLE_IDS.PUBLIC + roleId = BuiltInRole.PUBLIC if (!ctx.user?._id) { // not logged in, try to set a cookie for public apps appId = requestAppId @@ -47,7 +47,7 @@ export default async (ctx: UserCtx, next: any) => { const globalUser = await getCachedSelf(ctx, requestAppId) appId = requestAppId // retrieving global user gets the right role - roleId = globalUser.roleId || roleId + roleId = (globalUser.roleId as BuiltInRole) || roleId // Allow builders to specify their role via a header const isBuilder = users.isBuilder(globalUser, appId) @@ -60,7 +60,7 @@ export default async (ctx: UserCtx, next: any) => { try { if (roleHeader) { await roles.getRole(roleHeader) - roleId = roleHeader + roleId = roleHeader as BuiltInRole // Delete admin and builder flags so that the specified role is honoured ctx.user = users.removePortalUserPermissions(ctx.user) as ContextUser @@ -99,7 +99,7 @@ export default async (ctx: UserCtx, next: any) => { // clear out the user ctx.user = users.cleanseUserObject(ctx.user) as ContextUser ctx.isAuthenticated = false - roleId = roles.BUILTIN_ROLE_IDS.PUBLIC + roleId = BuiltInRole.PUBLIC // remove the cookie, so future calls are public await auth.platformLogout({ ctx, diff --git a/packages/server/src/utilities/global.ts b/packages/server/src/utilities/global.ts index bbb84c18825..bec7a02a4c8 100644 --- a/packages/server/src/utilities/global.ts +++ b/packages/server/src/utilities/global.ts @@ -1,6 +1,5 @@ import { getGlobalIDFromUserMetadataID } from "../db/utils" import { - roles, db as dbCore, cache, tenancy, @@ -9,7 +8,13 @@ import { } from "@budibase/backend-core" import env from "../environment" import { groups } from "@budibase/pro" -import { UserCtx, ContextUser, User, UserGroup } from "@budibase/types" +import { + UserCtx, + ContextUser, + BuiltInRole, + User, + UserGroup, +} from "@budibase/types" import cloneDeep from "lodash/cloneDeep" export async function processUser( @@ -28,7 +33,7 @@ export async function processUser( // if in a multi-tenancy environment and in wrong tenant make sure roles are never updated if (env.MULTI_TENANCY && appId && !tenancy.isUserInAppTenant(appId, user)) { user = users.removePortalUserPermissions(user) - user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC + user.roleId = BuiltInRole.PUBLIC return user } let groupList: UserGroup[] = [] @@ -50,7 +55,7 @@ export async function processUser( } // builders are always admins within the app if (users.isBuilder(user, appId)) { - user.roleId = roles.BUILTIN_ROLE_IDS.ADMIN + user.roleId = BuiltInRole.ADMIN } // try to get the role from the user list if (!user.roleId && appId && user.roles) { @@ -64,7 +69,7 @@ export async function processUser( } // final fallback, simply couldn't find a role - user must be public if (!user.roleId) { - user.roleId = roles.BUILTIN_ROLE_IDS.PUBLIC + user.roleId = BuiltInRole.PUBLIC } // remove the roles as it is now set delete user.roles diff --git a/packages/shared-core/src/sdk/documents/users.ts b/packages/shared-core/src/sdk/documents/users.ts index 17aa8a1e587..853b0d3d97e 100644 --- a/packages/shared-core/src/sdk/documents/users.ts +++ b/packages/shared-core/src/sdk/documents/users.ts @@ -4,6 +4,7 @@ import { SEPARATOR, User, InternalTable, + BuiltInRole, } from "@budibase/types" import { getProdAppID } from "./applications" import * as _ from "lodash/fp" @@ -67,7 +68,7 @@ export function hasAppCreatorPermissions(user?: User | ContextUser): boolean { return _.flow( _.get("roles"), _.values, - _.find(x => ["CREATOR", "ADMIN"].includes(x)), + _.find(x => [BuiltInRole.CREATOR, BuiltInRole.ADMIN].includes(x)), x => !!x )(user) } diff --git a/packages/types/src/sdk/index.ts b/packages/types/src/sdk/index.ts index d87ec58b0ca..599db67247c 100644 --- a/packages/types/src/sdk/index.ts +++ b/packages/types/src/sdk/index.ts @@ -22,3 +22,4 @@ export * from "./permissions" export * from "./row" export * from "./vm" export * from "./view" +export * from "./roles" diff --git a/packages/types/src/sdk/roles.ts b/packages/types/src/sdk/roles.ts new file mode 100644 index 00000000000..4ac21254329 --- /dev/null +++ b/packages/types/src/sdk/roles.ts @@ -0,0 +1,9 @@ +// Role IDs +export enum BuiltInRole { + ADMIN = "ADMIN", + POWER = "POWER", + BASIC = "BASIC", + PUBLIC = "PUBLIC", + BUILDER = "BUILDER", + CREATOR = "CREATOR", +}