reworking frontend to use shared core functions to check if is admin or builder (needs further expansion).
This commit is contained in:
parent
85dea47a31
commit
e469abb679
|
@ -1,10 +1,8 @@
|
||||||
import { UserCtx } from "@budibase/types"
|
import { UserCtx } from "@budibase/types"
|
||||||
|
import { isAdmin } from "../users"
|
||||||
|
|
||||||
export default async (ctx: UserCtx, next: any) => {
|
export default async (ctx: UserCtx, next: any) => {
|
||||||
if (
|
if (!ctx.internal && !isAdmin(ctx.user)) {
|
||||||
!ctx.internal &&
|
|
||||||
(!ctx.user || !ctx.user.admin || !ctx.user.admin.global)
|
|
||||||
) {
|
|
||||||
ctx.throw(403, "Admin user only endpoint.")
|
ctx.throw(403, "Admin user only endpoint.")
|
||||||
}
|
}
|
||||||
return next()
|
return next()
|
||||||
|
|
|
@ -12,12 +12,12 @@
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import { groups, licensing, apps, users, auth, admin } from "stores/portal"
|
import { groups, licensing, apps, users, auth, admin } from "stores/portal"
|
||||||
import { fetchData } from "@budibase/frontend-core"
|
import { fetchData, Constants, Utils } from "@budibase/frontend-core"
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import GroupIcon from "../../../portal/users/groups/_components/GroupIcon.svelte"
|
import GroupIcon from "../../../portal/users/groups/_components/GroupIcon.svelte"
|
||||||
import RoleSelect from "components/common/RoleSelect.svelte"
|
import RoleSelect from "components/common/RoleSelect.svelte"
|
||||||
import UpgradeModal from "components/common/users/UpgradeModal.svelte"
|
import UpgradeModal from "components/common/users/UpgradeModal.svelte"
|
||||||
import { Constants, Utils } from "@budibase/frontend-core"
|
|
||||||
import { emailValidator } from "helpers/validation"
|
import { emailValidator } from "helpers/validation"
|
||||||
import { roles } from "stores/backend"
|
import { roles } from "stores/backend"
|
||||||
import { fly } from "svelte/transition"
|
import { fly } from "svelte/transition"
|
||||||
|
@ -108,7 +108,7 @@
|
||||||
await usersFetch.refresh()
|
await usersFetch.refresh()
|
||||||
|
|
||||||
filteredUsers = $usersFetch.rows.map(user => {
|
filteredUsers = $usersFetch.rows.map(user => {
|
||||||
const isBuilderOrAdmin = user.admin?.global || user.builder?.global
|
const isBuilderOrAdmin = sdk.users.isBuilderOrAdmin(user, prodAppId)
|
||||||
let role = undefined
|
let role = undefined
|
||||||
if (isBuilderOrAdmin) {
|
if (isBuilderOrAdmin) {
|
||||||
role = Constants.Roles.ADMIN
|
role = Constants.Roles.ADMIN
|
||||||
|
@ -258,7 +258,7 @@
|
||||||
}
|
}
|
||||||
// Must exclude users who have explicit privileges
|
// Must exclude users who have explicit privileges
|
||||||
const userByEmail = filteredUsers.reduce((acc, user) => {
|
const userByEmail = filteredUsers.reduce((acc, user) => {
|
||||||
if (user.role || user.admin?.global || user.builder?.global) {
|
if (user.role || sdk.users.isBuilderOrAdmin(user, prodAppId)) {
|
||||||
acc.push(user.email)
|
acc.push(user.email)
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
|
@ -389,9 +389,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const userTitle = user => {
|
const userTitle = user => {
|
||||||
if (user.admin?.global) {
|
if (sdk.users.isAdmin(user)) {
|
||||||
return "Admin"
|
return "Admin"
|
||||||
} else if (user.builder?.global) {
|
} else if (sdk.users.isBuilder(user, prodAppId)) {
|
||||||
return "Developer"
|
return "Developer"
|
||||||
} else {
|
} else {
|
||||||
return "App user"
|
return "App user"
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
import Spaceman from "assets/bb-space-man.svg"
|
import Spaceman from "assets/bb-space-man.svg"
|
||||||
import Logo from "assets/bb-emblem.svg"
|
import Logo from "assets/bb-emblem.svg"
|
||||||
import { UserAvatar } from "@budibase/frontend-core"
|
import { UserAvatar } from "@budibase/frontend-core"
|
||||||
import { helpers } from "@budibase/shared-core"
|
import { helpers, sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
let userInfoModal
|
let userInfoModal
|
||||||
|
@ -43,32 +43,30 @@
|
||||||
$: userGroups = $groups.filter(group =>
|
$: userGroups = $groups.filter(group =>
|
||||||
group.users.find(user => user._id === $auth.user?._id)
|
group.users.find(user => user._id === $auth.user?._id)
|
||||||
)
|
)
|
||||||
let userApps = []
|
|
||||||
$: publishedApps = $apps.filter(publishedAppsOnly)
|
$: publishedApps = $apps.filter(publishedAppsOnly)
|
||||||
|
$: userApps = getUserApps($auth.user)
|
||||||
|
|
||||||
$: {
|
function getUserApps(user) {
|
||||||
if (!Object.keys($auth.user?.roles).length && $auth.user?.userGroups) {
|
if (sdk.users.isAdmin(user)) {
|
||||||
userApps =
|
return publishedApps
|
||||||
$auth.user?.builder?.global || $auth.user?.admin?.global
|
|
||||||
? publishedApps
|
|
||||||
: publishedApps.filter(app => {
|
|
||||||
return userGroups.find(group => {
|
|
||||||
return groups.actions
|
|
||||||
.getGroupAppIds(group)
|
|
||||||
.map(role => apps.extractAppId(role))
|
|
||||||
.includes(app.appId)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
userApps =
|
|
||||||
$auth.user?.builder?.global || $auth.user?.admin?.global
|
|
||||||
? publishedApps
|
|
||||||
: publishedApps.filter(app =>
|
|
||||||
Object.keys($auth.user?.roles)
|
|
||||||
.map(x => apps.extractAppId(x))
|
|
||||||
.includes(app.appId)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
return publishedApps.filter(app => {
|
||||||
|
if (sdk.users.isBuilder(user, app.appId)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (!Object.keys(user?.roles).length && user?.userGroups) {
|
||||||
|
return userGroups.find(group => {
|
||||||
|
return groups.actions
|
||||||
|
.getGroupAppIds(group)
|
||||||
|
.map(role => apps.extractAppId(role))
|
||||||
|
.includes(app.appId)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return Object.keys($auth.user?.roles)
|
||||||
|
.map(x => apps.extractAppId(x))
|
||||||
|
.includes(app.appId)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUrl(app) {
|
function getUrl(app) {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { redirect } from "@roxi/routify"
|
import { redirect } from "@roxi/routify"
|
||||||
import { auth } from "stores/portal"
|
import { auth } from "stores/portal"
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
auth.checkQueryString()
|
auth.checkQueryString()
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($auth.user?.builder?.global) {
|
if (sdk.users.hasBuilderPermissions($auth.user)) {
|
||||||
$redirect(`./portal`)
|
$redirect(`./portal`)
|
||||||
} else if ($auth.user) {
|
} else if ($auth.user) {
|
||||||
$redirect(`./apps`)
|
$redirect(`./apps`)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import Logo from "./_components/Logo.svelte"
|
import Logo from "./_components/Logo.svelte"
|
||||||
import UserDropdown from "./_components/UserDropdown.svelte"
|
import UserDropdown from "./_components/UserDropdown.svelte"
|
||||||
import HelpMenu from "components/common/HelpMenu.svelte"
|
import HelpMenu from "components/common/HelpMenu.svelte"
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
let loaded = false
|
let loaded = false
|
||||||
let mobileMenuVisible = false
|
let mobileMenuVisible = false
|
||||||
|
@ -33,7 +34,7 @@
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
// Prevent non-builders from accessing the portal
|
// Prevent non-builders from accessing the portal
|
||||||
if ($auth.user) {
|
if ($auth.user) {
|
||||||
if (!$auth.user?.builder?.global) {
|
if (!sdk.users.hasBuilderPermissions($auth.user)) {
|
||||||
$redirect("../")
|
$redirect("../")
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
import AppNameTableRenderer from "./_components/AppNameTableRenderer.svelte"
|
import AppNameTableRenderer from "./_components/AppNameTableRenderer.svelte"
|
||||||
import AppRoleTableRenderer from "./_components/AppRoleTableRenderer.svelte"
|
import AppRoleTableRenderer from "./_components/AppRoleTableRenderer.svelte"
|
||||||
import ScimBanner from "../_components/SCIMBanner.svelte"
|
import ScimBanner from "../_components/SCIMBanner.svelte"
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
export let userId
|
export let userId
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@
|
||||||
$: scimEnabled = $features.isScimEnabled
|
$: scimEnabled = $features.isScimEnabled
|
||||||
$: isSSO = !!user?.provider
|
$: isSSO = !!user?.provider
|
||||||
$: readonly = !$auth.isAdmin || scimEnabled
|
$: readonly = !$auth.isAdmin || scimEnabled
|
||||||
$: privileged = user?.admin?.global || user?.builder?.global
|
$: privileged = sdk.users.isAdminOrBuilder(user)
|
||||||
$: nameLabel = getNameLabel(user)
|
$: nameLabel = getNameLabel(user)
|
||||||
$: filteredGroups = getFilteredGroups($groups, searchTerm)
|
$: filteredGroups = getFilteredGroups($groups, searchTerm)
|
||||||
$: availableApps = getAvailableApps($apps, privileged, user?.roles)
|
$: availableApps = getAvailableApps($apps, privileged, user?.roles)
|
||||||
|
@ -97,9 +98,9 @@
|
||||||
return y._id === userId
|
return y._id === userId
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
$: globalRole = user?.admin?.global
|
$: globalRole = sdk.users.isAdmin(user)
|
||||||
? "admin"
|
? "admin"
|
||||||
: user?.builder?.global
|
: sdk.users.isBuilder(user)
|
||||||
? "developer"
|
? "developer"
|
||||||
: "appUser"
|
: "appUser"
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { Icon } from "@budibase/bbui"
|
import { Icon } from "@budibase/bbui"
|
||||||
import { apps } from "stores/portal"
|
import { apps } from "stores/portal"
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
export let value
|
export let value
|
||||||
export let row
|
export let row
|
||||||
|
|
||||||
$: priviliged = row?.admin?.global || row?.builder?.global
|
$: priviliged = sdk.users.isAdminOrBuilder(row)
|
||||||
$: count = priviliged ? $apps.length : value?.length || 0
|
$: count = priviliged ? $apps.length : value?.length || 0
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { Body, Select, ModalContent, notifications } from "@budibase/bbui"
|
import { Body, Select, ModalContent, notifications } from "@budibase/bbui"
|
||||||
import { users } from "stores/portal"
|
import { users } from "stores/portal"
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
export let app
|
export let app
|
||||||
export let user
|
export let user
|
||||||
|
@ -15,7 +16,7 @@
|
||||||
.filter(role => role._id !== "PUBLIC")
|
.filter(role => role._id !== "PUBLIC")
|
||||||
.map(role => ({ value: role._id, label: role.name }))
|
.map(role => ({ value: role._id, label: role.name }))
|
||||||
|
|
||||||
if (!user?.builder?.global) {
|
if (!sdk.users.isBuilder(user, app?.appId)) {
|
||||||
options.push({ value: NO_ACCESS, label: "No Access" })
|
options.push({ value: NO_ACCESS, label: "No Access" })
|
||||||
}
|
}
|
||||||
let selectedRole = user?.roles?.[app?._id]
|
let selectedRole = user?.roles?.[app?._id]
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { derived, writable, get } from "svelte/store"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import { admin } from "stores/portal"
|
import { admin } from "stores/portal"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
export function createAuthStore() {
|
export function createAuthStore() {
|
||||||
const auth = writable({
|
const auth = writable({
|
||||||
|
@ -17,8 +18,8 @@ export function createAuthStore() {
|
||||||
let isBuilder = false
|
let isBuilder = false
|
||||||
if ($store.user) {
|
if ($store.user) {
|
||||||
const user = $store.user
|
const user = $store.user
|
||||||
isAdmin = !!user.admin?.global
|
isAdmin = sdk.users.isAdmin(user)
|
||||||
isBuilder = !!user.builder?.global
|
isBuilder = sdk.users.isBuilder(user)
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
user: $store.user,
|
user: $store.user,
|
||||||
|
@ -57,8 +58,8 @@ export function createAuthStore() {
|
||||||
name: user.account?.name,
|
name: user.account?.name,
|
||||||
user_id: user._id,
|
user_id: user._id,
|
||||||
tenant: user.tenantId,
|
tenant: user.tenantId,
|
||||||
admin: user?.admin?.global,
|
admin: sdk.users.isAdmin(user),
|
||||||
builder: user?.builder?.global,
|
builder: sdk.users.isBuilder(user),
|
||||||
"Company size": user.account?.size,
|
"Company size": user.account?.size,
|
||||||
"Job role": user.account?.profession,
|
"Job role": user.account?.profession,
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { writable } from "svelte/store"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import { update } from "lodash"
|
import { update } from "lodash"
|
||||||
import { licensing } from "."
|
import { licensing } from "."
|
||||||
|
import { sdk } from "@budibase/shared-core"
|
||||||
|
|
||||||
export function createUsersStore() {
|
export function createUsersStore() {
|
||||||
const { subscribe, set } = writable({})
|
const { subscribe, set } = writable({})
|
||||||
|
@ -111,8 +112,12 @@ export function createUsersStore() {
|
||||||
return await API.saveUser(user)
|
return await API.saveUser(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getUserRole = ({ admin, builder }) =>
|
const getUserRole = user =>
|
||||||
admin?.global ? "admin" : builder?.global ? "developer" : "appUser"
|
sdk.users.isAdmin(user)
|
||||||
|
? "admin"
|
||||||
|
: sdk.users.isBuilder(user)
|
||||||
|
? "developer"
|
||||||
|
: "appUser"
|
||||||
|
|
||||||
const refreshUsage =
|
const refreshUsage =
|
||||||
fn =>
|
fn =>
|
||||||
|
|
|
@ -18,6 +18,10 @@ export function isAdmin(user: User | ContextUser) {
|
||||||
return hasAdminPermissions(user)
|
return hasAdminPermissions(user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isAdminOrBuilder(user: User | ContextUser, appId?: string) {
|
||||||
|
return isBuilder(user, appId) || isAdmin(user)
|
||||||
|
}
|
||||||
|
|
||||||
// checks if a user is capable of building any app
|
// checks if a user is capable of building any app
|
||||||
export function hasBuilderPermissions(user?: User | ContextUser) {
|
export function hasBuilderPermissions(user?: User | ContextUser) {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
|
|
Loading…
Reference in New Issue