e703bb7415
* feat(workspaces): drop createdByUserId from the dataschema * feat(workspaces): repositories WIP * merge * protect against removing last admin in workspace * quick impl and stub tests * add tests * services * unit tests for role services * fix(workspaces): maybe tests work like this * fix(workspaces): dry * fix(workspaces): initialize tests better * fix(workspaces): so true * fix(workspaces): right * fix(workspaces): self nit * fix(workspaces): better repository structure * fix(workspaces): repair tests, use `example.org` * fix(workspaces): add tests for new repo functions, repair other tests * fix(workspaces): better distinction between service-level guarantees and repo-level guarantees * fix(workspaces): review comments and stencil tests * fix(workspaces): add tests * fix(workspaces): tests work --------- Co-authored-by: Gergő Jedlicska <gergo@jedlicska.com>
90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
import {
|
|
DeleteWorkspaceRole,
|
|
EmitWorkspaceEvent,
|
|
GetWorkspaceRoleForUser,
|
|
GetWorkspaceRoles,
|
|
UpsertWorkspaceRole
|
|
} from '@/modules/workspaces/domain/operations'
|
|
import { WorkspaceAcl } from '@/modules/workspaces/domain/types'
|
|
import { WorkspaceAdminRequiredError } from '@/modules/workspaces/errors/workspace'
|
|
import { isUserLastWorkspaceAdmin } from '@/modules/workspaces/utils/isUserLastWorkspaceAdmin'
|
|
import { WorkspaceEvents } from '@/modules/workspacesCore/domain/events'
|
|
|
|
type WorkspaceRoleDeleteArgs = {
|
|
userId: string
|
|
workspaceId: string
|
|
}
|
|
|
|
export const deleteWorkspaceRoleFactory =
|
|
({
|
|
getWorkspaceRoles,
|
|
deleteWorkspaceRole,
|
|
emitWorkspaceEvent
|
|
}: {
|
|
getWorkspaceRoles: GetWorkspaceRoles
|
|
deleteWorkspaceRole: DeleteWorkspaceRole
|
|
emitWorkspaceEvent: EmitWorkspaceEvent
|
|
}) =>
|
|
async ({
|
|
userId,
|
|
workspaceId
|
|
}: WorkspaceRoleDeleteArgs): Promise<WorkspaceAcl | null> => {
|
|
const workspaceRoles = await getWorkspaceRoles({ workspaceId })
|
|
|
|
if (isUserLastWorkspaceAdmin(workspaceRoles, userId)) {
|
|
throw new WorkspaceAdminRequiredError()
|
|
}
|
|
|
|
const deletedRole = await deleteWorkspaceRole({ userId, workspaceId })
|
|
|
|
if (!deletedRole) {
|
|
return null
|
|
}
|
|
|
|
emitWorkspaceEvent({ event: WorkspaceEvents.RoleDeleted, payload: deletedRole })
|
|
|
|
return deletedRole
|
|
}
|
|
|
|
type WorkspaceRoleGetArgs = {
|
|
userId: string
|
|
workspaceId: string
|
|
}
|
|
|
|
export const getWorkspaceRoleFactory =
|
|
({ getWorkspaceRoleForUser }: { getWorkspaceRoleForUser: GetWorkspaceRoleForUser }) =>
|
|
async ({
|
|
userId,
|
|
workspaceId
|
|
}: WorkspaceRoleGetArgs): Promise<WorkspaceAcl | null> => {
|
|
return await getWorkspaceRoleForUser({ userId, workspaceId })
|
|
}
|
|
|
|
export const setWorkspaceRoleFactory =
|
|
({
|
|
getWorkspaceRoles,
|
|
upsertWorkspaceRole,
|
|
emitWorkspaceEvent
|
|
}: {
|
|
getWorkspaceRoles: GetWorkspaceRoles
|
|
upsertWorkspaceRole: UpsertWorkspaceRole
|
|
emitWorkspaceEvent: EmitWorkspaceEvent
|
|
}) =>
|
|
async ({ userId, workspaceId, role }: WorkspaceAcl): Promise<void> => {
|
|
const workspaceRoles = await getWorkspaceRoles({ workspaceId })
|
|
|
|
if (
|
|
isUserLastWorkspaceAdmin(workspaceRoles, userId) &&
|
|
role !== 'workspace:admin'
|
|
) {
|
|
throw new WorkspaceAdminRequiredError()
|
|
}
|
|
|
|
await upsertWorkspaceRole({ userId, workspaceId, role })
|
|
|
|
await emitWorkspaceEvent({
|
|
event: WorkspaceEvents.RoleUpdated,
|
|
payload: { userId, workspaceId, role }
|
|
})
|
|
}
|