budibase/packages/server/src/api/controllers/public/users.ts

101 lines
2.6 KiB
TypeScript
Raw Normal View History

2022-02-25 20:00:12 +01:00
import {
allGlobalUsers,
deleteGlobalUser,
2022-02-25 20:00:12 +01:00
readGlobalUser,
saveGlobalUser,
} from "../../../utilities/workerRequests"
import { publicApiUserFix } from "../../../utilities/users"
import { db as dbCore } from "@budibase/backend-core"
import { search as stringSearch } from "./utils"
import { UserCtx, User } from "@budibase/types"
import { Next } from "koa"
2023-08-15 15:19:36 +02:00
import { sdk } from "@budibase/pro"
import { isEqual, cloneDeep } from "lodash"
function rolesRemoved(base: User, ctx: UserCtx) {
return (
!isEqual(base.builder, ctx.request.body.builder) ||
!isEqual(base.admin, ctx.request.body.admin) ||
!isEqual(base.roles, ctx.request.body.roles)
)
}
const NO_ROLES_MSG =
"Roles/admin/builder can only be set on business/enterprise licenses - input ignored."
async function createUpdateResponse(ctx: UserCtx, user?: User) {
const base = cloneDeep(ctx.request.body)
ctx = await sdk.publicApi.users.roleCheck(ctx, user)
// check the ctx before any updates to it
const removed = rolesRemoved(base, ctx)
ctx = publicApiUserFix(ctx)
const response = await saveGlobalUser(ctx)
ctx.body = await getUser(ctx, response._id)
if (removed) {
ctx.extra = { message: NO_ROLES_MSG }
}
return ctx
}
function isLoggedInUser(ctx: UserCtx, user: User) {
const loggedInId = ctx.user?._id
2022-12-06 19:23:55 +01:00
const globalUserId = dbCore.getGlobalIDFromUserMetadataID(loggedInId!)
// check both just incase
return globalUserId === user._id || loggedInId === user._id
}
function getUser(ctx: UserCtx, userId?: string) {
2022-02-25 20:00:12 +01:00
if (userId) {
ctx.params = { userId }
2022-02-25 20:00:12 +01:00
} else if (!ctx.params?.userId) {
throw "No user ID provided for getting"
}
return readGlobalUser(ctx)
}
export async function search(ctx: UserCtx, next: Next) {
const { name } = ctx.request.body
const users = await allGlobalUsers(ctx)
ctx.body = stringSearch(users, name, "email")
await next()
2022-02-25 20:00:12 +01:00
}
2022-02-24 16:13:14 +01:00
export async function create(ctx: UserCtx, next: Next) {
await createUpdateResponse(ctx)
await next()
2022-02-25 20:00:12 +01:00
}
2022-02-24 16:13:14 +01:00
export async function read(ctx: UserCtx, next: Next) {
ctx.body = await readGlobalUser(ctx)
await next()
2022-02-25 20:00:12 +01:00
}
2022-02-24 16:13:14 +01:00
export async function update(ctx: UserCtx, next: Next) {
2022-02-25 20:00:12 +01:00
const user = await readGlobalUser(ctx)
ctx.request.body = {
...ctx.request.body,
_rev: user._rev,
}
await createUpdateResponse(ctx, user)
await next()
2022-02-25 20:00:12 +01:00
}
export async function destroy(ctx: UserCtx, next: Next) {
2022-02-25 20:00:12 +01:00
const user = await getUser(ctx)
// disallow deleting yourself
if (isLoggedInUser(ctx, user)) {
ctx.throw(405, "Cannot delete user using its own API key.")
}
2022-02-25 20:00:12 +01:00
await deleteGlobalUser(ctx)
ctx.body = user
await next()
2022-02-25 20:00:12 +01:00
}
2022-02-24 16:13:14 +01:00
export default {
create,
read,
update,
destroy,
search,
}