fix: access to invited workspace (#6360)

* fix: access to invited workspace

* update: idor guards
This commit is contained in:
Ilango
2026-05-19 19:52:50 +05:30
committed by GitHub
parent 9c85c14205
commit b7a2005fd7
@@ -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,
@@ -35,6 +36,7 @@ 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,
@@ -42,28 +44,35 @@ export class WorkspaceUserController {
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)
}