Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getRunningExpressApp } from '../../utils/getRunningExpressApp'
import { WorkspaceUser } from '../database/entities/workspace-user.entity'
import { WorkspaceUserService } from '../services/workspace-user.service'
import {
assertMayReadTargetUser,
assertQueryOrganizationMatchesActiveOrg,
assertWorkspaceIdAccessibleToUser,
getLoggedInUser,
Expand Down Expand Up @@ -35,35 +36,43 @@ export class WorkspaceUserController {

let workspaceUser: any
if (query.workspaceId && query.userId) {
// Caller must have access to the workspace (own, assigned, or org admin within their org).
await assertWorkspaceIdAccessibleToUser(user, query.workspaceId, queryRunner)
workspaceUser = await workspaceUserService.readWorkspaceUserByWorkspaceIdUserId(
query.workspaceId,
query.userId,
queryRunner
)
} else if (query.workspaceId) {
// Caller must have access to the workspace (own, assigned, or org admin within their org).
await assertWorkspaceIdAccessibleToUser(user, query.workspaceId, queryRunner)
workspaceUser = await workspaceUserService.readWorkspaceUserByWorkspaceId(query.workspaceId, queryRunner)
} else if (query.organizationId && query.userId) {
// organizationId must match the caller's active org to prevent cross-org access.
// Caller must be the target user or an org user manager whose target belongs to the same org (IDOR guard).
assertQueryOrganizationMatchesActiveOrg(user, query.organizationId)
if (query.userId !== user.id && !userMayManageOrgUsers(user)) {
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
}
await assertMayReadTargetUser(user, query.userId, queryRunner)
workspaceUser = await workspaceUserService.readWorkspaceUserByOrganizationIdUserId(
query.organizationId,
query.userId,
queryRunner
)
} else if (query.userId) {
if (query.userId !== user.id && !userMayManageOrgUsers(user)) {
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
if (query.userId === user.id) {
// Self-lookup: return memberships across all orgs so the user can switch to an invited org/workspace.
workspaceUser = await workspaceUserService.readWorkspaceUserByUserId(query.userId, queryRunner)
} else {
// Non-self: caller must be an org user manager and the target must belong to the caller's active org (IDOR guard).
// Results are scoped to the caller's active org to prevent cross-org data leakage.
await assertMayReadTargetUser(user, query.userId, queryRunner)
workspaceUser = await workspaceUserService.readWorkspaceUserByOrganizationIdUserId(
user.activeOrganizationId,
query.userId,
queryRunner
)
}
workspaceUser = await workspaceUserService.readWorkspaceUserByOrganizationIdUserId(
user.activeOrganizationId,
query.userId,
queryRunner
)
} else if (query.roleId) {
// Only org user managers may list workspace members by role.
if (!userMayManageOrgUsers(user)) {
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
}
Expand Down
Loading