diff --git a/apps/sim/app/api/audit-logs/export/route.test.ts b/apps/sim/app/api/audit-logs/export/route.test.ts index 7c0667a9de7..83f2da6687d 100644 --- a/apps/sim/app/api/audit-logs/export/route.test.ts +++ b/apps/sim/app/api/audit-logs/export/route.test.ts @@ -22,7 +22,7 @@ vi.mock('@/app/api/v1/audit-logs/auth', () => ({ validateEnterpriseAuditAccess: mockValidateEnterpriseAuditAccess, })) -vi.mock('@/lib/audit-logs/query', () => ({ +vi.mock('@/ee/audit-logs/lib/query', () => ({ buildFilterConditions: mockBuildFilterConditions, buildOrgScopeCondition: mockBuildOrgScopeCondition, getOrgWorkspaceIds: mockGetOrgWorkspaceIds, diff --git a/apps/sim/app/api/audit-logs/export/route.ts b/apps/sim/app/api/audit-logs/export/route.ts index bcf02a37d72..b869cee9a4d 100644 --- a/apps/sim/app/api/audit-logs/export/route.ts +++ b/apps/sim/app/api/audit-logs/export/route.ts @@ -3,17 +3,17 @@ import { getErrorMessage } from '@sim/utils/errors' import { type NextRequest, NextResponse } from 'next/server' import { exportAuditLogsContract } from '@/lib/api/contracts/audit-logs' import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' -import { - buildFilterConditions, - buildOrgScopeCondition, - getOrgWorkspaceIds, - queryAuditLogs, -} from '@/lib/audit-logs/query' import { getSession } from '@/lib/auth' import { formatCsvValue, toCsvRow } from '@/lib/core/utils/csv' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { validateEnterpriseAuditAccess } from '@/app/api/v1/audit-logs/auth' import { formatAuditLogEntry } from '@/app/api/v1/audit-logs/format' +import { + buildFilterConditions, + buildOrgScopeCondition, + getOrgWorkspaceIds, + queryAuditLogs, +} from '@/ee/audit-logs/lib/query' const logger = createLogger('AuditLogsExportAPI') diff --git a/apps/sim/app/api/audit-logs/route.test.ts b/apps/sim/app/api/audit-logs/route.test.ts index 2d8c4af1aa1..bebc2f2de89 100644 --- a/apps/sim/app/api/audit-logs/route.test.ts +++ b/apps/sim/app/api/audit-logs/route.test.ts @@ -11,7 +11,7 @@ const mocks = vi.hoisted(() => ({ vi.mock('@/lib/auth', () => ({ getSession: mocks.getSession })) -vi.mock('@/lib/audit-logs/application/list-audit-logs', () => ({ +vi.mock('@/ee/audit-logs/lib/application/list-audit-logs', () => ({ listAuditLogs: { operation: { id: 'audit_logs.list' }, execute: mocks.execute }, })) diff --git a/apps/sim/app/api/audit-logs/route.ts b/apps/sim/app/api/audit-logs/route.ts index f63e99575c2..2fe5cb0bdc5 100644 --- a/apps/sim/app/api/audit-logs/route.ts +++ b/apps/sim/app/api/audit-logs/route.ts @@ -5,9 +5,9 @@ import { internalRateLimits, internalSessionAuth, } from '@/lib/api/server/routes' -import { listAuditLogs } from '@/lib/audit-logs/application/list-audit-logs' -import { auditLogOperations } from '@/lib/audit-logs/application/operations' import { formatAuditLogEntry } from '@/app/api/v1/audit-logs/format' +import { listAuditLogs } from '@/ee/audit-logs/lib/application/list-audit-logs' +import { auditLogOperations } from '@/ee/audit-logs/lib/application/operations' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/auth/oauth/connections/route.test.ts b/apps/sim/app/api/auth/oauth/connections/route.test.ts index 282cd6b7d46..bc1b0ee7402 100644 --- a/apps/sim/app/api/auth/oauth/connections/route.test.ts +++ b/apps/sim/app/api/auth/oauth/connections/route.test.ts @@ -28,7 +28,7 @@ vi.mock('@sim/db', () => ({ eq: mockEq, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('jose', () => ({ decodeJwt: mockDecodeJwt, diff --git a/apps/sim/app/api/auth/oauth/credentials/route.test.ts b/apps/sim/app/api/auth/oauth/credentials/route.test.ts index 94f2cf1a7ab..605c355a47d 100644 --- a/apps/sim/app/api/auth/oauth/credentials/route.test.ts +++ b/apps/sim/app/api/auth/oauth/credentials/route.test.ts @@ -36,10 +36,10 @@ vi.mock('@/lib/workflows/utils', () => workflowsUtilsMock) vi.mock('@/lib/workspaces/permissions/utils', () => permissionsMock) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET } from '@/app/api/auth/oauth/credentials/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' describe('OAuth Credentials API Route', () => { function createMockRequestWithQuery(method = 'GET', queryParams = ''): NextRequest { diff --git a/apps/sim/app/api/auth/oauth/credentials/route.ts b/apps/sim/app/api/auth/oauth/credentials/route.ts index 0625008f233..5e5a4b7de16 100644 --- a/apps/sim/app/api/auth/oauth/credentials/route.ts +++ b/apps/sim/app/api/auth/oauth/credentials/route.ts @@ -16,11 +16,11 @@ import { getServiceAccountProviderForProviderId, providerIdsForService, } from '@/lib/oauth/utils' +import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' import { capabilityRefusal, isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' -import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' +} from '@/ee/access-control/lib/capability-assertions' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/chat/manage/[id]/route.test.ts b/apps/sim/app/api/chat/manage/[id]/route.test.ts index 361bea5f55a..d4b42fdb2cc 100644 --- a/apps/sim/app/api/chat/manage/[id]/route.test.ts +++ b/apps/sim/app/api/chat/manage/[id]/route.test.ts @@ -21,7 +21,7 @@ import { } from '@sim/testing' import { NextRequest } from 'next/server' import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' -import { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' +import { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' const mocks = vi.hoisted(() => ({ resolvePermission: vi.fn(), diff --git a/apps/sim/app/api/chat/route.test.ts b/apps/sim/app/api/chat/route.test.ts index c7670c123a4..8034fe71336 100644 --- a/apps/sim/app/api/chat/route.test.ts +++ b/apps/sim/app/api/chat/route.test.ts @@ -18,7 +18,7 @@ import { } from '@sim/testing' import { NextRequest } from 'next/server' import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest' -import { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' +import { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' const mocks = vi.hoisted(() => ({ resolvePermission: vi.fn(), diff --git a/apps/sim/app/api/cli/auth/approve/route.test.ts b/apps/sim/app/api/cli/auth/approve/route.test.ts index 2c74b36d44d..927b2560f40 100644 --- a/apps/sim/app/api/cli/auth/approve/route.test.ts +++ b/apps/sim/app/api/cli/auth/approve/route.test.ts @@ -25,7 +25,7 @@ const { mockGetUserOrganization: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, getUserPermissionConfigForOrganization: mockGetOrgPermissionConfig, resolveVerifiedUserAccessControlContext: mockResolveVerifiedContext, diff --git a/apps/sim/app/api/cli/auth/approve/route.ts b/apps/sim/app/api/cli/auth/approve/route.ts index fa463ab9238..62f9d2fd9f5 100644 --- a/apps/sim/app/api/cli/auth/approve/route.ts +++ b/apps/sim/app/api/cli/auth/approve/route.ts @@ -6,9 +6,9 @@ import { getSession } from '@/lib/auth' import { createApproval } from '@/lib/cli-auth/approval-store' import { enforceUserRateLimit } from '@/lib/core/rate-limiter' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { capabilityRefusal } from '@/lib/permission-groups/capability-assertions' -import { isCapabilityWithheldForUser } from '@/lib/permission-groups/user-scope.server' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' +import { capabilityRefusal } from '@/ee/access-control/lib/capability-assertions' +import { isCapabilityWithheldForUser } from '@/ee/access-control/lib/user-scope.server' const logger = createLogger('CliAuthApproveAPI') diff --git a/apps/sim/app/api/copilot/tool-permission/route.test.ts b/apps/sim/app/api/copilot/tool-permission/route.test.ts index b533477f309..5462e96dd6e 100644 --- a/apps/sim/app/api/copilot/tool-permission/route.test.ts +++ b/apps/sim/app/api/copilot/tool-permission/route.test.ts @@ -51,7 +51,7 @@ vi.mock('@/lib/core/config/env-flags', () => ({ isCopilotToolPermissionsEnabled: true, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig, })) diff --git a/apps/sim/app/api/copilot/tool-permission/route.ts b/apps/sim/app/api/copilot/tool-permission/route.ts index 8c18edef37c..04741eb8a93 100644 --- a/apps/sim/app/api/copilot/tool-permission/route.ts +++ b/apps/sim/app/api/copilot/tool-permission/route.ts @@ -29,7 +29,7 @@ import { import { withIncomingGoSpan } from '@/lib/copilot/request/otel' import { isCopilotToolPermissionsEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('CopilotToolPermissionAPI') diff --git a/apps/sim/app/api/cron/run-data-drains/route.ts b/apps/sim/app/api/cron/run-data-drains/route.ts index 61416bb8f6d..bdc64fa822b 100644 --- a/apps/sim/app/api/cron/run-data-drains/route.ts +++ b/apps/sim/app/api/cron/run-data-drains/route.ts @@ -4,7 +4,7 @@ import { type NextRequest, NextResponse } from 'next/server' import { verifyCronAuth } from '@/lib/auth/internal' import { isBillingEnabled, isDataDrainsEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { dispatchDueDrains } from '@/lib/data-drains/dispatcher' +import { dispatchDueDrains } from '@/ee/data-drains/lib/dispatcher' const logger = createLogger('CronRunDataDrains') diff --git a/apps/sim/app/api/custom-blocks/[id]/authorize-manage.ts b/apps/sim/app/api/custom-blocks/[id]/authorize-manage.ts index a94c17975b4..42b9282c744 100644 --- a/apps/sim/app/api/custom-blocks/[id]/authorize-manage.ts +++ b/apps/sim/app/api/custom-blocks/[id]/authorize-manage.ts @@ -1,9 +1,9 @@ import { NextResponse } from 'next/server' +import { hasWorkspaceAdminAccess } from '@/lib/workspaces/permissions/utils' import { getCustomBlockManageContext, isCustomBlocksDeploymentEnabled, -} from '@/lib/workflows/custom-blocks/operations' -import { hasWorkspaceAdminAccess } from '@/lib/workspaces/permissions/utils' +} from '@/ee/custom-blocks/lib/operations' export type ManageContext = NonNullable>> diff --git a/apps/sim/app/api/custom-blocks/[id]/route.ts b/apps/sim/app/api/custom-blocks/[id]/route.ts index a344424f2ed..65d9f6f7862 100644 --- a/apps/sim/app/api/custom-blocks/[id]/route.ts +++ b/apps/sim/app/api/custom-blocks/[id]/route.ts @@ -10,13 +10,13 @@ import { import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { authorizeManage } from '@/app/api/custom-blocks/[id]/authorize-manage' import { CustomBlockValidationError, deleteCustomBlock, getCustomBlockUsageCounts, updateCustomBlock, -} from '@/lib/workflows/custom-blocks/operations' -import { authorizeManage } from '@/app/api/custom-blocks/[id]/authorize-manage' +} from '@/ee/custom-blocks/lib/operations' const logger = createLogger('CustomBlockAPI') diff --git a/apps/sim/app/api/custom-blocks/[id]/usages/route.test.ts b/apps/sim/app/api/custom-blocks/[id]/usages/route.test.ts index dadf29fdf6a..9c0730941a9 100644 --- a/apps/sim/app/api/custom-blocks/[id]/usages/route.test.ts +++ b/apps/sim/app/api/custom-blocks/[id]/usages/route.test.ts @@ -17,7 +17,7 @@ vi.mock('@/lib/workspaces/permissions/utils', () => ({ hasWorkspaceAdminAccess: mockHasWorkspaceAdminAccess, })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => mockOperations) +vi.mock('@/ee/custom-blocks/lib/operations', () => mockOperations) import { GET } from '@/app/api/custom-blocks/[id]/usages/route' diff --git a/apps/sim/app/api/custom-blocks/[id]/usages/route.ts b/apps/sim/app/api/custom-blocks/[id]/usages/route.ts index eee59b2c20a..3587e7df223 100644 --- a/apps/sim/app/api/custom-blocks/[id]/usages/route.ts +++ b/apps/sim/app/api/custom-blocks/[id]/usages/route.ts @@ -4,8 +4,8 @@ import { getCustomBlockUsageCountsContract } from '@/lib/api/contracts/custom-bl import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { getCustomBlockUsageCounts } from '@/lib/workflows/custom-blocks/operations' import { authorizeManage } from '@/app/api/custom-blocks/[id]/authorize-manage' +import { getCustomBlockUsageCounts } from '@/ee/custom-blocks/lib/operations' type RouteContext = { params: Promise<{ id: string }> } diff --git a/apps/sim/app/api/custom-blocks/route.ts b/apps/sim/app/api/custom-blocks/route.ts index 6bb65be93d4..202b604b2a0 100644 --- a/apps/sim/app/api/custom-blocks/route.ts +++ b/apps/sim/app/api/custom-blocks/route.ts @@ -10,14 +10,14 @@ import { import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' import { CustomBlockValidationError, type CustomBlockWithInputs, isCustomBlocksEligibleForOrganization, listCustomBlocksWithInputs, publishCustomBlock, -} from '@/lib/workflows/custom-blocks/operations' -import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' +} from '@/ee/custom-blocks/lib/operations' const logger = createLogger('CustomBlocksAPI') diff --git a/apps/sim/app/api/invitations/[id]/resend/route.ts b/apps/sim/app/api/invitations/[id]/resend/route.ts index 2d8bb7f511b..c3d89890da8 100644 --- a/apps/sim/app/api/invitations/[id]/resend/route.ts +++ b/apps/sim/app/api/invitations/[id]/resend/route.ts @@ -18,9 +18,9 @@ import { prepareInvitationResend, sendInvitationEmail, } from '@/lib/invitations/send' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { getWorkspaceWithOwner, hasWorkspaceAdminAccess } from '@/lib/workspaces/permissions/utils' import { getWorkspaceInvitePolicy } from '@/lib/workspaces/policy' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' import { InvitationsNotAllowedError, validateInvitationsAllowed, diff --git a/apps/sim/app/api/logs/export/route.test.ts b/apps/sim/app/api/logs/export/route.test.ts index 0955840a5c3..12d55ec3525 100644 --- a/apps/sim/app/api/logs/export/route.test.ts +++ b/apps/sim/app/api/logs/export/route.test.ts @@ -25,7 +25,7 @@ const { mockGetUserPermissionConfig: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, })) @@ -46,8 +46,8 @@ vi.mock('@/lib/core/utils/concurrency', () => ({ mapWithConcurrency: mockMapWithConcurrency, })) -import { capabilityRefusal } from '@/lib/permission-groups/capabilities' import { GET } from '@/app/api/logs/export/route' +import { capabilityRefusal } from '@/ee/access-control/lib/capabilities' const mockGetSession = authMockFns.mockGetSession const STARTED_AT = new Date('2026-08-23T12:00:00.000Z') diff --git a/apps/sim/app/api/logs/export/route.ts b/apps/sim/app/api/logs/export/route.ts index f79149e437b..11ecdaa2db6 100644 --- a/apps/sim/app/api/logs/export/route.ts +++ b/apps/sim/app/api/logs/export/route.ts @@ -13,12 +13,12 @@ import { withheldSpendData } from '@/lib/logs/fetch-log-detail' import { buildFilterConditions, LogFilterParamsSchema } from '@/lib/logs/filters' import { expandFolderIdsWithDescendants } from '@/lib/logs/folder-expansion' import { logQuerySelectsCost } from '@/lib/logs/log-projection' +import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' import { capabilityDeniedBy, capabilityRefusal, -} from '@/lib/permission-groups/capability-assertions' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' +} from '@/ee/access-control/lib/capability-assertions' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' const logger = createLogger('LogsExportAPI') const LOG_EXPORT_PAGE_SIZE = 100 diff --git a/apps/sim/app/api/logs/stats/route.test.ts b/apps/sim/app/api/logs/stats/route.test.ts index 669cb2af758..732987266c0 100644 --- a/apps/sim/app/api/logs/stats/route.test.ts +++ b/apps/sim/app/api/logs/stats/route.test.ts @@ -29,10 +29,10 @@ vi.mock('@/lib/logs/stats-queries', () => ({ readLogStatsSegments: mocks.readLogStatsSegments, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) -import { capabilityRefusal } from '@/lib/permission-groups/capabilities' import { GET } from '@/app/api/logs/stats/route' +import { capabilityRefusal } from '@/ee/access-control/lib/capabilities' const resolveGroupConfigMock = permissionGroupScopeMockFns.mockResolvePermissionGroupConfig diff --git a/apps/sim/app/api/logs/stats/route.ts b/apps/sim/app/api/logs/stats/route.ts index a5689d63028..b23f3b12104 100644 --- a/apps/sim/app/api/logs/stats/route.ts +++ b/apps/sim/app/api/logs/stats/route.ts @@ -12,9 +12,9 @@ import { expandFolderIdsWithDescendants } from '@/lib/logs/folder-expansion' import { logQuerySelectsCost } from '@/lib/logs/log-projection' import { buildDashboardStats, resolveLogStatsWindow } from '@/lib/logs/stats' import { readLogStatsBounds, readLogStatsSegments } from '@/lib/logs/stats-queries' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('LogsStatsAPI') diff --git a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/route.ts b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/route.ts index b0b291b0807..d36f0804cd7 100644 --- a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/route.ts +++ b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/route.ts @@ -12,10 +12,10 @@ import { } from '@/lib/api/contracts/data-drains' import { parseRequest, validationErrorResponse } from '@/lib/api/server' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { authorizeDrainAccess, loadDrain } from '@/lib/data-drains/access' -import { getDestination } from '@/lib/data-drains/destinations/registry' -import { encryptCredentials } from '@/lib/data-drains/encryption' -import { serializeDrain } from '@/lib/data-drains/serializers' +import { authorizeDrainAccess, loadDrain } from '@/ee/data-drains/lib/access' +import { getDestination } from '@/ee/data-drains/lib/destinations/registry' +import { encryptCredentials } from '@/ee/data-drains/lib/encryption' +import { serializeDrain } from '@/ee/data-drains/lib/serializers' const logger = createLogger('DataDrainAPI') diff --git a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/run/route.ts b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/run/route.ts index 433f381143d..c93d47f1e91 100644 --- a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/run/route.ts +++ b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/run/route.ts @@ -8,7 +8,7 @@ import { runDataDrainContract } from '@/lib/api/contracts/data-drains' import { parseRequest } from '@/lib/api/server' import { getJobQueue } from '@/lib/core/async-jobs' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { authorizeDrainAccess, loadDrain } from '@/lib/data-drains/access' +import { authorizeDrainAccess, loadDrain } from '@/ee/data-drains/lib/access' const logger = createLogger('DataDrainRunAPI') diff --git a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/runs/route.ts b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/runs/route.ts index cd7ef667ab5..60f83f9fafc 100644 --- a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/runs/route.ts +++ b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/runs/route.ts @@ -5,8 +5,8 @@ import { type NextRequest, NextResponse } from 'next/server' import { listDataDrainRunsContract } from '@/lib/api/contracts/data-drains' import { parseRequest } from '@/lib/api/server' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { authorizeDrainAccess, loadDrain } from '@/lib/data-drains/access' -import { serializeDrainRun } from '@/lib/data-drains/serializers' +import { authorizeDrainAccess, loadDrain } from '@/ee/data-drains/lib/access' +import { serializeDrainRun } from '@/ee/data-drains/lib/serializers' const DEFAULT_LIMIT = 25 diff --git a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/test/route.ts b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/test/route.ts index 5550ff9eb4c..e3fc7468ead 100644 --- a/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/test/route.ts +++ b/apps/sim/app/api/organizations/[id]/data-drains/[drainId]/test/route.ts @@ -5,9 +5,9 @@ import { type NextRequest, NextResponse } from 'next/server' import { testDataDrainContract } from '@/lib/api/contracts/data-drains' import { parseRequest } from '@/lib/api/server' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { authorizeDrainAccess, loadDrain } from '@/lib/data-drains/access' -import { getDestination } from '@/lib/data-drains/destinations/registry' -import { decryptCredentials } from '@/lib/data-drains/encryption' +import { authorizeDrainAccess, loadDrain } from '@/ee/data-drains/lib/access' +import { getDestination } from '@/ee/data-drains/lib/destinations/registry' +import { decryptCredentials } from '@/ee/data-drains/lib/encryption' const logger = createLogger('DataDrainTestAPI') diff --git a/apps/sim/app/api/organizations/[id]/data-drains/route.ts b/apps/sim/app/api/organizations/[id]/data-drains/route.ts index d78655ae28b..ff8fd683c63 100644 --- a/apps/sim/app/api/organizations/[id]/data-drains/route.ts +++ b/apps/sim/app/api/organizations/[id]/data-drains/route.ts @@ -9,10 +9,10 @@ import { type NextRequest, NextResponse } from 'next/server' import { createDataDrainContract, listDataDrainsContract } from '@/lib/api/contracts/data-drains' import { parseRequest, validationErrorResponse } from '@/lib/api/server' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { authorizeDrainAccess } from '@/lib/data-drains/access' -import { getDestination } from '@/lib/data-drains/destinations/registry' -import { encryptCredentials } from '@/lib/data-drains/encryption' -import { serializeDrain } from '@/lib/data-drains/serializers' +import { authorizeDrainAccess } from '@/ee/data-drains/lib/access' +import { getDestination } from '@/ee/data-drains/lib/destinations/registry' +import { encryptCredentials } from '@/ee/data-drains/lib/encryption' +import { serializeDrain } from '@/ee/data-drains/lib/serializers' const logger = createLogger('DataDrainsAPI') diff --git a/apps/sim/app/api/organizations/[id]/data-retention/route.ts b/apps/sim/app/api/organizations/[id]/data-retention/route.ts index cb70d83805d..8f41170beb5 100644 --- a/apps/sim/app/api/organizations/[id]/data-retention/route.ts +++ b/apps/sim/app/api/organizations/[id]/data-retention/route.ts @@ -13,10 +13,10 @@ import { parseRequest, validationErrorResponse } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { CLEANUP_CONFIG } from '@/lib/billing/cleanup-dispatcher' import { isOrganizationOnEnterprisePlan } from '@/lib/billing/core/subscription' -import { getForeignWorkspaceTargetsReason } from '@/lib/billing/retention' import { isBillingEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { coercePiiLanguage } from '@/lib/guardrails/pii-entities' +import { getForeignWorkspaceTargetsReason } from '@/ee/data-retention/lib/retention' const logger = createLogger('DataRetentionAPI') diff --git a/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.test.ts b/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.test.ts index 4a7b76741d2..f80dd8315fa 100644 --- a/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.test.ts +++ b/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.test.ts @@ -36,7 +36,7 @@ vi.mock('@sim/audit', () => ({ AuditResourceType: { ORGANIZATION: 'organization' }, })) -vi.mock('@/lib/auth/sso/domain-verification', () => ({ +vi.mock('@/ee/sso/lib/domain-verification', () => ({ checkDomainTxtRecord: mockCheckDomainTxtRecord, toDomainResponse: (row: { id: string; status: string }) => ({ id: row.id, status: row.status }), })) diff --git a/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.ts b/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.ts index f48cd7c8510..1157bfb6035 100644 --- a/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.ts +++ b/apps/sim/app/api/organizations/[id]/domains/[domainId]/verify/route.ts @@ -9,10 +9,10 @@ import { type NextRequest, NextResponse } from 'next/server' import { verifyOrganizationDomainContract } from '@/lib/api/contracts/organization' import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' -import { checkDomainTxtRecord, toDomainResponse } from '@/lib/auth/sso/domain-verification' import { isOrganizationOnEnterprisePlan } from '@/lib/billing/core/subscription' import { isBillingEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { checkDomainTxtRecord, toDomainResponse } from '@/ee/sso/lib/domain-verification' const logger = createLogger('OrgDomainVerifyAPI') diff --git a/apps/sim/app/api/organizations/[id]/domains/route.ts b/apps/sim/app/api/organizations/[id]/domains/route.ts index 88ae74b8389..0e5943adf09 100644 --- a/apps/sim/app/api/organizations/[id]/domains/route.ts +++ b/apps/sim/app/api/organizations/[id]/domains/route.ts @@ -14,10 +14,10 @@ import { } from '@/lib/api/contracts/organization' import { parseRequest, validationErrorResponse } from '@/lib/api/server' import { getSession } from '@/lib/auth' -import { generateVerificationToken, toDomainResponse } from '@/lib/auth/sso/domain-verification' import { isOrganizationOnEnterprisePlan } from '@/lib/billing/core/subscription' import { isBillingEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { generateVerificationToken, toDomainResponse } from '@/ee/sso/lib/domain-verification' const logger = createLogger('OrgDomainsAPI') diff --git a/apps/sim/app/api/organizations/[id]/members/route.test.ts b/apps/sim/app/api/organizations/[id]/members/route.test.ts index 5eab80f930b..396568e3124 100644 --- a/apps/sim/app/api/organizations/[id]/members/route.test.ts +++ b/apps/sim/app/api/organizations/[id]/members/route.test.ts @@ -27,7 +27,7 @@ vi.mock('@sim/platform-authz/workspace', () => ({ isOrgAdminRole: (role: string | null | undefined) => role === 'owner' || role === 'admin', })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, getUserPermissionConfigForOrganization: mockGetOrgPermissionConfig, resolveVerifiedUserAccessControlContext: mockResolveVerifiedContext, @@ -37,8 +37,8 @@ vi.mock('@/lib/billing/core/organization', () => ({ getOrganizationMemberUsageSnapshot: mockGetUsageSnapshot, })) -import { capabilityRefusal } from '@/lib/permission-groups/capability-assertions' import { GET } from '@/app/api/organizations/[id]/members/route' +import { capabilityRefusal } from '@/ee/access-control/lib/capability-assertions' const mockGetSession = authMockFns.mockGetSession diff --git a/apps/sim/app/api/organizations/[id]/members/route.ts b/apps/sim/app/api/organizations/[id]/members/route.ts index 858c33f74ae..de153a75a01 100644 --- a/apps/sim/app/api/organizations/[id]/members/route.ts +++ b/apps/sim/app/api/organizations/[id]/members/route.ts @@ -15,7 +15,7 @@ import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { capabilityRefusal, isOrganizationCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('OrganizationMembersAPI') diff --git a/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/bulk/route.ts b/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/bulk/route.ts index 7cec2121fb2..2900c1e3d72 100644 --- a/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/bulk/route.ts +++ b/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/bulk/route.ts @@ -10,8 +10,6 @@ import { bulkAddPermissionGroupMembersContract } from '@/lib/api/contracts/permi import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { PERMISSION_GROUP_MEMBER_CONSTRAINTS } from '@/lib/permission-groups/constraints' -import { acquirePermissionGroupOrgLock } from '@/lib/permission-groups/locks' import { authorizeOrgAccessControl, findScopeConflicts, @@ -20,6 +18,8 @@ import { loadGroupInOrganization, type ScopeConflict, } from '@/app/api/organizations/[id]/permission-groups/utils' +import { PERMISSION_GROUP_MEMBER_CONSTRAINTS } from '@/ee/access-control/lib/constraints' +import { acquirePermissionGroupOrgLock } from '@/ee/access-control/lib/locks' const logger = createLogger('OrganizationPermissionGroupBulkMembers') diff --git a/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/route.ts b/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/route.ts index 27a95cf0c7f..759de5b2ad1 100644 --- a/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/route.ts +++ b/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/members/route.ts @@ -10,8 +10,6 @@ import { addPermissionGroupMemberContract } from '@/lib/api/contracts/permission import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { PERMISSION_GROUP_MEMBER_CONSTRAINTS } from '@/lib/permission-groups/constraints' -import { acquirePermissionGroupOrgLock } from '@/lib/permission-groups/locks' import { isOrganizationMember } from '@/lib/workspaces/permissions/utils' import { type AllMembersConflict, @@ -24,6 +22,8 @@ import { loadGroupInOrganization, type ScopeConflict, } from '@/app/api/organizations/[id]/permission-groups/utils' +import { PERMISSION_GROUP_MEMBER_CONSTRAINTS } from '@/ee/access-control/lib/constraints' +import { acquirePermissionGroupOrgLock } from '@/ee/access-control/lib/locks' const logger = createLogger('OrganizationPermissionGroupMembers') diff --git a/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/route.ts b/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/route.ts index fcf5b0ee280..76332320956 100644 --- a/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/route.ts +++ b/apps/sim/app/api/organizations/[id]/permission-groups/[groupId]/route.ts @@ -10,12 +10,6 @@ import { updatePermissionGroupContract } from '@/lib/api/contracts/permission-gr import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { PERMISSION_GROUP_CONSTRAINTS } from '@/lib/permission-groups/constraints' -import { - type PermissionGroupConfig, - parsePermissionGroupConfig, -} from '@/lib/permission-groups/fields' -import { acquirePermissionGroupOrgLock } from '@/lib/permission-groups/locks' import { type AllMembersConflict, authorizeOrgAccessControl, @@ -28,6 +22,12 @@ import { loadGroupInOrganization, type ScopeConflict, } from '@/app/api/organizations/[id]/permission-groups/utils' +import { PERMISSION_GROUP_CONSTRAINTS } from '@/ee/access-control/lib/constraints' +import { + type PermissionGroupConfig, + parsePermissionGroupConfig, +} from '@/ee/access-control/lib/fields' +import { acquirePermissionGroupOrgLock } from '@/ee/access-control/lib/locks' const logger = createLogger('OrganizationPermissionGroup') diff --git a/apps/sim/app/api/organizations/[id]/permission-groups/route.ts b/apps/sim/app/api/organizations/[id]/permission-groups/route.ts index dd8e9400fe3..b609b60c042 100644 --- a/apps/sim/app/api/organizations/[id]/permission-groups/route.ts +++ b/apps/sim/app/api/organizations/[id]/permission-groups/route.ts @@ -15,13 +15,6 @@ import { createPermissionGroupContract } from '@/lib/api/contracts/permission-gr import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { PERMISSION_GROUP_CONSTRAINTS } from '@/lib/permission-groups/constraints' -import { - DEFAULT_PERMISSION_GROUP_CONFIG, - type PermissionGroupConfig, - parsePermissionGroupConfig, -} from '@/lib/permission-groups/fields' -import { acquirePermissionGroupOrgLock } from '@/lib/permission-groups/locks' import { type AllMembersConflict, authorizeOrgAccessControl, @@ -30,6 +23,13 @@ import { formatAllMembersConflictError, getWorkspacesForGroups, } from '@/app/api/organizations/[id]/permission-groups/utils' +import { PERMISSION_GROUP_CONSTRAINTS } from '@/ee/access-control/lib/constraints' +import { + DEFAULT_PERMISSION_GROUP_CONFIG, + type PermissionGroupConfig, + parsePermissionGroupConfig, +} from '@/ee/access-control/lib/fields' +import { acquirePermissionGroupOrgLock } from '@/ee/access-control/lib/locks' const logger = createLogger('OrganizationPermissionGroups') diff --git a/apps/sim/app/api/organizations/[id]/roster/route.test.ts b/apps/sim/app/api/organizations/[id]/roster/route.test.ts index 45b2ad9437a..5c5e1bcde62 100644 --- a/apps/sim/app/api/organizations/[id]/roster/route.test.ts +++ b/apps/sim/app/api/organizations/[id]/roster/route.test.ts @@ -29,7 +29,7 @@ const { mockResolveVerifiedContext: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, getUserPermissionConfigForOrganization: mockGetOrgPermissionConfig, resolveVerifiedUserAccessControlContext: mockResolveVerifiedContext, @@ -43,8 +43,8 @@ vi.mock('@/lib/invitations/core', () => ({ expireStalePendingInvitationsForOrganization: mockExpireStaleInvitations, })) -import { capabilityRefusal } from '@/lib/permission-groups/capability-assertions' import { GET } from '@/app/api/organizations/[id]/roster/route' +import { capabilityRefusal } from '@/ee/access-control/lib/capability-assertions' const mockGetSession = authMockFns.mockGetSession diff --git a/apps/sim/app/api/organizations/[id]/roster/route.ts b/apps/sim/app/api/organizations/[id]/roster/route.ts index a7d7bba1868..5bb0674d0c1 100644 --- a/apps/sim/app/api/organizations/[id]/roster/route.ts +++ b/apps/sim/app/api/organizations/[id]/roster/route.ts @@ -24,7 +24,7 @@ import { expireStalePendingInvitationsForOrganization } from '@/lib/invitations/ import { capabilityRefusal, isOrganizationCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('OrganizationRosterAPI') diff --git a/apps/sim/app/api/organizations/[id]/session-policy/route.test.ts b/apps/sim/app/api/organizations/[id]/session-policy/route.test.ts index 65183a0e83d..364b1090626 100644 --- a/apps/sim/app/api/organizations/[id]/session-policy/route.test.ts +++ b/apps/sim/app/api/organizations/[id]/session-policy/route.test.ts @@ -19,7 +19,7 @@ const { mockIsEnterprise, mockEagerClamp, mockRecordAudit } = vi.hoisted(() => ( mockRecordAudit: vi.fn(), })) -vi.mock('@/lib/auth/session-policy', () => ({ +vi.mock('@/ee/session-policy/lib/session-policy', () => ({ eagerClampOrgSessions: mockEagerClamp, invalidateSessionPolicyCache: vi.fn(), })) diff --git a/apps/sim/app/api/organizations/[id]/session-policy/route.ts b/apps/sim/app/api/organizations/[id]/session-policy/route.ts index fca76741506..dcf4b1d6c74 100644 --- a/apps/sim/app/api/organizations/[id]/session-policy/route.ts +++ b/apps/sim/app/api/organizations/[id]/session-policy/route.ts @@ -10,10 +10,13 @@ import { updateOrganizationSessionPolicyContract } from '@/lib/api/contracts/org import { parseRequest, validationErrorResponse } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { invalidateSecurityPolicyVersionCache } from '@/lib/auth/security-policy' -import { eagerClampOrgSessions, invalidateSessionPolicyCache } from '@/lib/auth/session-policy' import { isOrganizationFeatureEntitled } from '@/lib/billing/core/subscription' import { isBillingEnabled, isSessionPoliciesEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { + eagerClampOrgSessions, + invalidateSessionPolicyCache, +} from '@/ee/session-policy/lib/session-policy' const logger = createLogger('SessionPolicyAPI') diff --git a/apps/sim/app/api/organizations/[id]/usage/breakdown/route.ts b/apps/sim/app/api/organizations/[id]/usage/breakdown/route.ts index 7af435c43da..cfd5d2cf74e 100644 --- a/apps/sim/app/api/organizations/[id]/usage/breakdown/route.ts +++ b/apps/sim/app/api/organizations/[id]/usage/breakdown/route.ts @@ -4,9 +4,9 @@ import { internalRateLimits, internalSessionAuth, } from '@/lib/api/server/routes' -import { getOrganizationUsageBreakdown } from '@/lib/billing/application/organization-usage/get-organization-usage-breakdown' -import { organizationUsageOperations } from '@/lib/billing/application/organization-usage/operations' import { organizationUsageErrorPolicy } from '@/app/api/organizations/[id]/usage/error-policy' +import { getOrganizationUsageBreakdown } from '@/ee/organization-usage/lib/get-organization-usage-breakdown' +import { organizationUsageOperations } from '@/ee/organization-usage/lib/operations' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/organizations/[id]/usage/events/route.ts b/apps/sim/app/api/organizations/[id]/usage/events/route.ts index 59d5c28de45..d8521af86d8 100644 --- a/apps/sim/app/api/organizations/[id]/usage/events/route.ts +++ b/apps/sim/app/api/organizations/[id]/usage/events/route.ts @@ -4,9 +4,9 @@ import { internalRateLimits, internalSessionAuth, } from '@/lib/api/server/routes' -import { listOrganizationUsageEvents } from '@/lib/billing/application/organization-usage/list-organization-usage-events' -import { organizationUsageOperations } from '@/lib/billing/application/organization-usage/operations' import { organizationUsageErrorPolicy } from '@/app/api/organizations/[id]/usage/error-policy' +import { listOrganizationUsageEvents } from '@/ee/organization-usage/lib/list-organization-usage-events' +import { organizationUsageOperations } from '@/ee/organization-usage/lib/operations' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/organizations/[id]/usage/export/route.ts b/apps/sim/app/api/organizations/[id]/usage/export/route.ts index c4b77332e17..300277cbc0a 100644 --- a/apps/sim/app/api/organizations/[id]/usage/export/route.ts +++ b/apps/sim/app/api/organizations/[id]/usage/export/route.ts @@ -4,10 +4,6 @@ import { type NextRequest, NextResponse } from 'next/server' import { exportOrganizationUsageContract } from '@/lib/api/contracts/organization-usage' import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' -import { - exportOrganizationUsageEvents, - type OrganizationUsageExportRow, -} from '@/lib/billing/application/organization-usage/export-organization-usage-events' import { UsageWindowRangeInvertedError, UsageWindowRangeTooLargeError, @@ -15,6 +11,10 @@ import { import { ForbiddenOperationError } from '@/lib/core/application' import { formatCsvValue, toCsvRow } from '@/lib/core/utils/csv' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { + exportOrganizationUsageEvents, + type OrganizationUsageExportRow, +} from '@/ee/organization-usage/lib/export-organization-usage-events' const logger = createLogger('OrganizationUsageExportAPI') diff --git a/apps/sim/app/api/organizations/[id]/usage/summary/route.ts b/apps/sim/app/api/organizations/[id]/usage/summary/route.ts index 4d1111e1962..4b7b622d8d8 100644 --- a/apps/sim/app/api/organizations/[id]/usage/summary/route.ts +++ b/apps/sim/app/api/organizations/[id]/usage/summary/route.ts @@ -4,9 +4,9 @@ import { internalRateLimits, internalSessionAuth, } from '@/lib/api/server/routes' -import { getOrganizationUsageSummary } from '@/lib/billing/application/organization-usage/get-organization-usage-summary' -import { organizationUsageOperations } from '@/lib/billing/application/organization-usage/operations' import { organizationUsageErrorPolicy } from '@/app/api/organizations/[id]/usage/error-policy' +import { getOrganizationUsageSummary } from '@/ee/organization-usage/lib/get-organization-usage-summary' +import { organizationUsageOperations } from '@/ee/organization-usage/lib/operations' export const dynamic = 'force-dynamic' diff --git a/apps/sim/app/api/table/[tableId]/export/route.test.ts b/apps/sim/app/api/table/[tableId]/export/route.test.ts index 90d039f8715..fe5bcc9ff27 100644 --- a/apps/sim/app/api/table/[tableId]/export/route.test.ts +++ b/apps/sim/app/api/table/[tableId]/export/route.test.ts @@ -11,7 +11,7 @@ const { mockCheckAccess, mockQueryRows, mockGetUserPermissionConfig } = vi.hoist mockGetUserPermissionConfig: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, })) @@ -28,8 +28,8 @@ vi.mock('@/lib/table/rows/service', () => ({ queryRows: mockQueryRows, })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET } from '@/app/api/table/[tableId]/export/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' /** Table with an id-native column whose stable id (`col_email`) differs from its display name. */ diff --git a/apps/sim/app/api/table/[tableId]/export/route.ts b/apps/sim/app/api/table/[tableId]/export/route.ts index a9fee083ed4..dd11c36315d 100644 --- a/apps/sim/app/api/table/[tableId]/export/route.ts +++ b/apps/sim/app/api/table/[tableId]/export/route.ts @@ -5,12 +5,12 @@ import { getValidationErrorMessage } from '@/lib/api/server' import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { captureServerEvent } from '@/lib/posthog/server' import { sanitizeExportFilename } from '@/lib/table/export-format' import { createTableExportStream, exportContentType } from '@/lib/table/export-stream' import { accessError, checkAccess } from '@/app/api/table/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' interface RouteParams { params: Promise<{ tableId: string }> diff --git a/apps/sim/app/api/table/[tableId]/restore/route.ts b/apps/sim/app/api/table/[tableId]/restore/route.ts index 1d2f3e726c6..8a382bde47d 100644 --- a/apps/sim/app/api/table/[tableId]/restore/route.ts +++ b/apps/sim/app/api/table/[tableId]/restore/route.ts @@ -4,12 +4,12 @@ import { tableIdParamsSchema } from '@/lib/api/contracts/tables' import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { getTableById } from '@/lib/table' import { performRestoreTable } from '@/lib/table/orchestration' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' import { orchestrationOutcomeErrorResponse } from '@/app/api/table/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('RestoreTableAPI') diff --git a/apps/sim/app/api/table/capability-gate.test.ts b/apps/sim/app/api/table/capability-gate.test.ts index 5dd9e2007c3..227561cb2d4 100644 --- a/apps/sim/app/api/table/capability-gate.test.ts +++ b/apps/sim/app/api/table/capability-gate.test.ts @@ -28,7 +28,7 @@ const { mockGetTableById, mockGetUserEntityPermissions, mockAddTableColumn, mock mockListTableViews: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/table', () => ({ addTableColumn: mockAddTableColumn, @@ -48,9 +48,9 @@ vi.mock('@/lib/workspaces/permissions/utils', () => ({ })) vi.mock('@/lib/workspaces/utils', () => ({ getWorkspaceOrganizationId: vi.fn() })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { POST } from '@/app/api/table/[tableId]/columns/route' import { GET } from '@/app/api/table/[tableId]/views/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const USER_ID = 'user-1' const TABLE_ID = '22222222-2222-4222-8222-222222222222' diff --git a/apps/sim/app/api/table/executor-capability-exemption.test.ts b/apps/sim/app/api/table/executor-capability-exemption.test.ts index 9e8d73af8e9..60bf0246284 100644 --- a/apps/sim/app/api/table/executor-capability-exemption.test.ts +++ b/apps/sim/app/api/table/executor-capability-exemption.test.ts @@ -31,7 +31,7 @@ const mocks = vi.hoisted(() => ({ performCreateTableFromCsv: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/table/jobs/service', () => ({ listWorkspaceExportJobs: mocks.listWorkspaceExportJobs, })) @@ -58,9 +58,9 @@ vi.mock('@/lib/core/utils/background', () => ({ runDetached: mocks.runDetached } vi.mock('@/lib/core/config/env-flags', () => ({ isTriggerDevEnabled: false })) vi.mock('@/lib/posthog/server', () => ({ captureServerEvent: vi.fn() })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { POST as importCsv } from '@/app/api/table/import-csv/route' import { GET as listJobs } from '@/app/api/table/jobs/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111' const TABLE_ID = '22222222-2222-4222-8222-222222222222' diff --git a/apps/sim/app/api/table/import-csv/route.test.ts b/apps/sim/app/api/table/import-csv/route.test.ts index 136eb4b0f3e..73942c2f937 100644 --- a/apps/sim/app/api/table/import-csv/route.test.ts +++ b/apps/sim/app/api/table/import-csv/route.test.ts @@ -70,12 +70,12 @@ vi.mock('@/app/api/table/utils', async () => { } }) vi.mock('@/lib/workspaces/permissions/utils', () => permissionsMock) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import { OrchestrationError, type OrchestrationErrorCode } from '@/lib/core/orchestration/types' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { TableLockedError } from '@/lib/table/mutation-locks' import { POST } from '@/app/api/table/import-csv/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' type Part = | { name: string; value: string } diff --git a/apps/sim/app/api/table/import-csv/route.ts b/apps/sim/app/api/table/import-csv/route.ts index f3b03e66baa..1a3b66c30a6 100644 --- a/apps/sim/app/api/table/import-csv/route.ts +++ b/apps/sim/app/api/table/import-csv/route.ts @@ -9,8 +9,6 @@ import { isMultipartError, readMultipart } from '@/lib/core/utils/multipart' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { findActiveFolder } from '@/lib/folders/queries' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { CSV_SYNC_MAX_FILE_SIZE_BYTES } from '@/lib/table' import { performCreateTableFromCsv } from '@/lib/table/orchestration' import { getUserSettings } from '@/lib/users/queries' @@ -20,6 +18,8 @@ import { multipartErrorResponse, orchestrationOutcomeErrorResponse, } from '@/app/api/table/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('TableImportCSV') diff --git a/apps/sim/app/api/table/jobs/route.ts b/apps/sim/app/api/table/jobs/route.ts index f2225b308cd..1470e6fb30a 100644 --- a/apps/sim/app/api/table/jobs/route.ts +++ b/apps/sim/app/api/table/jobs/route.ts @@ -5,9 +5,9 @@ import { parseRequest } from '@/lib/api/server' import { capabilityGovernedAuthUserId, checkSessionOrInternalAuth } from '@/lib/auth/hybrid' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' import { listWorkspaceExportJobs } from '@/lib/table/jobs/service' import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('TableJobsAPI') diff --git a/apps/sim/app/api/table/utils.ts b/apps/sim/app/api/table/utils.ts index daf4ed3d838..f56fa9ae45b 100644 --- a/apps/sim/app/api/table/utils.ts +++ b/apps/sim/app/api/table/utils.ts @@ -10,12 +10,6 @@ import { statusForOrchestrationError, } from '@/lib/core/orchestration/types' import type { MultipartError } from '@/lib/core/utils/multipart' -import type { StaticPermissionGroupCapability } from '@/lib/permission-groups/capabilities' -import { - capabilityRefusal, - isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import type { ColumnDefinition, Filter, TableDefinition, TablePredicate } from '@/lib/table' import { buildFilterClause, getTableById, TableQueryValidationError } from '@/lib/table' import { USER_TABLE_ROWS_SQL_NAME } from '@/lib/table/constants' @@ -25,6 +19,12 @@ import { validateStoragePredicate } from '@/lib/table/query-builder/validate' import type { TableLockKind } from '@/lib/table/types' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' import { getWorkspaceOrganizationId } from '@/lib/workspaces/utils' +import type { StaticPermissionGroupCapability } from '@/ee/access-control/lib/capabilities' +import { + capabilityRefusal, + isWorkspaceCapabilityWithheld, +} from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' /** * Gate for the internal predicate-grammar table query route (`tables-v2-api` diff --git a/apps/sim/app/api/users/me/api-keys/route.ts b/apps/sim/app/api/users/me/api-keys/route.ts index 88a51d54a7d..6395d783cf9 100644 --- a/apps/sim/app/api/users/me/api-keys/route.ts +++ b/apps/sim/app/api/users/me/api-keys/route.ts @@ -9,9 +9,9 @@ import { getApiKeyDisplayFormat } from '@/lib/api-key/auth' import { performCreatePersonalApiKey } from '@/lib/api-key/orchestration' import { getSession } from '@/lib/auth' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { capabilityRefusal } from '@/lib/permission-groups/capability-assertions' -import { isCapabilityWithheldForUser } from '@/lib/permission-groups/user-scope.server' import { captureServerEvent } from '@/lib/posthog/server' +import { capabilityRefusal } from '@/ee/access-control/lib/capability-assertions' +import { isCapabilityWithheldForUser } from '@/ee/access-control/lib/user-scope.server' const logger = createLogger('ApiKeysAPI') diff --git a/apps/sim/app/api/v1/admin/audit-logs/route.ts b/apps/sim/app/api/v1/admin/audit-logs/route.ts index 8403bed1530..f9ad56f5618 100644 --- a/apps/sim/app/api/v1/admin/audit-logs/route.ts +++ b/apps/sim/app/api/v1/admin/audit-logs/route.ts @@ -24,7 +24,6 @@ import { createLogger } from '@sim/logger' import { and, count, desc } from 'drizzle-orm' import { v1AdminListAuditLogsContract } from '@/lib/api/contracts/v1/audit-logs' import { parseRequest } from '@/lib/api/server' -import { buildFilterConditions } from '@/lib/audit-logs/query' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { withAdminAuth } from '@/app/api/v1/admin/middleware' import { @@ -33,6 +32,7 @@ import { listResponse, } from '@/app/api/v1/admin/responses' import { type AdminAuditLog, createPaginationMeta, toAdminAuditLog } from '@/app/api/v1/admin/types' +import { buildFilterConditions } from '@/ee/audit-logs/lib/query' const logger = createLogger('AdminAuditLogsAPI') diff --git a/apps/sim/app/api/v1/admin/organizations/[id]/data-retention/route.ts b/apps/sim/app/api/v1/admin/organizations/[id]/data-retention/route.ts index 97224cb2b25..aadc2c47dc7 100644 --- a/apps/sim/app/api/v1/admin/organizations/[id]/data-retention/route.ts +++ b/apps/sim/app/api/v1/admin/organizations/[id]/data-retention/route.ts @@ -23,7 +23,6 @@ import { createLogger } from '@sim/logger' import { eq } from 'drizzle-orm' import { adminV1UpdateOrganizationDataRetentionContract } from '@/lib/api/contracts/v1/admin' import { parseRequest } from '@/lib/api/server' -import { getForeignWorkspaceTargetsReason } from '@/lib/billing/retention' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { withAdminAuthParams } from '@/app/api/v1/admin/middleware' import { @@ -34,6 +33,7 @@ import { notFoundResponse, singleResponse, } from '@/app/api/v1/admin/responses' +import { getForeignWorkspaceTargetsReason } from '@/ee/data-retention/lib/retention' const logger = createLogger('AdminOrganizationDataRetentionAPI') diff --git a/apps/sim/app/api/v1/admin/organizations/[id]/session-policy/route.ts b/apps/sim/app/api/v1/admin/organizations/[id]/session-policy/route.ts index c38a26c08f4..ccad4db34a1 100644 --- a/apps/sim/app/api/v1/admin/organizations/[id]/session-policy/route.ts +++ b/apps/sim/app/api/v1/admin/organizations/[id]/session-policy/route.ts @@ -20,7 +20,6 @@ import { eq, sql } from 'drizzle-orm' import { adminV1UpdateOrganizationSessionPolicyContract } from '@/lib/api/contracts/v1/admin' import { parseRequest } from '@/lib/api/server' import { invalidateSecurityPolicyVersionCache } from '@/lib/auth/security-policy' -import { eagerClampOrgSessions, invalidateSessionPolicyCache } from '@/lib/auth/session-policy' import { isOrganizationFeatureEntitled } from '@/lib/billing/core/subscription' import { isBillingEnabled, isSessionPoliciesEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' @@ -33,6 +32,10 @@ import { notFoundResponse, singleResponse, } from '@/app/api/v1/admin/responses' +import { + eagerClampOrgSessions, + invalidateSessionPolicyCache, +} from '@/ee/session-policy/lib/session-policy' const logger = createLogger('AdminOrganizationSessionPolicyAPI') diff --git a/apps/sim/app/api/v1/audit-logs/[id]/route.test.ts b/apps/sim/app/api/v1/audit-logs/[id]/route.test.ts index 6849e05ffe6..8b8d1747965 100644 --- a/apps/sim/app/api/v1/audit-logs/[id]/route.test.ts +++ b/apps/sim/app/api/v1/audit-logs/[id]/route.test.ts @@ -28,7 +28,7 @@ vi.mock('@/app/api/v1/audit-logs/auth', () => ({ validateEnterpriseAuditAccess: mockValidateEnterpriseAuditAccess, })) -vi.mock('@/lib/audit-logs/query', () => ({ +vi.mock('@/ee/audit-logs/lib/query', () => ({ buildOrgScopeCondition: mockBuildOrgScopeCondition, getOrgWorkspaceIds: mockGetOrgWorkspaceIds, })) diff --git a/apps/sim/app/api/v1/audit-logs/[id]/route.ts b/apps/sim/app/api/v1/audit-logs/[id]/route.ts index 3ba25fdbfb1..8fb45d7d0d3 100644 --- a/apps/sim/app/api/v1/audit-logs/[id]/route.ts +++ b/apps/sim/app/api/v1/audit-logs/[id]/route.ts @@ -20,12 +20,12 @@ import { and, eq } from 'drizzle-orm' import { type NextRequest, NextResponse } from 'next/server' import { v1GetAuditLogContract } from '@/lib/api/contracts/v1/audit-logs' import { parseRequest } from '@/lib/api/server' -import { buildOrgScopeCondition, getOrgWorkspaceIds } from '@/lib/audit-logs/query' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { validateEnterpriseAuditAccess } from '@/app/api/v1/audit-logs/auth' import { formatAuditLogEntry } from '@/app/api/v1/audit-logs/format' import { createApiResponse, getUserLimits } from '@/app/api/v1/logs/meta' import { checkRateLimit, createRateLimitResponse } from '@/app/api/v1/middleware' +import { buildOrgScopeCondition, getOrgWorkspaceIds } from '@/ee/audit-logs/lib/query' const logger = createLogger('V1AuditLogDetailAPI') diff --git a/apps/sim/app/api/v1/audit-logs/auth.ts b/apps/sim/app/api/v1/audit-logs/auth.ts index 739e1c39918..13491655b5a 100644 --- a/apps/sim/app/api/v1/audit-logs/auth.ts +++ b/apps/sim/app/api/v1/audit-logs/auth.ts @@ -2,7 +2,7 @@ import { NextResponse } from 'next/server' import { type EnterpriseAuditContext, resolveEnterpriseAuditAccess, -} from '@/lib/audit-logs/authorization' +} from '@/ee/audit-logs/lib/authorization' type AuthResult = | { success: true; context: EnterpriseAuditContext } diff --git a/apps/sim/app/api/v1/audit-logs/route.test.ts b/apps/sim/app/api/v1/audit-logs/route.test.ts index 2644d07132f..814a3737d34 100644 --- a/apps/sim/app/api/v1/audit-logs/route.test.ts +++ b/apps/sim/app/api/v1/audit-logs/route.test.ts @@ -34,7 +34,7 @@ vi.mock('@/app/api/v1/audit-logs/auth', () => ({ validateEnterpriseAuditAccess: mockValidateEnterpriseAuditAccess, })) -vi.mock('@/lib/audit-logs/query', () => ({ +vi.mock('@/ee/audit-logs/lib/query', () => ({ buildFilterConditions: mockBuildFilterConditions, buildOrgScopeCondition: mockBuildOrgScopeCondition, getOrgWorkspaceIds: mockGetOrgWorkspaceIds, diff --git a/apps/sim/app/api/v1/audit-logs/route.ts b/apps/sim/app/api/v1/audit-logs/route.ts index e1ddc69d9b1..e3bc59fce49 100644 --- a/apps/sim/app/api/v1/audit-logs/route.ts +++ b/apps/sim/app/api/v1/audit-logs/route.ts @@ -25,12 +25,6 @@ import { generateId } from '@sim/utils/id' import { type NextRequest, NextResponse } from 'next/server' import { v1ListAuditLogsContract } from '@/lib/api/contracts/v1/audit-logs' import { parseRequest } from '@/lib/api/server' -import { - buildFilterConditions, - buildOrgScopeCondition, - getOrgWorkspaceIds, - queryAuditLogs, -} from '@/lib/audit-logs/query' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { validateEnterpriseAuditAccess } from '@/app/api/v1/audit-logs/auth' import { formatAuditLogEntry } from '@/app/api/v1/audit-logs/format' @@ -40,6 +34,12 @@ import { createRateLimitResponse, v1ValidationErrorResponse, } from '@/app/api/v1/middleware' +import { + buildFilterConditions, + buildOrgScopeCondition, + getOrgWorkspaceIds, + queryAuditLogs, +} from '@/ee/audit-logs/lib/query' const logger = createLogger('V1AuditLogsAPI') diff --git a/apps/sim/app/api/v1/capability-gate.test.ts b/apps/sim/app/api/v1/capability-gate.test.ts index b367393a6a9..52f72a5feac 100644 --- a/apps/sim/app/api/v1/capability-gate.test.ts +++ b/apps/sim/app/api/v1/capability-gate.test.ts @@ -52,7 +52,7 @@ const { mockPerformFullDeploy: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/app/api/v1/auth', () => ({ authenticateV1Request: mockAuthenticateV1Request })) vi.mock('@/lib/workspaces/permissions/utils', () => ({ getUserEntityPermissions: mockGetUserEntityPermissions, @@ -113,12 +113,12 @@ vi.mock('@/lib/workflows/orchestration', () => ({ })) vi.mock('@/lib/posthog/server', () => ({ captureServerEvent: vi.fn() })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET as getFiles } from '@/app/api/v1/files/route' import { GET as getKnowledge } from '@/app/api/v1/knowledge/route' import { GET as getLogs } from '@/app/api/v1/logs/route' import { GET as getTables } from '@/app/api/v1/tables/route' import { POST as deployWorkflow } from '@/app/api/v1/workflows/[id]/deploy/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const USER_ID = 'user-1' const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111' diff --git a/apps/sim/app/api/v1/logs/executions/[executionId]/route.test.ts b/apps/sim/app/api/v1/logs/executions/[executionId]/route.test.ts index 5a6ef965d8a..5e4a1465813 100644 --- a/apps/sim/app/api/v1/logs/executions/[executionId]/route.test.ts +++ b/apps/sim/app/api/v1/logs/executions/[executionId]/route.test.ts @@ -36,7 +36,7 @@ vi.mock('@/app/api/v1/middleware', () => ({ resolveWorkspaceAccess: mocks.resolveWorkspaceAccess, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/logs/public-queries', () => ({ getPublicWorkflowLog: mocks.getPublicWorkflowLog, @@ -73,8 +73,8 @@ vi.mock('@/blocks/registry', () => ({ getBlockByToolName: vi.fn(() => undefined), })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET } from '@/app/api/v1/logs/executions/[executionId]/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const rateLimit = { allowed: true, diff --git a/apps/sim/app/api/v1/logs/projection.test.ts b/apps/sim/app/api/v1/logs/projection.test.ts index 16eafc243d5..6070baeb262 100644 --- a/apps/sim/app/api/v1/logs/projection.test.ts +++ b/apps/sim/app/api/v1/logs/projection.test.ts @@ -41,7 +41,7 @@ const { mockMaterialize: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/app/api/v1/auth', () => ({ authenticateV1Request: mockAuthenticateV1Request })) vi.mock('@/lib/workspaces/permissions/utils', () => ({ getUserEntityPermissions: mockGetUserEntityPermissions, @@ -80,10 +80,10 @@ vi.mock('@/app/api/v1/logs/meta', async () => { } }) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET as getLogDetail } from '@/app/api/v1/logs/[id]/route' import { GET as getExecution } from '@/app/api/v1/logs/executions/[executionId]/route' import { GET as listLogs } from '@/app/api/v1/logs/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const USER_ID = 'user-1' const WORKSPACE_ID = '11111111-1111-4111-8111-111111111111' diff --git a/apps/sim/app/api/v1/logs/route.ts b/apps/sim/app/api/v1/logs/route.ts index 2322a06c34d..52f5b78f0fb 100644 --- a/apps/sim/app/api/v1/logs/route.ts +++ b/apps/sim/app/api/v1/logs/route.ts @@ -13,8 +13,6 @@ import { resolveLogFieldProjection, } from '@/lib/logs/log-projection' import { decodePublicLogCursor, listPublicWorkflowLogs } from '@/lib/logs/public-queries' -import { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { createApiResponse, getUserLimits, projectUserLimits } from '@/app/api/v1/logs/meta' import { capabilityGovernedUserId, @@ -23,6 +21,8 @@ import { v1ValidationErrorResponse, validateWorkspaceAccess, } from '@/app/api/v1/middleware' +import { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('V1LogsAPI') diff --git a/apps/sim/app/api/v1/middleware.test.ts b/apps/sim/app/api/v1/middleware.test.ts index 3c92fdb58cd..65c824a6d96 100644 --- a/apps/sim/app/api/v1/middleware.test.ts +++ b/apps/sim/app/api/v1/middleware.test.ts @@ -55,7 +55,7 @@ vi.mock('@/lib/core/rate-limiter', () => ({ }, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/workspaces/permissions/utils', () => ({ getUserEntityPermissions: mockGetUserEntityPermissions, @@ -66,7 +66,6 @@ vi.mock('@/lib/workspaces/utils', () => ({ getWorkspaceBilledAccountUserId: mockGetWorkspaceBilledAccountUserId, })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { authenticateRequest, checkRateLimit, @@ -75,6 +74,7 @@ import { requireWorkspaceRequestActor, v1ValidationErrorResponse, } from '@/app/api/v1/middleware' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' /** Mirrors `createBucketConfig`: capacity is the per-minute rate x burst multiplier. */ const TEAM_BUCKET = { maxTokens: 400, refillRate: 200, refillIntervalMs: 60_000 } diff --git a/apps/sim/app/api/v1/middleware.ts b/apps/sim/app/api/v1/middleware.ts index dbde4f2837a..3f2192bf4bf 100644 --- a/apps/sim/app/api/v1/middleware.ts +++ b/apps/sim/app/api/v1/middleware.ts @@ -11,14 +11,6 @@ import type { ForbiddenDetailCode } from '@/lib/core/application/forbidden' import type { SubscriptionPlan } from '@/lib/core/rate-limiter' import { getRateLimit, RateLimiter } from '@/lib/core/rate-limiter' import { generateRequestId } from '@/lib/core/utils/request' -import { - CAPABILITY_RULES, - type StaticPermissionGroupCapability, -} from '@/lib/permission-groups/capabilities' -import { - capabilityRefusal, - isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' import { getWorkspaceBilledAccountUserId, @@ -26,6 +18,14 @@ import { } from '@/lib/workspaces/utils' import type { TableAccessPrincipal } from '@/app/api/table/utils' import { authenticateV1Request } from '@/app/api/v1/auth' +import { + CAPABILITY_RULES, + type StaticPermissionGroupCapability, +} from '@/ee/access-control/lib/capabilities' +import { + capabilityRefusal, + isWorkspaceCapabilityWithheld, +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('V1Middleware') const rateLimiter = new RateLimiter() diff --git a/apps/sim/app/api/v1/tables/capability-gate.test.ts b/apps/sim/app/api/v1/tables/capability-gate.test.ts index 1936de7a5c5..5810c7d5de0 100644 --- a/apps/sim/app/api/v1/tables/capability-gate.test.ts +++ b/apps/sim/app/api/v1/tables/capability-gate.test.ts @@ -39,7 +39,7 @@ const { mockGetTableById: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/app/api/v1/auth', () => ({ authenticateV1Request: mockAuthenticateV1Request })) vi.mock('@/lib/workspaces/permissions/utils', () => ({ getUserEntityPermissions: mockGetUserEntityPermissions, @@ -60,8 +60,8 @@ vi.mock('@/lib/table', () => ({ vi.mock('@/lib/table/orchestration', () => ({ performDeleteTable: vi.fn() })) vi.mock('@/lib/table/wire', () => ({ normalizeColumn: (column: unknown) => column })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET as getTable } from '@/app/api/v1/tables/[tableId]/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const MEMBER_ID = 'user-1' const TABLE_ID = '22222222-2222-4222-8222-222222222222' diff --git a/apps/sim/app/api/v2/audit-logs/[auditLogId]/route.ts b/apps/sim/app/api/v2/audit-logs/[auditLogId]/route.ts index bf37d146527..6f4ed11d01a 100644 --- a/apps/sim/app/api/v2/audit-logs/[auditLogId]/route.ts +++ b/apps/sim/app/api/v2/audit-logs/[auditLogId]/route.ts @@ -5,9 +5,9 @@ import { v2OrchestrationErrorPolicy, v2RateLimits, } from '@/lib/api/server/routes' -import { getAuditLog } from '@/lib/audit-logs/application/get-audit-log' -import { auditLogOperations } from '@/lib/audit-logs/application/operations' import { formatV2AuditLogEntry } from '@/app/api/v2/audit-logs/format' +import { getAuditLog } from '@/ee/audit-logs/lib/application/get-audit-log' +import { auditLogOperations } from '@/ee/audit-logs/lib/application/operations' export const revalidate = 0 diff --git a/apps/sim/app/api/v2/audit-logs/route.test.ts b/apps/sim/app/api/v2/audit-logs/route.test.ts index 0bf0f7baece..120233a7efc 100644 --- a/apps/sim/app/api/v2/audit-logs/route.test.ts +++ b/apps/sim/app/api/v2/audit-logs/route.test.ts @@ -19,11 +19,11 @@ const mocks = vi.hoisted(() => ({ vi.mock('@/lib/api/server/routes/v2-api-key-auth', () => v2ApiKeyAuthModuleMock) vi.mock('@/lib/core/rate-limiter', () => v2RateLimiterModuleMock) -vi.mock('@/lib/audit-logs/application/list-audit-logs', () => ({ +vi.mock('@/ee/audit-logs/lib/application/list-audit-logs', () => ({ listAuditLogs: { operation: { id: 'audit_logs.list' }, execute: mocks.list }, })) -vi.mock('@/lib/audit-logs/application/get-audit-log', () => ({ +vi.mock('@/ee/audit-logs/lib/application/get-audit-log', () => ({ getAuditLog: { operation: { id: 'audit_logs.read_detail' }, execute: mocks.get }, })) diff --git a/apps/sim/app/api/v2/audit-logs/route.ts b/apps/sim/app/api/v2/audit-logs/route.ts index fbce5e2d92b..4ee4c3acace 100644 --- a/apps/sim/app/api/v2/audit-logs/route.ts +++ b/apps/sim/app/api/v2/audit-logs/route.ts @@ -11,10 +11,10 @@ import { v2OrchestrationErrorPolicy, v2RateLimits, } from '@/lib/api/server/routes' -import { listAuditLogs } from '@/lib/audit-logs/application/list-audit-logs' -import { auditLogOperations } from '@/lib/audit-logs/application/operations' import { formatV2AuditLogEntry } from '@/app/api/v2/audit-logs/format' import { encodeScopedCursor, readScopedCursor } from '@/app/api/v2/lib/response' +import { listAuditLogs } from '@/ee/audit-logs/lib/application/list-audit-logs' +import { auditLogOperations } from '@/ee/audit-logs/lib/application/operations' /** * Every param that changes which audit entries, in which order, this list diff --git a/apps/sim/app/api/v2/chat/route.test.ts b/apps/sim/app/api/v2/chat/route.test.ts index af7f28a3930..bbe6c31a5c2 100644 --- a/apps/sim/app/api/v2/chat/route.test.ts +++ b/apps/sim/app/api/v2/chat/route.test.ts @@ -120,15 +120,15 @@ vi.mock('@/lib/core/config/env-flags', () => ({ isDocSandboxEnabled: false, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) const mockResolvePermissionGroupConfig = permissionGroupScopeMockFns.mockResolvePermissionGroupConfig import { chatOperations } from '@/lib/copilot/application/operations' -import { CAPABILITY_RULES } from '@/lib/permission-groups/capabilities' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { POST } from '@/app/api/v2/chat/route' +import { CAPABILITY_RULES } from '@/ee/access-control/lib/capabilities' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const personalAuth = { principal: { kind: 'personal_api_key', userId: 'user-1', keyId: 'key-1' }, diff --git a/apps/sim/app/api/v2/chat/route.ts b/apps/sim/app/api/v2/chat/route.ts index 17932605f92..9f2dc52d195 100644 --- a/apps/sim/app/api/v2/chat/route.ts +++ b/apps/sim/app/api/v2/chat/route.ts @@ -45,16 +45,16 @@ import { import { isDocSandboxEnabled } from '@/lib/core/config/env-flags' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { getPersonalAndWorkspaceEnv } from '@/lib/environment/utils' -import { CAPABILITY_RULES } from '@/lib/permission-groups/capabilities' -import { - capabilityRefusal, - isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' import { assertActiveWorkspaceAccess, isWorkspaceAccessDeniedError, } from '@/lib/workspaces/permissions/utils' import { v2Data, v2Error } from '@/app/api/v2/lib/response' +import { CAPABILITY_RULES } from '@/ee/access-control/lib/capabilities' +import { + capabilityRefusal, + isWorkspaceCapabilityWithheld, +} from '@/ee/access-control/lib/capability-assertions' export const dynamic = 'force-dynamic' export const maxDuration = 3600 diff --git a/apps/sim/app/api/v2/workflows/[workflowId]/deployments/chat/route.test.ts b/apps/sim/app/api/v2/workflows/[workflowId]/deployments/chat/route.test.ts index 51900d00d90..cb938947026 100644 --- a/apps/sim/app/api/v2/workflows/[workflowId]/deployments/chat/route.test.ts +++ b/apps/sim/app/api/v2/workflows/[workflowId]/deployments/chat/route.test.ts @@ -12,7 +12,7 @@ import { } from '@sim/testing' import { NextRequest } from 'next/server' import { beforeEach, describe, expect, it, vi } from 'vitest' -import { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' +import { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' const mocks = vi.hoisted(() => ({ resolvePermission: vi.fn(), diff --git a/apps/sim/app/api/v2/workflows/[workflowId]/execute/route.test.ts b/apps/sim/app/api/v2/workflows/[workflowId]/execute/route.test.ts index 6449e170f57..573d9139ab6 100644 --- a/apps/sim/app/api/v2/workflows/[workflowId]/execute/route.test.ts +++ b/apps/sim/app/api/v2/workflows/[workflowId]/execute/route.test.ts @@ -120,7 +120,7 @@ vi.mock('@/background/workflow-execution', () => ({ executeWorkflowJob: vi.fn(), })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ getCustomBlockRowsForWorkspace: vi.fn().mockResolvedValue([]), })) diff --git a/apps/sim/app/api/webhooks/[id]/reactivation-gate.test.ts b/apps/sim/app/api/webhooks/[id]/reactivation-gate.test.ts index 292e1d48ca0..26f96fb6fec 100644 --- a/apps/sim/app/api/webhooks/[id]/reactivation-gate.test.ts +++ b/apps/sim/app/api/webhooks/[id]/reactivation-gate.test.ts @@ -17,13 +17,13 @@ import { import { beforeEach, describe, expect, it, vi } from 'vitest' vi.mock('@sim/audit', () => auditMock) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/core/telemetry', () => telemetryMock) vi.mock('@/lib/posthog/server', () => posthogServerMock) vi.mock('@/lib/webhooks/provider-subscriptions', () => ({ cleanupExternalWebhook: vi.fn() })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { PATCH } from '@/app/api/webhooks/[id]/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const ACTOR_ID = 'actor-1' diff --git a/apps/sim/app/api/webhooks/[id]/route.ts b/apps/sim/app/api/webhooks/[id]/route.ts index 5b3b7571f06..0a2c27f1a1d 100644 --- a/apps/sim/app/api/webhooks/[id]/route.ts +++ b/apps/sim/app/api/webhooks/[id]/route.ts @@ -19,12 +19,12 @@ import { capabilityGovernedAuthUserId, checkSessionOrInternalAuth } from '@/lib/ import { PlatformEvents } from '@/lib/core/telemetry' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { captureServerEvent } from '@/lib/posthog/server' +import { cleanupExternalWebhook } from '@/lib/webhooks/provider-subscriptions' import { capabilityRefusal, isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' -import { captureServerEvent } from '@/lib/posthog/server' -import { cleanupExternalWebhook } from '@/lib/webhooks/provider-subscriptions' +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('WebhookAPI') diff --git a/apps/sim/app/api/webhooks/route.test.ts b/apps/sim/app/api/webhooks/route.test.ts index 85c318c1ca2..af013896ce0 100644 --- a/apps/sim/app/api/webhooks/route.test.ts +++ b/apps/sim/app/api/webhooks/route.test.ts @@ -28,7 +28,7 @@ const mocks = vi.hoisted(() => ({ })) vi.mock('@sim/audit', () => auditMock) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/core/telemetry', () => telemetryMock) vi.mock('@/lib/posthog/server', () => posthogServerMock) vi.mock('@/lib/webhooks/env-resolver', () => ({ @@ -46,8 +46,8 @@ vi.mock('@/lib/webhooks/utils.server', () => ({ findConflictingWebhookPathOwner: mocks.findConflictingWebhookPathOwner, })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { POST } from '@/app/api/webhooks/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' describe('POST /api/webhooks polling configuration', () => { beforeEach(() => { diff --git a/apps/sim/app/api/webhooks/route.ts b/apps/sim/app/api/webhooks/route.ts index e96cb78b084..37518049936 100644 --- a/apps/sim/app/api/webhooks/route.ts +++ b/apps/sim/app/api/webhooks/route.ts @@ -17,10 +17,6 @@ import { getSession } from '@/lib/auth' import { PlatformEvents } from '@/lib/core/telemetry' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { - capabilityRefusal, - isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' import { captureServerEvent } from '@/lib/posthog/server' import { resolveEnvVarsInObject } from '@/lib/webhooks/env-resolver' import { @@ -32,6 +28,10 @@ import { getProviderHandler } from '@/lib/webhooks/providers' import { mergeNonUserFields } from '@/lib/webhooks/utils' import { findConflictingWebhookPathOwner } from '@/lib/webhooks/utils.server' import { listAccessibleWorkspaceRowsForUser } from '@/lib/workspaces/utils' +import { + capabilityRefusal, + isWorkspaceCapabilityWithheld, +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('WebhooksAPI') diff --git a/apps/sim/app/api/workflows/[id]/execute/route.ts b/apps/sim/app/api/workflows/[id]/execute/route.ts index 2d99b7a7a7f..7d931424d5f 100644 --- a/apps/sim/app/api/workflows/[id]/execute/route.ts +++ b/apps/sim/app/api/workflows/[id]/execute/route.ts @@ -103,7 +103,6 @@ import { cleanupExecutionBase64Cache, hydrateUserFilesWithBase64, } from '@/lib/uploads/utils/user-file-base64.server' -import { getCustomBlockRowsForWorkspace } from '@/lib/workflows/custom-blocks/operations' import { checkNeedsRedeployment } from '@/lib/workflows/deployment-status' import { enqueueWorkflowExecution } from '@/lib/workflows/executor/enqueue-execution' import { executeWorkflow } from '@/lib/workflows/executor/execute-workflow' @@ -154,6 +153,7 @@ import { PublicApiNotAllowedError, validatePublicApiAllowed, } from '@/ee/access-control/utils/permission-check' +import { getCustomBlockRowsForWorkspace } from '@/ee/custom-blocks/lib/operations' import { ExecutionSnapshot } from '@/executor/execution/snapshot' import type { BlockCompletionCallbackData, diff --git a/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.test.ts b/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.test.ts index dc8b2212ab6..8ec4f9b13e4 100644 --- a/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.test.ts +++ b/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.test.ts @@ -13,7 +13,7 @@ import { } from '@sim/testing' import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest' -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) const { mockGetUserEntityPermissions } = vi.hoisted(() => ({ mockGetUserEntityPermissions: vi.fn(), @@ -31,9 +31,9 @@ vi.mock('@sim/audit', () => ({ vi.mock('@/lib/posthog/server', () => ({ captureServerEvent: vi.fn() })) -import { capabilityRefusal } from '@/lib/permission-groups/capabilities' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { DELETE, PUT } from '@/app/api/workspaces/[id]/api-keys/[keyId]/route' +import { capabilityRefusal } from '@/ee/access-control/lib/capabilities' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const mockGetSession = authMockFns.mockGetSession diff --git a/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts b/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts index 1bde6980ea4..db377626484 100644 --- a/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts +++ b/apps/sim/app/api/workspaces/[id]/api-keys/[keyId]/route.ts @@ -10,12 +10,12 @@ import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { captureServerEvent } from '@/lib/posthog/server' +import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' import { capabilityRefusal, isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' -import { captureServerEvent } from '@/lib/posthog/server' -import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('WorkspaceApiKeyAPI') diff --git a/apps/sim/app/api/workspaces/[id]/api-keys/route.ts b/apps/sim/app/api/workspaces/[id]/api-keys/route.ts index c0923b3a89d..12494414bcd 100644 --- a/apps/sim/app/api/workspaces/[id]/api-keys/route.ts +++ b/apps/sim/app/api/workspaces/[id]/api-keys/route.ts @@ -16,12 +16,12 @@ import { getSession } from '@/lib/auth' import { PlatformEvents } from '@/lib/core/telemetry' import { generateRequestId } from '@/lib/core/utils/request' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' +import { captureServerEvent } from '@/lib/posthog/server' +import { getUserEntityPermissions, getWorkspaceById } from '@/lib/workspaces/permissions/utils' import { capabilityRefusal, isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' -import { captureServerEvent } from '@/lib/posthog/server' -import { getUserEntityPermissions, getWorkspaceById } from '@/lib/workspaces/permissions/utils' +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('WorkspaceApiKeysAPI') diff --git a/apps/sim/app/api/workspaces/[id]/environment/capability-gate.test.ts b/apps/sim/app/api/workspaces/[id]/environment/capability-gate.test.ts index 6dcb807185b..b01c7e827f2 100644 --- a/apps/sim/app/api/workspaces/[id]/environment/capability-gate.test.ts +++ b/apps/sim/app/api/workspaces/[id]/environment/capability-gate.test.ts @@ -30,7 +30,7 @@ const { mockGetPersonalEnvKeyRawAccess: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/workspaces/permissions/utils', () => ({ getWorkspaceById: mockGetWorkspaceById, @@ -44,8 +44,8 @@ vi.mock('@/lib/credentials/environment', () => ({ deleteWorkspaceEnvCredentials: vi.fn(), })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { DELETE, GET, PUT } from '@/app/api/workspaces/[id]/environment/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const USER_ID = 'user-1' const WORKSPACE_ID = 'ws-1' diff --git a/apps/sim/app/api/workspaces/[id]/environment/route.ts b/apps/sim/app/api/workspaces/[id]/environment/route.ts index eadffd8ec92..f2d80e0c60f 100644 --- a/apps/sim/app/api/workspaces/[id]/environment/route.ts +++ b/apps/sim/app/api/workspaces/[id]/environment/route.ts @@ -26,14 +26,14 @@ import { getPersonalAndWorkspaceEnv, invalidateEffectiveDecryptedEnvCache, } from '@/lib/environment/utils' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { captureServerEvent } from '@/lib/posthog/server' import { getUserEntityPermissions, getWorkspaceById, type PermissionType, } from '@/lib/workspaces/permissions/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('WorkspaceEnvironmentAPI') diff --git a/apps/sim/app/api/workspaces/[id]/inbox/route.test.ts b/apps/sim/app/api/workspaces/[id]/inbox/route.test.ts index 0c9e4ecf029..336f39c8a14 100644 --- a/apps/sim/app/api/workspaces/[id]/inbox/route.test.ts +++ b/apps/sim/app/api/workspaces/[id]/inbox/route.test.ts @@ -37,10 +37,10 @@ vi.mock('@/lib/workspaces/permissions/utils', () => ({ getUserEntityPermissions: mockGetUserEntityPermissions, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET, PATCH } from '@/app/api/workspaces/[id]/inbox/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const context = { params: Promise.resolve({ id: 'workspace-1' }) } diff --git a/apps/sim/app/api/workspaces/[id]/inbox/route.ts b/apps/sim/app/api/workspaces/[id]/inbox/route.ts index 5b53c629cb1..d9cac96a02f 100644 --- a/apps/sim/app/api/workspaces/[id]/inbox/route.ts +++ b/apps/sim/app/api/workspaces/[id]/inbox/route.ts @@ -10,9 +10,9 @@ import { hasWorkspaceInboxAccess } from '@/lib/billing/core/subscription' import { normalizeSecretMountPolicy } from '@/lib/copilot/secret-mount-policy' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' import { disableInbox, enableInbox, updateInboxAddress } from '@/lib/mothership/inbox/lifecycle' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('InboxConfigAPI') diff --git a/apps/sim/app/api/workspaces/[id]/inbox/senders/route.ts b/apps/sim/app/api/workspaces/[id]/inbox/senders/route.ts index 3530aca8edb..105a01f8e78 100644 --- a/apps/sim/app/api/workspaces/[id]/inbox/senders/route.ts +++ b/apps/sim/app/api/workspaces/[id]/inbox/senders/route.ts @@ -8,9 +8,9 @@ import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { hasWorkspaceInboxAccess } from '@/lib/billing/core/subscription' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('InboxSendersAPI') diff --git a/apps/sim/app/api/workspaces/[id]/inbox/siblings.capability.test.ts b/apps/sim/app/api/workspaces/[id]/inbox/siblings.capability.test.ts index 7c934e5abf2..b939d43a665 100644 --- a/apps/sim/app/api/workspaces/[id]/inbox/siblings.capability.test.ts +++ b/apps/sim/app/api/workspaces/[id]/inbox/siblings.capability.test.ts @@ -29,15 +29,15 @@ vi.mock('@/lib/workspaces/permissions/utils', () => ({ getUserEntityPermissions: mockGetUserEntityPermissions, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { DELETE as DELETE_SENDER, GET as GET_SENDERS, POST as POST_SENDER, } from '@/app/api/workspaces/[id]/inbox/senders/route' import { GET as GET_TASKS } from '@/app/api/workspaces/[id]/inbox/tasks/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const context = { params: Promise.resolve({ id: 'workspace-1' }) } const REFUSAL = "The inbox is not available under your organization's permission group" diff --git a/apps/sim/app/api/workspaces/[id]/inbox/tasks/route.ts b/apps/sim/app/api/workspaces/[id]/inbox/tasks/route.ts index 02fd9057214..cbf0f4a9bd7 100644 --- a/apps/sim/app/api/workspaces/[id]/inbox/tasks/route.ts +++ b/apps/sim/app/api/workspaces/[id]/inbox/tasks/route.ts @@ -6,9 +6,9 @@ import { getValidationErrorMessage } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { hasWorkspaceInboxAccess } from '@/lib/billing/core/subscription' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' export const GET = withRouteHandler( async (req: NextRequest, { params }: { params: Promise<{ id: string }> }) => { diff --git a/apps/sim/app/api/workspaces/route.ts b/apps/sim/app/api/workspaces/route.ts index 50033c1d51c..d318abe8cfd 100644 --- a/apps/sim/app/api/workspaces/route.ts +++ b/apps/sim/app/api/workspaces/route.ts @@ -11,7 +11,6 @@ import { parseRequest } from '@/lib/api/server' import { getSession } from '@/lib/auth' import { getActiveOrganizationId } from '@/lib/auth/session-response' import { withRouteHandler } from '@/lib/core/utils/with-route-handler' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { captureServerEvent } from '@/lib/posthog/server' import { createWorkspace } from '@/lib/workspaces/create' import { listWorkspacesForViewer } from '@/lib/workspaces/list' @@ -20,6 +19,7 @@ import { WorkspaceCreationCapabilityWithheldError, WorkspaceCreationContextChangedError, } from '@/lib/workspaces/policy' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' const logger = createLogger('Workspaces') diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/dropdown/dropdown.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/dropdown/dropdown.tsx index 081d329bc3c..8cccd73b0e2 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/dropdown/dropdown.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/dropdown/dropdown.tsx @@ -2,10 +2,6 @@ import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { ChipTag, Combobox, type ComboboxOption } from '@sim/emcn' import { generateId } from '@sim/utils/id' import { isRecordLike } from '@sim/utils/object' -import { - NO_DENIED_OPERATIONS, - OPERATION_SUBBLOCK_ID, -} from '@/lib/permission-groups/operation-access' import type { SelectorKey } from '@/lib/selectors/manifest' import { SEARCH_DEBOUNCE_MS } from '@/lib/url-state' import { getDependsOnFields } from '@/lib/workflows/subblocks/dependencies' @@ -17,6 +13,10 @@ import { useSubBlockValue } from '@/app/workspace/[workspaceId]/w/[workflowId]/c import { useActiveSearchTarget } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/providers/active-search-target-provider' import { getBlock } from '@/blocks/registry' import type { SubBlockConfig } from '@/blocks/types' +import { + NO_DENIED_OPERATIONS, + OPERATION_SUBBLOCK_ID, +} from '@/ee/access-control/lib/operation-access' import { ResponseBlockHandler } from '@/executor/handlers/response/response-handler' import { useDebounce } from '@/hooks/use-debounce' import { useOperationAccess } from '@/hooks/use-operation-access' diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx index b5e2bb9aed2..adc42a51506 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx @@ -25,10 +25,6 @@ import { getMcpToolIssue as validateMcpTool, } from '@/lib/mcp/tool-validation' import type { McpToolSchema } from '@/lib/mcp/types' -import { - NO_DENIED_OPERATIONS, - OPERATION_SUBBLOCK_ID, -} from '@/lib/permission-groups/operation-access' import { resolveStoredToolName } from '@/lib/workflows/subblocks/display' import { buildToolSubBlockId } from '@/lib/workflows/tool-input/synthetic-subblocks' import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider' @@ -59,6 +55,10 @@ import { useCustomBlockOverlayVersion } from '@/blocks/custom/client-overlay' import { getTileIconColorClass } from '@/blocks/icon-color' import type { BlockConfig, SubBlockConfig as BlockSubBlockConfig } from '@/blocks/types' import { BUILT_IN_TOOL_TYPES } from '@/blocks/utils' +import { + NO_DENIED_OPERATIONS, + OPERATION_SUBBLOCK_ID, +} from '@/ee/access-control/lib/operation-access' import { useMcpOauthPopup } from '@/hooks/mcp/use-mcp-oauth-popup' import { useMcpTools } from '@/hooks/mcp/use-mcp-tools' import { useWorkspaceCredential } from '@/hooks/queries/credentials' diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx index 475d610c851..eb6488d7191 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx @@ -47,7 +47,6 @@ import type { OAuthConnectEventDetail } from '@/lib/copilot/tools/client/base-to import { consumeOAuthReturnContext, writeOAuthReturnContext } from '@/lib/credentials/client-state' import type { OAuthProvider } from '@/lib/oauth' import { usesCredentialConfiguredOAuthClient } from '@/lib/oauth/utils' -import { OPERATION_SUBBLOCK_ID } from '@/lib/permission-groups/operation-access' import { DEFAULT_HORIZONTAL_SPACING, DEFAULT_VERTICAL_SPACING, @@ -127,6 +126,7 @@ import { } from '@/app/workspace/[workspaceId]/w/[workflowId]/workflow-constants' import { useSocket } from '@/app/workspace/providers/socket-provider' import { getBlock } from '@/blocks' +import { OPERATION_SUBBLOCK_ID } from '@/ee/access-control/lib/operation-access' import { isAnnotationOnlyBlock } from '@/executor/constants' import { useCustomBlocks } from '@/hooks/queries/custom-blocks' import { useWorkspaceEnvironment } from '@/hooks/queries/environment' diff --git a/apps/sim/background/run-data-drain.ts b/apps/sim/background/run-data-drain.ts index 21d462055df..13b8f8693e6 100644 --- a/apps/sim/background/run-data-drain.ts +++ b/apps/sim/background/run-data-drain.ts @@ -1,6 +1,6 @@ import { task } from '@trigger.dev/sdk' -import { runDrain } from '@/lib/data-drains/service' -import type { RunTrigger } from '@/lib/data-drains/types' +import { runDrain } from '@/ee/data-drains/lib/service' +import type { RunTrigger } from '@/ee/data-drains/lib/types' interface RunDataDrainPayload { drainId: string diff --git a/apps/sim/ee/README.md b/apps/sim/ee/README.md index f0377161e5e..638481f0c98 100644 --- a/apps/sim/ee/README.md +++ b/apps/sim/ee/README.md @@ -7,8 +7,20 @@ for production use. - **SSO (Single Sign-On)**: OIDC and SAML authentication integration - **Access Control**: Permission groups for fine-grained user access management +- **Audit Logs**: Organization-wide audit trail with search and export +- **Data Drains**: Streaming of logs and audit events to external destinations +- **Data Retention**: Organization-level retention windows for execution data +- **Session Policies**: Session lifetime and idle-timeout controls +- **Custom Blocks**: Organization-owned reusable blocks for the workflow builder +- **Usage Monitoring**: Organization usage breakdown, consumers, and event export +- **Workspace Forking**: Fork, sync, and promote workspaces across environments - **Whitelabeling**: Custom branding and theming for enterprise deployments +Each feature keeps its server code under `ee//lib`, its React Query hooks under +`ee//hooks`, and its UI under `ee//components`. Contracts stay in +`lib/api/contracts` and routes under `app/api`, so the enterprise directory is imported by the +rest of the app rather than the other way round. + ## Licensing See [LICENSE](./LICENSE) for terms. Development and testing use is permitted. diff --git a/apps/sim/ee/access-control/components/group-detail.tsx b/apps/sim/ee/access-control/components/group-detail.tsx index a115c94a864..909b626e778 100644 --- a/apps/sim/ee/access-control/components/group-detail.tsx +++ b/apps/sim/ee/access-control/components/group-detail.tsx @@ -30,14 +30,6 @@ import { formatDate } from '@sim/utils/formatting' import { useQueryState } from 'nuqs' import { saveDiscardActions } from '@/components/settings/save-discard-actions' import type { ShareAuthType } from '@/lib/api/contracts/public-shares' -import { isAccessControlAllowlistRow } from '@/lib/permission-groups/block-access' -import { - isFeatureInertForGroup, - ORGANIZATION_SCOPED_FEATURE_NOTE, - PLATFORM_CATEGORY_ORDER, - PLATFORM_FEATURES, -} from '@/lib/permission-groups/features' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' import { UnsavedChangesModal } from '@/app/workspace/[workspaceId]/components/credential-detail' import { groupSearchParam, @@ -70,6 +62,14 @@ import { useRemovePermissionGroupMember, useUpdatePermissionGroup, } from '@/ee/access-control/hooks/permission-groups' +import { isAccessControlAllowlistRow } from '@/ee/access-control/lib/block-access' +import { + isFeatureInertForGroup, + ORGANIZATION_SCOPED_FEATURE_NOTE, + PLATFORM_CATEGORY_ORDER, + PLATFORM_FEATURES, +} from '@/ee/access-control/lib/features' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' import { allowlistRowsFromStored, toggleAllowlistRow, diff --git a/apps/sim/lib/permission-groups/block-access.test.ts b/apps/sim/ee/access-control/lib/block-access.test.ts similarity index 98% rename from apps/sim/lib/permission-groups/block-access.test.ts rename to apps/sim/ee/access-control/lib/block-access.test.ts index 88514b10888..b4ef2411319 100644 --- a/apps/sim/lib/permission-groups/block-access.test.ts +++ b/apps/sim/ee/access-control/lib/block-access.test.ts @@ -2,11 +2,11 @@ * @vitest-environment node */ import { beforeEach, describe, expect, it, vi } from 'vitest' +import { getBlock } from '@/blocks/registry' import { isAccessControlAllowlistRow, isBlockTypeAccessControlExempt, -} from '@/lib/permission-groups/block-access' -import { getBlock } from '@/blocks/registry' +} from '@/ee/access-control/lib/block-access' const mockGetBlock = getBlock as unknown as ReturnType diff --git a/apps/sim/lib/permission-groups/block-access.ts b/apps/sim/ee/access-control/lib/block-access.ts similarity index 97% rename from apps/sim/lib/permission-groups/block-access.ts rename to apps/sim/ee/access-control/lib/block-access.ts index e18a2068ae1..b47ad03ce33 100644 --- a/apps/sim/lib/permission-groups/block-access.ts +++ b/apps/sim/ee/access-control/lib/block-access.ts @@ -1,5 +1,5 @@ -import { resolveAccessControlBlockType } from '@/lib/permission-groups/integration-allowlist' import { getBlock } from '@/blocks/registry' +import { resolveAccessControlBlockType } from '@/ee/access-control/lib/integration-allowlist' /** * The universal workflow entry point. Every retired entry point resolves to it, diff --git a/apps/sim/lib/permission-groups/block-successors.generated.ts b/apps/sim/ee/access-control/lib/block-successors.generated.ts similarity index 95% rename from apps/sim/lib/permission-groups/block-successors.generated.ts rename to apps/sim/ee/access-control/lib/block-successors.generated.ts index d4f7c30c858..6c987f250f0 100644 --- a/apps/sim/lib/permission-groups/block-successors.generated.ts +++ b/apps/sim/ee/access-control/lib/block-successors.generated.ts @@ -4,7 +4,7 @@ * * Maps a retired block type to the *terminal* type an access-control decision * about it is made against — `sunset.replacedBy`, followed transitively. It - * exists as a generated projection because `lib/permission-groups/` may not + * exists as a generated projection because `ee/access-control/lib/` may not * import `blocks/`; see `scripts/generate-block-successors.ts`. */ export const BLOCK_ACCESS_SUCCESSORS: Record = { diff --git a/apps/sim/lib/permission-groups/capabilities.test.ts b/apps/sim/ee/access-control/lib/capabilities.test.ts similarity index 94% rename from apps/sim/lib/permission-groups/capabilities.test.ts rename to apps/sim/ee/access-control/lib/capabilities.test.ts index 30e19dc4cf0..7cd73a925be 100644 --- a/apps/sim/lib/permission-groups/capabilities.test.ts +++ b/apps/sim/ee/access-control/lib/capabilities.test.ts @@ -3,11 +3,11 @@ */ import { describe, expect, it } from 'vitest' -import { CAPABILITY_RULES } from '@/lib/permission-groups/capabilities' +import { CAPABILITY_RULES } from '@/ee/access-control/lib/capabilities' import { DEFAULT_PERMISSION_GROUP_CONFIG, type PermissionGroupConfig, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' function configWith(overrides: Partial): PermissionGroupConfig { return { ...DEFAULT_PERMISSION_GROUP_CONFIG, ...overrides } diff --git a/apps/sim/lib/permission-groups/capabilities.ts b/apps/sim/ee/access-control/lib/capabilities.ts similarity index 99% rename from apps/sim/lib/permission-groups/capabilities.ts rename to apps/sim/ee/access-control/lib/capabilities.ts index df0d117c819..0835bb1fd46 100644 --- a/apps/sim/lib/permission-groups/capabilities.ts +++ b/apps/sim/ee/access-control/lib/capabilities.ts @@ -1,9 +1,9 @@ import type { ForbiddenDetailCode } from '@/lib/core/application/forbidden' -import { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' +import { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' import type { PermissionGroupConfig, PermissionGroupConfigKey, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' /** * Every capability a permission group can withhold. diff --git a/apps/sim/lib/permission-groups/capability-assertions.ts b/apps/sim/ee/access-control/lib/capability-assertions.ts similarity index 92% rename from apps/sim/lib/permission-groups/capability-assertions.ts rename to apps/sim/ee/access-control/lib/capability-assertions.ts index 5ea30faf313..b5e0df4d903 100644 --- a/apps/sim/lib/permission-groups/capability-assertions.ts +++ b/apps/sim/ee/access-control/lib/capability-assertions.ts @@ -3,20 +3,20 @@ import { CAPABILITY_RULES, refuseCapability, type StaticPermissionGroupCapability, -} from '@/lib/permission-groups/capabilities' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/capabilities' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' import { getEntitledOrganizationPermissionConfig, getUserPermissionConfigForOrganization, -} from '@/lib/permission-groups/resolve.server' +} from '@/ee/access-control/lib/resolve.server' /** * Re-exported so a caller that gates inline reaches the refusal sentence and the * assertions through one module; {@link CAPABILITY_RULES} remains its only * definition. */ -export { capabilityRefusal } from '@/lib/permission-groups/capabilities' +export { capabilityRefusal } from '@/ee/access-control/lib/capabilities' /** * The one way to ask whether a permission group withholds a capability. diff --git a/apps/sim/lib/permission-groups/capability-error.ts b/apps/sim/ee/access-control/lib/capability-error.ts similarity index 92% rename from apps/sim/lib/permission-groups/capability-error.ts rename to apps/sim/ee/access-control/lib/capability-error.ts index a470a7592b6..a17e0143267 100644 --- a/apps/sim/lib/permission-groups/capability-error.ts +++ b/apps/sim/ee/access-control/lib/capability-error.ts @@ -1,5 +1,5 @@ import { type ForbiddenDetailCode, ForbiddenOperationError } from '@/lib/core/application/forbidden' -import type { PermissionGroupCapability } from '@/lib/permission-groups/capabilities' +import type { PermissionGroupCapability } from '@/ee/access-control/lib/capabilities' /** * The caller's permission group withholds a capability the request needs. diff --git a/apps/sim/lib/permission-groups/capability-response.ts b/apps/sim/ee/access-control/lib/capability-response.ts similarity index 96% rename from apps/sim/lib/permission-groups/capability-response.ts rename to apps/sim/ee/access-control/lib/capability-response.ts index a1d28471aaa..c44b4993288 100644 --- a/apps/sim/lib/permission-groups/capability-response.ts +++ b/apps/sim/ee/access-control/lib/capability-response.ts @@ -3,7 +3,7 @@ import { CAPABILITY_RULES, capabilityRefusal, type PermissionGroupCapability, -} from '@/lib/permission-groups/capabilities' +} from '@/ee/access-control/lib/capabilities' /** * The 403 a raw route returns when a permission group withholds a capability, diff --git a/apps/sim/lib/permission-groups/config-scope.server.test.ts b/apps/sim/ee/access-control/lib/config-scope.server.test.ts similarity index 90% rename from apps/sim/lib/permission-groups/config-scope.server.test.ts rename to apps/sim/ee/access-control/lib/config-scope.server.test.ts index 7f4f473e885..516cd37f783 100644 --- a/apps/sim/lib/permission-groups/config-scope.server.test.ts +++ b/apps/sim/ee/access-control/lib/config-scope.server.test.ts @@ -10,13 +10,13 @@ const { mockGetUserPermissionConfig, mockResolveVerifiedContext } = vi.hoisted(( vi.mock('react', () => ({ cache: (fn: F) => fn })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, resolveVerifiedUserAccessControlContext: mockResolveVerifiedContext, })) -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import { withPermissionGroupScope } from '@/lib/permission-groups/request-scope.server' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' +import { withPermissionGroupScope } from '@/ee/access-control/lib/request-scope.server' const CONFIG = { hideTablesTab: true } diff --git a/apps/sim/lib/permission-groups/config-scope.server.ts b/apps/sim/ee/access-control/lib/config-scope.server.ts similarity index 90% rename from apps/sim/lib/permission-groups/config-scope.server.ts rename to apps/sim/ee/access-control/lib/config-scope.server.ts index 42d480c46c7..b86b4943509 100644 --- a/apps/sim/lib/permission-groups/config-scope.server.ts +++ b/apps/sim/ee/access-control/lib/config-scope.server.ts @@ -1,11 +1,11 @@ import { cache } from 'react' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' -import type { PermissionGroupScopeKey } from '@/lib/permission-groups/request-scope.server' -import { getPermissionGroupConfigStore } from '@/lib/permission-groups/request-scope.server' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' +import type { PermissionGroupScopeKey } from '@/ee/access-control/lib/request-scope.server' +import { getPermissionGroupConfigStore } from '@/ee/access-control/lib/request-scope.server' import { getUserPermissionConfig, resolveVerifiedUserAccessControlContext, -} from '@/lib/permission-groups/resolve.server' +} from '@/ee/access-control/lib/resolve.server' /** * Memoized for a React server request, so an RSC render that resolves the same diff --git a/apps/sim/lib/permission-groups/constraints.ts b/apps/sim/ee/access-control/lib/constraints.ts similarity index 100% rename from apps/sim/lib/permission-groups/constraints.ts rename to apps/sim/ee/access-control/lib/constraints.ts diff --git a/apps/sim/lib/permission-groups/features.test.ts b/apps/sim/ee/access-control/lib/features.test.ts similarity index 98% rename from apps/sim/lib/permission-groups/features.test.ts rename to apps/sim/ee/access-control/lib/features.test.ts index 45211533c16..b27371bcbe1 100644 --- a/apps/sim/lib/permission-groups/features.test.ts +++ b/apps/sim/ee/access-control/lib/features.test.ts @@ -6,11 +6,11 @@ import { getActivePermissionGroupRestrictions, isFeatureInertForGroup, PLATFORM_FEATURES, -} from '@/lib/permission-groups/features' +} from '@/ee/access-control/lib/features' import { DEFAULT_PERMISSION_GROUP_CONFIG, type PermissionGroupConfig, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' describe('getActivePermissionGroupRestrictions', () => { it('returns no restrictions for an absent or unrestricted config', () => { diff --git a/apps/sim/lib/permission-groups/features.ts b/apps/sim/ee/access-control/lib/features.ts similarity index 99% rename from apps/sim/lib/permission-groups/features.ts rename to apps/sim/ee/access-control/lib/features.ts index 642921fa3ca..d2cb6025670 100644 --- a/apps/sim/lib/permission-groups/features.ts +++ b/apps/sim/ee/access-control/lib/features.ts @@ -3,7 +3,7 @@ import { type PermissionGroupCapabilityScope, type PermissionGroupConfig, type PermissionGroupConfigKey, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' export type BooleanPermissionGroupConfigKey = { [Key in keyof PermissionGroupConfig]: PermissionGroupConfig[Key] extends boolean ? Key : never diff --git a/apps/sim/lib/permission-groups/fields.test.ts b/apps/sim/ee/access-control/lib/fields.test.ts similarity index 99% rename from apps/sim/lib/permission-groups/fields.test.ts rename to apps/sim/ee/access-control/lib/fields.test.ts index 5b9ad4cf981..fe7a274cc56 100644 --- a/apps/sim/lib/permission-groups/fields.test.ts +++ b/apps/sim/ee/access-control/lib/fields.test.ts @@ -3,13 +3,13 @@ */ import { describe, expect, it } from 'vitest' import { permissionGroupFullConfigSchema } from '@/lib/api/contracts/permission-groups' -import { PLATFORM_FEATURES } from '@/lib/permission-groups/features' +import { PLATFORM_FEATURES } from '@/ee/access-control/lib/features' import { DEFAULT_PERMISSION_GROUP_CONFIG, type PermissionGroupConfig, parsePermissionGroupConfig, permissionGroupConfigSchema, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' /** * The coercion corpus, pinned against the hand-written parser before it is diff --git a/apps/sim/lib/permission-groups/fields.ts b/apps/sim/ee/access-control/lib/fields.ts similarity index 100% rename from apps/sim/lib/permission-groups/fields.ts rename to apps/sim/ee/access-control/lib/fields.ts diff --git a/apps/sim/lib/permission-groups/integration-allowlist.test.ts b/apps/sim/ee/access-control/lib/integration-allowlist.test.ts similarity index 99% rename from apps/sim/lib/permission-groups/integration-allowlist.test.ts rename to apps/sim/ee/access-control/lib/integration-allowlist.test.ts index fd183581ac3..7feb04e54a8 100644 --- a/apps/sim/lib/permission-groups/integration-allowlist.test.ts +++ b/apps/sim/ee/access-control/lib/integration-allowlist.test.ts @@ -12,7 +12,7 @@ import { intersectIntegrationAllowlists, resolveAccessControlBlockType, toAccessControlAllowlist, -} from '@/lib/permission-groups/integration-allowlist' +} from '@/ee/access-control/lib/integration-allowlist' describe('resolveAccessControlBlockType', () => { it('judges a superseded block as its successor', () => { diff --git a/apps/sim/lib/permission-groups/integration-allowlist.ts b/apps/sim/ee/access-control/lib/integration-allowlist.ts similarity index 98% rename from apps/sim/lib/permission-groups/integration-allowlist.ts rename to apps/sim/ee/access-control/lib/integration-allowlist.ts index 8f1789c48ef..edd74596034 100644 --- a/apps/sim/lib/permission-groups/integration-allowlist.ts +++ b/apps/sim/ee/access-control/lib/integration-allowlist.ts @@ -1,4 +1,4 @@ -import { BLOCK_ACCESS_SUCCESSORS } from '@/lib/permission-groups/block-successors.generated' +import { BLOCK_ACCESS_SUCCESSORS } from '@/ee/access-control/lib/block-successors.generated' /** * The block type an allowlist decision about `blockType` is really made against. diff --git a/apps/sim/lib/permission-groups/locks.ts b/apps/sim/ee/access-control/lib/locks.ts similarity index 100% rename from apps/sim/lib/permission-groups/locks.ts rename to apps/sim/ee/access-control/lib/locks.ts diff --git a/apps/sim/lib/permission-groups/model-access.test.ts b/apps/sim/ee/access-control/lib/model-access.test.ts similarity index 95% rename from apps/sim/lib/permission-groups/model-access.test.ts rename to apps/sim/ee/access-control/lib/model-access.test.ts index d525c27b8e4..2cf11b44be2 100644 --- a/apps/sim/lib/permission-groups/model-access.test.ts +++ b/apps/sim/ee/access-control/lib/model-access.test.ts @@ -2,7 +2,7 @@ * @vitest-environment node */ import { describe, expect, it } from 'vitest' -import { createModelAccessGate } from '@/lib/permission-groups/model-access' +import { createModelAccessGate } from '@/ee/access-control/lib/model-access' describe('createModelAccessGate', () => { it('allows everything when the group restricts nothing', () => { diff --git a/apps/sim/lib/permission-groups/model-access.ts b/apps/sim/ee/access-control/lib/model-access.ts similarity index 95% rename from apps/sim/lib/permission-groups/model-access.ts rename to apps/sim/ee/access-control/lib/model-access.ts index b78f98fd4e2..4873c2b4d22 100644 --- a/apps/sim/lib/permission-groups/model-access.ts +++ b/apps/sim/ee/access-control/lib/model-access.ts @@ -1,4 +1,4 @@ -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' import { findProviderFromModel } from '@/providers/utils' /** Decides whether the caller's permission group allows a concrete model id. */ diff --git a/apps/sim/lib/permission-groups/operation-access.test.ts b/apps/sim/ee/access-control/lib/operation-access.test.ts similarity index 99% rename from apps/sim/lib/permission-groups/operation-access.test.ts rename to apps/sim/ee/access-control/lib/operation-access.test.ts index c3a032fb3a4..8240c185df6 100644 --- a/apps/sim/lib/permission-groups/operation-access.test.ts +++ b/apps/sim/ee/access-control/lib/operation-access.test.ts @@ -8,7 +8,7 @@ import { isOperationAllowed, type OperationGateBlock, pickDefaultOperation, -} from '@/lib/permission-groups/operation-access' +} from '@/ee/access-control/lib/operation-access' /** A block that resolves its tool from the operation, like most integrations. */ const selectorBlock: OperationGateBlock = { diff --git a/apps/sim/lib/permission-groups/operation-access.ts b/apps/sim/ee/access-control/lib/operation-access.ts similarity index 100% rename from apps/sim/lib/permission-groups/operation-access.ts rename to apps/sim/ee/access-control/lib/operation-access.ts diff --git a/apps/sim/lib/permission-groups/queries.ts b/apps/sim/ee/access-control/lib/queries.ts similarity index 96% rename from apps/sim/lib/permission-groups/queries.ts rename to apps/sim/ee/access-control/lib/queries.ts index f61ef57e394..4b677c2fe5f 100644 --- a/apps/sim/lib/permission-groups/queries.ts +++ b/apps/sim/ee/access-control/lib/queries.ts @@ -9,8 +9,8 @@ import { asc, count, desc, eq, inArray } from 'drizzle-orm' import { type ActivePermissionGroupRestriction, getActivePermissionGroupRestrictions, -} from '@/lib/permission-groups/features' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/features' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' /** A workspace reference (id + display name). */ export interface OrgWorkspaceRef { diff --git a/apps/sim/lib/permission-groups/request-scope.server.ts b/apps/sim/ee/access-control/lib/request-scope.server.ts similarity index 97% rename from apps/sim/lib/permission-groups/request-scope.server.ts rename to apps/sim/ee/access-control/lib/request-scope.server.ts index c972449dd5f..9327c59341a 100644 --- a/apps/sim/lib/permission-groups/request-scope.server.ts +++ b/apps/sim/ee/access-control/lib/request-scope.server.ts @@ -1,4 +1,4 @@ -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' /** * A resolution key, `userId:workspaceId`. `organizationId` is deliberately not diff --git a/apps/sim/lib/permission-groups/resolve.server.test.ts b/apps/sim/ee/access-control/lib/resolve.server.test.ts similarity index 98% rename from apps/sim/lib/permission-groups/resolve.server.test.ts rename to apps/sim/ee/access-control/lib/resolve.server.test.ts index 12e4176cb14..6bfcc0681c9 100644 --- a/apps/sim/lib/permission-groups/resolve.server.test.ts +++ b/apps/sim/ee/access-control/lib/resolve.server.test.ts @@ -21,7 +21,7 @@ import { getUserPermissionConfig, getUserPermissionConfigForOrganization, resolveVerifiedUserAccessControlContext, -} from '@/lib/permission-groups/resolve.server' +} from '@/ee/access-control/lib/resolve.server' const ORGANIZATION_ID = 'org-1' const USER_ID = 'user-1' diff --git a/apps/sim/lib/permission-groups/resolve.server.ts b/apps/sim/ee/access-control/lib/resolve.server.ts similarity index 98% rename from apps/sim/lib/permission-groups/resolve.server.ts rename to apps/sim/ee/access-control/lib/resolve.server.ts index cc2bebb91f9..7013c8edfd6 100644 --- a/apps/sim/lib/permission-groups/resolve.server.ts +++ b/apps/sim/ee/access-control/lib/resolve.server.ts @@ -23,13 +23,13 @@ import { isHosted, } from '@/lib/core/config/env-flags' import type { DbOrTx } from '@/lib/db/types' +import { getWorkspaceWithOwner } from '@/lib/workspaces/permissions/utils' import { DEFAULT_PERMISSION_GROUP_CONFIG, type PermissionGroupConfig, parsePermissionGroupConfig, -} from '@/lib/permission-groups/fields' -import { intersectIntegrationAllowlists } from '@/lib/permission-groups/integration-allowlist' -import { getWorkspaceWithOwner } from '@/lib/workspaces/permissions/utils' +} from '@/ee/access-control/lib/fields' +import { intersectIntegrationAllowlists } from '@/ee/access-control/lib/integration-allowlist' /** * Merges the env allowlist into a permission config. diff --git a/apps/sim/lib/permission-groups/user-scope.server.ts b/apps/sim/ee/access-control/lib/user-scope.server.ts similarity index 91% rename from apps/sim/lib/permission-groups/user-scope.server.ts rename to apps/sim/ee/access-control/lib/user-scope.server.ts index e160ec1076a..249cc5b9d8b 100644 --- a/apps/sim/lib/permission-groups/user-scope.server.ts +++ b/apps/sim/ee/access-control/lib/user-scope.server.ts @@ -1,9 +1,9 @@ import { getUserOrganization } from '@/lib/billing/organizations/membership' -import type { StaticPermissionGroupCapability } from '@/lib/permission-groups/capabilities' +import type { StaticPermissionGroupCapability } from '@/ee/access-control/lib/capabilities' import { isOrganizationCapabilityWithheld, isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' +} from '@/ee/access-control/lib/capability-assertions' /** * Whether the group governing `userId` withholds `capability`, for an action diff --git a/apps/sim/ee/access-control/utils/integration-allowlist-rows.ts b/apps/sim/ee/access-control/utils/integration-allowlist-rows.ts index 38b14ea10cd..c3042ad9c9e 100644 --- a/apps/sim/ee/access-control/utils/integration-allowlist-rows.ts +++ b/apps/sim/ee/access-control/utils/integration-allowlist-rows.ts @@ -1,4 +1,4 @@ -import { toAccessControlAllowlist } from '@/lib/permission-groups/integration-allowlist' +import { toAccessControlAllowlist } from '@/ee/access-control/lib/integration-allowlist' /** * The stored `allowedIntegrations` re-expressed as editor rows: successor- diff --git a/apps/sim/ee/access-control/utils/permission-check.test.ts b/apps/sim/ee/access-control/utils/permission-check.test.ts index 02baa8ee855..4668a575268 100644 --- a/apps/sim/ee/access-control/utils/permission-check.test.ts +++ b/apps/sim/ee/access-control/utils/permission-check.test.ts @@ -36,8 +36,8 @@ vi.mock('@/providers/utils', () => ({ getProviderFromModel: mockGetProviderFromModel, })) -import { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' -import { withPermissionGroupScope } from '@/lib/permission-groups/request-scope.server' +import { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' +import { withPermissionGroupScope } from '@/ee/access-control/lib/request-scope.server' import { assertPermissionsAllowed, CustomToolsNotAllowedError, diff --git a/apps/sim/ee/access-control/utils/permission-check.ts b/apps/sim/ee/access-control/utils/permission-check.ts index 6a3c189c95c..7ad15afcdf6 100644 --- a/apps/sim/ee/access-control/utils/permission-check.ts +++ b/apps/sim/ee/access-control/utils/permission-check.ts @@ -5,29 +5,29 @@ import { isInvitationsDisabled, isPublicApiDisabled, } from '@/lib/core/config/env-flags' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' import { CAPABILITY_RULES, refuseCapability, type StaticCapabilityRule, -} from '@/lib/permission-groups/capabilities' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/capabilities' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' import { resolveAccessControlBlockType, toAccessControlAllowlist, -} from '@/lib/permission-groups/integration-allowlist' -import { createToolAccessGate } from '@/lib/permission-groups/operation-access' +} from '@/ee/access-control/lib/integration-allowlist' +import { createToolAccessGate } from '@/ee/access-control/lib/operation-access' import { getUserPermissionConfig, getUserPermissionConfigForOrganization, mergeEnvAllowlist, -} from '@/lib/permission-groups/resolve.server' +} from '@/ee/access-control/lib/resolve.server' import type { ExecutionContext } from '@/executor/types' import { getProviderFromModel } from '@/providers/utils' /** - * The permission-group resolution layer lives in `@/lib/permission-groups` + * The permission-group resolution layer lives in `@/ee/access-control/lib` * because ~24 domain `operations.ts` modules reach it through the authorization * funnel, and none of them may pull in this module's provider, block-registry * and billing imports. Re-exported here so the surfaces that already read the @@ -40,7 +40,7 @@ export { resolveVerifiedUserAccessControlContext, resolveWorkspaceGroup, type UserAccessControlContext, -} from '@/lib/permission-groups/resolve.server' +} from '@/ee/access-control/lib/resolve.server' const logger = createLogger('PermissionCheck') diff --git a/apps/sim/ee/access-control/utils/permission-gate-subject.test.ts b/apps/sim/ee/access-control/utils/permission-gate-subject.test.ts index 5c1cfdfb3bb..ff100bf9368 100644 --- a/apps/sim/ee/access-control/utils/permission-gate-subject.test.ts +++ b/apps/sim/ee/access-control/utils/permission-gate-subject.test.ts @@ -7,7 +7,7 @@ const mocks = vi.hoisted(() => ({ getUserPermissionConfig: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, getUserPermissionConfigForOrganization: vi.fn(), mergeEnvAllowlist: (config: unknown) => config, diff --git a/apps/sim/lib/audit-logs/application/audit-log-use-cases.test.ts b/apps/sim/ee/audit-logs/lib/application/audit-log-use-cases.test.ts similarity index 96% rename from apps/sim/lib/audit-logs/application/audit-log-use-cases.test.ts rename to apps/sim/ee/audit-logs/lib/application/audit-log-use-cases.test.ts index 5d43358e648..8fca1280b53 100644 --- a/apps/sim/lib/audit-logs/application/audit-log-use-cases.test.ts +++ b/apps/sim/ee/audit-logs/lib/application/audit-log-use-cases.test.ts @@ -16,12 +16,12 @@ const mocks = vi.hoisted(() => ({ recordAudit: vi.fn(), })) -vi.mock('@/lib/audit-logs/authorization', () => ({ +vi.mock('@/ee/audit-logs/lib/authorization', () => ({ resolveEnterpriseAuditAccess: mocks.resolveAccess, resolveDefaultAuditOrganization: mocks.resolveDefaultOrganization, })) -vi.mock('@/lib/audit-logs/query', () => ({ +vi.mock('@/ee/audit-logs/lib/query', () => ({ getOrgWorkspaceIds: mocks.getOrgWorkspaceIds, buildOrgScopeCondition: mocks.buildOrgScopeCondition, buildFilterConditions: mocks.buildFilterConditions, @@ -31,8 +31,8 @@ vi.mock('@/lib/audit-logs/query', () => ({ vi.mock('@sim/audit', () => ({ recordAudit: mocks.recordAudit })) -import { getAuditLog } from '@/lib/audit-logs/application/get-audit-log' -import { listAuditLogs } from '@/lib/audit-logs/application/list-audit-logs' +import { getAuditLog } from '@/ee/audit-logs/lib/application/get-audit-log' +import { listAuditLogs } from '@/ee/audit-logs/lib/application/list-audit-logs' const sessionPrincipal: SessionPrincipal = { kind: 'session', diff --git a/apps/sim/lib/audit-logs/application/authorized-audit-log-use-case.ts b/apps/sim/ee/audit-logs/lib/application/authorized-audit-log-use-case.ts similarity index 95% rename from apps/sim/lib/audit-logs/application/authorized-audit-log-use-case.ts rename to apps/sim/ee/audit-logs/lib/application/authorized-audit-log-use-case.ts index 142190a2612..16c9a28b1f5 100644 --- a/apps/sim/lib/audit-logs/application/authorized-audit-log-use-case.ts +++ b/apps/sim/ee/audit-logs/lib/application/authorized-audit-log-use-case.ts @@ -1,10 +1,13 @@ import type { Principal } from '@sim/auth/principal' -import type { AuditLogOperation, AuditLogPrincipal } from '@/lib/audit-logs/application/operations' +import { ForbiddenOperationError, type OperationUseCase } from '@/lib/core/application' +import type { + AuditLogOperation, + AuditLogPrincipal, +} from '@/ee/audit-logs/lib/application/operations' import { resolveDefaultAuditOrganization, resolveEnterpriseAuditAccess, -} from '@/lib/audit-logs/authorization' -import { ForbiddenOperationError, type OperationUseCase } from '@/lib/core/application' +} from '@/ee/audit-logs/lib/authorization' export interface AuthorizedAuditLogContext { organizationId: string diff --git a/apps/sim/lib/audit-logs/application/get-audit-log.ts b/apps/sim/ee/audit-logs/lib/application/get-audit-log.ts similarity index 81% rename from apps/sim/lib/audit-logs/application/get-audit-log.ts rename to apps/sim/ee/audit-logs/lib/application/get-audit-log.ts index efc3d755d9a..5d44f29a76e 100644 --- a/apps/sim/lib/audit-logs/application/get-audit-log.ts +++ b/apps/sim/ee/audit-logs/lib/application/get-audit-log.ts @@ -1,10 +1,10 @@ import { db } from '@sim/db' import { auditLog } from '@sim/db/schema' import { and, eq } from 'drizzle-orm' -import { defineAuthorizedAuditLogUseCase } from '@/lib/audit-logs/application/authorized-audit-log-use-case' -import { auditLogOperations } from '@/lib/audit-logs/application/operations' -import { buildOrgScopeCondition, getOrgWorkspaceIds } from '@/lib/audit-logs/query' import { OrchestrationError } from '@/lib/core/orchestration/types' +import { defineAuthorizedAuditLogUseCase } from '@/ee/audit-logs/lib/application/authorized-audit-log-use-case' +import { auditLogOperations } from '@/ee/audit-logs/lib/application/operations' +import { buildOrgScopeCondition, getOrgWorkspaceIds } from '@/ee/audit-logs/lib/query' export interface GetAuditLogInput { /** Omitted when the caller belongs to exactly one organization and let it be derived. */ diff --git a/apps/sim/lib/audit-logs/application/list-audit-logs.ts b/apps/sim/ee/audit-logs/lib/application/list-audit-logs.ts similarity index 87% rename from apps/sim/lib/audit-logs/application/list-audit-logs.ts rename to apps/sim/ee/audit-logs/lib/application/list-audit-logs.ts index 0c7e6ebaa8a..51cc8d205b1 100644 --- a/apps/sim/lib/audit-logs/application/list-audit-logs.ts +++ b/apps/sim/ee/audit-logs/lib/application/list-audit-logs.ts @@ -1,5 +1,6 @@ -import { defineAuthorizedAuditLogUseCase } from '@/lib/audit-logs/application/authorized-audit-log-use-case' -import { auditLogOperations } from '@/lib/audit-logs/application/operations' +import { OrchestrationError } from '@/lib/core/orchestration/types' +import { defineAuthorizedAuditLogUseCase } from '@/ee/audit-logs/lib/application/authorized-audit-log-use-case' +import { auditLogOperations } from '@/ee/audit-logs/lib/application/operations' import { type AuditLogFilterParams, buildFilterConditions, @@ -7,8 +8,7 @@ import { decodeAuditLogCursor, getOrgWorkspaceIds, queryAuditLogs, -} from '@/lib/audit-logs/query' -import { OrchestrationError } from '@/lib/core/orchestration/types' +} from '@/ee/audit-logs/lib/query' export interface ListAuditLogsInput { /** Omitted when the caller belongs to exactly one organization and let it be derived. */ diff --git a/apps/sim/lib/audit-logs/application/operations.ts b/apps/sim/ee/audit-logs/lib/application/operations.ts similarity index 100% rename from apps/sim/lib/audit-logs/application/operations.ts rename to apps/sim/ee/audit-logs/lib/application/operations.ts diff --git a/apps/sim/lib/audit-logs/authorization.test.ts b/apps/sim/ee/audit-logs/lib/authorization.test.ts similarity index 94% rename from apps/sim/lib/audit-logs/authorization.test.ts rename to apps/sim/ee/audit-logs/lib/authorization.test.ts index 6467552851a..3781ca43631 100644 --- a/apps/sim/lib/audit-logs/authorization.test.ts +++ b/apps/sim/ee/audit-logs/lib/authorization.test.ts @@ -7,7 +7,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' vi.mock('@/lib/billing/core/access', () => ({ isOrganizationBillingBlocked: vi.fn() })) vi.mock('@/lib/billing/subscriptions/utils', () => ({ USABLE_SUBSCRIPTION_STATUSES: ['active'] })) -import { resolveDefaultAuditOrganization } from '@/lib/audit-logs/authorization' +import { resolveDefaultAuditOrganization } from '@/ee/audit-logs/lib/authorization' describe('resolveDefaultAuditOrganization', () => { beforeEach(() => { diff --git a/apps/sim/lib/audit-logs/authorization.ts b/apps/sim/ee/audit-logs/lib/authorization.ts similarity index 100% rename from apps/sim/lib/audit-logs/authorization.ts rename to apps/sim/ee/audit-logs/lib/authorization.ts diff --git a/apps/sim/lib/audit-logs/query.test.ts b/apps/sim/ee/audit-logs/lib/query.test.ts similarity index 99% rename from apps/sim/lib/audit-logs/query.test.ts rename to apps/sim/ee/audit-logs/lib/query.test.ts index 2af9e34b949..7d10decfb9b 100644 --- a/apps/sim/lib/audit-logs/query.test.ts +++ b/apps/sim/ee/audit-logs/lib/query.test.ts @@ -13,7 +13,7 @@ import { buildOrgScopeCondition, decodeAuditLogCursor, getOrgWorkspaceIds, -} from '@/lib/audit-logs/query' +} from '@/ee/audit-logs/lib/query' const ORG_ID = 'org-1' const MEMBER_IDS = ['user-1', 'user-2'] diff --git a/apps/sim/lib/audit-logs/query.ts b/apps/sim/ee/audit-logs/lib/query.ts similarity index 100% rename from apps/sim/lib/audit-logs/query.ts rename to apps/sim/ee/audit-logs/lib/query.ts diff --git a/apps/sim/lib/workflows/custom-blocks/child-execution.test.ts b/apps/sim/ee/custom-blocks/lib/child-execution.test.ts similarity index 99% rename from apps/sim/lib/workflows/custom-blocks/child-execution.test.ts rename to apps/sim/ee/custom-blocks/lib/child-execution.test.ts index 613a9452170..0844188964f 100644 --- a/apps/sim/lib/workflows/custom-blocks/child-execution.test.ts +++ b/apps/sim/ee/custom-blocks/lib/child-execution.test.ts @@ -25,7 +25,7 @@ import { createChildCancellationSignal, trackChildRun, waitForChildRuns, -} from '@/lib/workflows/custom-blocks/child-execution' +} from '@/ee/custom-blocks/lib/child-execution' import { isBoundarySafeError } from '@/executor/errors/boundary' const attribution = { actorUserId: 'owner-1', workspaceId: 'workspace-source' } as any diff --git a/apps/sim/lib/workflows/custom-blocks/child-execution.ts b/apps/sim/ee/custom-blocks/lib/child-execution.ts similarity index 100% rename from apps/sim/lib/workflows/custom-blocks/child-execution.ts rename to apps/sim/ee/custom-blocks/lib/child-execution.ts diff --git a/apps/sim/lib/workflows/custom-blocks/operations.test.ts b/apps/sim/ee/custom-blocks/lib/operations.test.ts similarity index 98% rename from apps/sim/lib/workflows/custom-blocks/operations.test.ts rename to apps/sim/ee/custom-blocks/lib/operations.test.ts index 1df4482fb55..6d61e81ffef 100644 --- a/apps/sim/lib/workflows/custom-blocks/operations.test.ts +++ b/apps/sim/ee/custom-blocks/lib/operations.test.ts @@ -33,7 +33,7 @@ import { listCustomBlocksWithInputs, publishCustomBlock, updateCustomBlock, -} from '@/lib/workflows/custom-blocks/operations' +} from '@/ee/custom-blocks/lib/operations' const publishParams = { organizationId: 'org-1', diff --git a/apps/sim/lib/workflows/custom-blocks/operations.ts b/apps/sim/ee/custom-blocks/lib/operations.ts similarity index 100% rename from apps/sim/lib/workflows/custom-blocks/operations.ts rename to apps/sim/ee/custom-blocks/lib/operations.ts diff --git a/apps/sim/ee/data-drains/components/data-drain-create.test.tsx b/apps/sim/ee/data-drains/components/data-drain-create.test.tsx index d235c93bd21..5bffa78d0d4 100644 --- a/apps/sim/ee/data-drains/components/data-drain-create.test.tsx +++ b/apps/sim/ee/data-drains/components/data-drain-create.test.tsx @@ -4,7 +4,7 @@ import { act, type ReactNode } from 'react' import { createRoot, type Root } from 'react-dom/client' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { DESTINATION_TYPES } from '@/lib/data-drains/types' +import { DESTINATION_TYPES } from '@/ee/data-drains/lib/types' const { mockToastError, mockToastSuccess, mockUseCreateDataDrain, mockGuardBack } = vi.hoisted( () => ({ diff --git a/apps/sim/ee/data-drains/components/data-drain-create.tsx b/apps/sim/ee/data-drains/components/data-drain-create.tsx index 9db2befb798..64cc82ecbad 100644 --- a/apps/sim/ee/data-drains/components/data-drain-create.tsx +++ b/apps/sim/ee/data-drains/components/data-drain-create.tsx @@ -6,8 +6,6 @@ import { ArrowLeft, Database } from '@sim/emcn/icons' import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' import type { CreateDataDrainBody } from '@/lib/api/contracts/data-drains' -import type { CADENCE_TYPES, SOURCE_TYPES } from '@/lib/data-drains/types' -import { DESTINATION_TYPES } from '@/lib/data-drains/types' import { ResourceTile } from '@/app/workspace/[workspaceId]/components' import { CredentialDetailHeading, @@ -26,6 +24,8 @@ import { DESTINATION_OPTIONS, SOURCE_OPTIONS, } from '@/ee/data-drains/labels' +import type { CADENCE_TYPES, SOURCE_TYPES } from '@/ee/data-drains/lib/types' +import { DESTINATION_TYPES } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainCreate') diff --git a/apps/sim/ee/data-drains/destinations/registry.tsx b/apps/sim/ee/data-drains/destinations/registry.tsx index fb1371a1552..f7e50ecbda1 100644 --- a/apps/sim/ee/data-drains/destinations/registry.tsx +++ b/apps/sim/ee/data-drains/destinations/registry.tsx @@ -3,8 +3,8 @@ import type { ComponentType } from 'react' import { ChipInput, ChipSelect, ChipTextarea, SecretInput, Switch } from '@sim/emcn' import type { CreateDataDrainBody } from '@/lib/api/contracts/data-drains' -import type { DestinationType } from '@/lib/data-drains/types' import { SettingRow } from '@/ee/components/setting-row' +import type { DestinationType } from '@/ee/data-drains/lib/types' type DestinationBranch = Pick< CreateDataDrainBody, diff --git a/apps/sim/ee/data-drains/labels.ts b/apps/sim/ee/data-drains/labels.ts index 0ab0c7d4c87..f854f00cf3f 100644 --- a/apps/sim/ee/data-drains/labels.ts +++ b/apps/sim/ee/data-drains/labels.ts @@ -1,4 +1,4 @@ -import { CADENCE_TYPES, DESTINATION_TYPES, SOURCE_TYPES } from '@/lib/data-drains/types' +import { CADENCE_TYPES, DESTINATION_TYPES, SOURCE_TYPES } from '@/ee/data-drains/lib/types' export const SOURCE_LABELS: Record<(typeof SOURCE_TYPES)[number], string> = { workflow_logs: 'Workflow logs', diff --git a/apps/sim/lib/data-drains/access.ts b/apps/sim/ee/data-drains/lib/access.ts similarity index 100% rename from apps/sim/lib/data-drains/access.ts rename to apps/sim/ee/data-drains/lib/access.ts diff --git a/apps/sim/lib/data-drains/destinations/azure_blob.test.ts b/apps/sim/ee/data-drains/lib/destinations/azure_blob.test.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/azure_blob.test.ts rename to apps/sim/ee/data-drains/lib/destinations/azure_blob.test.ts index 5ad6c99ba20..d080fa07be3 100644 --- a/apps/sim/lib/data-drains/destinations/azure_blob.test.ts +++ b/apps/sim/ee/data-drains/lib/destinations/azure_blob.test.ts @@ -26,7 +26,7 @@ vi.mock('@azure/storage-blob', () => ({ StorageSharedKeyCredential: StorageSharedKeyCredentialCtor, })) -import { azureBlobDestination } from '@/lib/data-drains/destinations/azure_blob' +import { azureBlobDestination } from '@/ee/data-drains/lib/destinations/azure_blob' const config = { accountName: 'simstore', containerName: 'drains', prefix: 'sim/' } // Realistic 88-char base64 (64-byte) Azure storage key shape. diff --git a/apps/sim/lib/data-drains/destinations/azure_blob.ts b/apps/sim/ee/data-drains/lib/destinations/azure_blob.ts similarity index 97% rename from apps/sim/lib/data-drains/destinations/azure_blob.ts rename to apps/sim/ee/data-drains/lib/destinations/azure_blob.ts index d038a84aca4..9919bd50f15 100644 --- a/apps/sim/lib/data-drains/destinations/azure_blob.ts +++ b/apps/sim/ee/data-drains/lib/destinations/azure_blob.ts @@ -1,8 +1,8 @@ import { createLogger } from '@sim/logger' import { generateShortId } from '@sim/utils/id' import { z } from 'zod' -import { buildObjectKey, normalizePrefix } from '@/lib/data-drains/destinations/utils' -import type { DrainDestination } from '@/lib/data-drains/types' +import { buildObjectKey, normalizePrefix } from '@/ee/data-drains/lib/destinations/utils' +import type { DrainDestination } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainAzureBlobDestination') diff --git a/apps/sim/lib/data-drains/destinations/bigquery.test.ts b/apps/sim/ee/data-drains/lib/destinations/bigquery.test.ts similarity index 99% rename from apps/sim/lib/data-drains/destinations/bigquery.test.ts rename to apps/sim/ee/data-drains/lib/destinations/bigquery.test.ts index 31f4d98092a..0ad6cc70b35 100644 --- a/apps/sim/lib/data-drains/destinations/bigquery.test.ts +++ b/apps/sim/ee/data-drains/lib/destinations/bigquery.test.ts @@ -46,7 +46,7 @@ const fetchMock = vi.fn( ) vi.stubGlobal('fetch', fetchMock) -import { bigqueryDestination } from '@/lib/data-drains/destinations/bigquery' +import { bigqueryDestination } from '@/ee/data-drains/lib/destinations/bigquery' const config = { projectId: 'my-proj', datasetId: 'logs', tableId: 'workflow' } const credentials = { diff --git a/apps/sim/lib/data-drains/destinations/bigquery.ts b/apps/sim/ee/data-drains/lib/destinations/bigquery.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/bigquery.ts rename to apps/sim/ee/data-drains/lib/destinations/bigquery.ts index c01779c163a..0ffd99a0929 100644 --- a/apps/sim/lib/data-drains/destinations/bigquery.ts +++ b/apps/sim/ee/data-drains/lib/destinations/bigquery.ts @@ -10,8 +10,8 @@ import { parseServiceAccount, refineServiceAccountJson, sleepUntilAborted, -} from '@/lib/data-drains/destinations/utils' -import type { DeliveryMetadata, DrainDestination } from '@/lib/data-drains/types' +} from '@/ee/data-drains/lib/destinations/utils' +import type { DeliveryMetadata, DrainDestination } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainBigQueryDestination') diff --git a/apps/sim/lib/data-drains/destinations/datadog.test.ts b/apps/sim/ee/data-drains/lib/destinations/datadog.test.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/datadog.test.ts rename to apps/sim/ee/data-drains/lib/destinations/datadog.test.ts index bb19761dd56..22d318cc068 100644 --- a/apps/sim/lib/data-drains/destinations/datadog.test.ts +++ b/apps/sim/ee/data-drains/lib/destinations/datadog.test.ts @@ -7,7 +7,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' const fetchMock = vi.fn(async () => new Response(null, { status: 202 })) vi.stubGlobal('fetch', fetchMock) -import { datadogDestination } from '@/lib/data-drains/destinations/datadog' +import { datadogDestination } from '@/ee/data-drains/lib/destinations/datadog' const config = { site: 'us1' as const, service: 'sim', tags: 'env:prod' } const credentials = { apiKey: 'dd-key' } diff --git a/apps/sim/lib/data-drains/destinations/datadog.ts b/apps/sim/ee/data-drains/lib/destinations/datadog.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/datadog.ts rename to apps/sim/ee/data-drains/lib/destinations/datadog.ts index 6a56c00ad95..8635bda176a 100644 --- a/apps/sim/lib/data-drains/destinations/datadog.ts +++ b/apps/sim/ee/data-drains/lib/destinations/datadog.ts @@ -3,8 +3,8 @@ import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' import { backoffWithJitter, parseRetryAfter } from '@sim/utils/retry' import { z } from 'zod' -import { parseNdjsonObjects, sleepUntilAborted } from '@/lib/data-drains/destinations/utils' -import type { DeliveryMetadata, DrainDestination } from '@/lib/data-drains/types' +import { parseNdjsonObjects, sleepUntilAborted } from '@/ee/data-drains/lib/destinations/utils' +import type { DeliveryMetadata, DrainDestination } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainDatadogDestination') diff --git a/apps/sim/lib/data-drains/destinations/gcs.test.ts b/apps/sim/ee/data-drains/lib/destinations/gcs.test.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/gcs.test.ts rename to apps/sim/ee/data-drains/lib/destinations/gcs.test.ts index 81d35034fe0..1061d0dda0a 100644 --- a/apps/sim/lib/data-drains/destinations/gcs.test.ts +++ b/apps/sim/ee/data-drains/lib/destinations/gcs.test.ts @@ -20,7 +20,7 @@ vi.mock('google-auth-library', () => ({ JWT: JWTCtor })) const fetchMock = vi.fn(async () => new Response(null, { status: 200 })) vi.stubGlobal('fetch', fetchMock) -import { gcsDestination } from '@/lib/data-drains/destinations/gcs' +import { gcsDestination } from '@/ee/data-drains/lib/destinations/gcs' const config = { bucket: 'my-bucket', prefix: 'sim/' } const credentials = { diff --git a/apps/sim/lib/data-drains/destinations/gcs.ts b/apps/sim/ee/data-drains/lib/destinations/gcs.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/gcs.ts rename to apps/sim/ee/data-drains/lib/destinations/gcs.ts index 40e288e7117..90d67a5a1a1 100644 --- a/apps/sim/lib/data-drains/destinations/gcs.ts +++ b/apps/sim/ee/data-drains/lib/destinations/gcs.ts @@ -11,8 +11,8 @@ import { parseServiceAccount, refineServiceAccountJson, sleepUntilAborted, -} from '@/lib/data-drains/destinations/utils' -import type { DrainDestination } from '@/lib/data-drains/types' +} from '@/ee/data-drains/lib/destinations/utils' +import type { DrainDestination } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainGCSDestination') diff --git a/apps/sim/ee/data-drains/lib/destinations/registry.ts b/apps/sim/ee/data-drains/lib/destinations/registry.ts new file mode 100644 index 00000000000..5344bfeacce --- /dev/null +++ b/apps/sim/ee/data-drains/lib/destinations/registry.ts @@ -0,0 +1,22 @@ +import { azureBlobDestination } from '@/ee/data-drains/lib/destinations/azure_blob' +import { bigqueryDestination } from '@/ee/data-drains/lib/destinations/bigquery' +import { datadogDestination } from '@/ee/data-drains/lib/destinations/datadog' +import { gcsDestination } from '@/ee/data-drains/lib/destinations/gcs' +import { s3Destination } from '@/ee/data-drains/lib/destinations/s3' +import { snowflakeDestination } from '@/ee/data-drains/lib/destinations/snowflake' +import { webhookDestination } from '@/ee/data-drains/lib/destinations/webhook' +import type { DestinationType, DrainDestination } from '@/ee/data-drains/lib/types' + +export const DESTINATION_REGISTRY = { + s3: s3Destination, + gcs: gcsDestination, + azure_blob: azureBlobDestination, + datadog: datadogDestination, + bigquery: bigqueryDestination, + snowflake: snowflakeDestination, + webhook: webhookDestination, +} as const satisfies Record + +export function getDestination(type: DestinationType): DrainDestination { + return DESTINATION_REGISTRY[type] +} diff --git a/apps/sim/lib/data-drains/destinations/s3.test.ts b/apps/sim/ee/data-drains/lib/destinations/s3.test.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/s3.test.ts rename to apps/sim/ee/data-drains/lib/destinations/s3.test.ts index 441a83cdd0e..0e2a0f9aebd 100644 --- a/apps/sim/lib/data-drains/destinations/s3.test.ts +++ b/apps/sim/ee/data-drains/lib/destinations/s3.test.ts @@ -43,7 +43,7 @@ vi.mock('@aws-sdk/client-s3', () => ({ DeleteObjectCommand: DeleteObjectCommandCtor, })) -import { s3Destination } from '@/lib/data-drains/destinations/s3' +import { s3Destination } from '@/ee/data-drains/lib/destinations/s3' const config = { bucket: 'my-bucket', diff --git a/apps/sim/lib/data-drains/destinations/s3.ts b/apps/sim/ee/data-drains/lib/destinations/s3.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/s3.ts rename to apps/sim/ee/data-drains/lib/destinations/s3.ts index 7d464626547..a44e184bb4e 100644 --- a/apps/sim/lib/data-drains/destinations/s3.ts +++ b/apps/sim/ee/data-drains/lib/destinations/s3.ts @@ -9,8 +9,8 @@ import { generateShortId } from '@sim/utils/id' import { z } from 'zod' import { validateExternalUrl } from '@/lib/core/security/input-validation' import { validateUrlWithDNS } from '@/lib/core/security/input-validation.server' -import { buildObjectKey, normalizePrefix } from '@/lib/data-drains/destinations/utils' -import type { DrainDestination } from '@/lib/data-drains/types' +import { buildObjectKey, normalizePrefix } from '@/ee/data-drains/lib/destinations/utils' +import type { DrainDestination } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainS3Destination') diff --git a/apps/sim/lib/data-drains/destinations/snowflake.test.ts b/apps/sim/ee/data-drains/lib/destinations/snowflake.test.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/snowflake.test.ts rename to apps/sim/ee/data-drains/lib/destinations/snowflake.test.ts index f4ea574c72a..95ae4ea807c 100644 --- a/apps/sim/lib/data-drains/destinations/snowflake.test.ts +++ b/apps/sim/ee/data-drains/lib/destinations/snowflake.test.ts @@ -8,7 +8,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' const fetchMock = vi.fn(async () => new Response(JSON.stringify({}), { status: 200 })) vi.stubGlobal('fetch', fetchMock) -import { snowflakeDestination } from '@/lib/data-drains/destinations/snowflake' +import { snowflakeDestination } from '@/ee/data-drains/lib/destinations/snowflake' const { privateKey } = generateKeyPairSync('rsa', { modulusLength: 2048, diff --git a/apps/sim/lib/data-drains/destinations/snowflake.ts b/apps/sim/ee/data-drains/lib/destinations/snowflake.ts similarity index 99% rename from apps/sim/lib/data-drains/destinations/snowflake.ts rename to apps/sim/ee/data-drains/lib/destinations/snowflake.ts index 23a8a5665dc..3b3416f8b98 100644 --- a/apps/sim/lib/data-drains/destinations/snowflake.ts +++ b/apps/sim/ee/data-drains/lib/destinations/snowflake.ts @@ -5,8 +5,8 @@ import { generateId } from '@sim/utils/id' import { backoffWithJitter, parseRetryAfter } from '@sim/utils/retry' import { importPKCS8, SignJWT } from 'jose' import { z } from 'zod' -import { sleepUntilAborted } from '@/lib/data-drains/destinations/utils' -import type { DrainDestination } from '@/lib/data-drains/types' +import { sleepUntilAborted } from '@/ee/data-drains/lib/destinations/utils' +import type { DrainDestination } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainSnowflakeDestination') diff --git a/apps/sim/lib/data-drains/destinations/utils.ts b/apps/sim/ee/data-drains/lib/destinations/utils.ts similarity index 100% rename from apps/sim/lib/data-drains/destinations/utils.ts rename to apps/sim/ee/data-drains/lib/destinations/utils.ts diff --git a/apps/sim/lib/data-drains/destinations/webhook.test.ts b/apps/sim/ee/data-drains/lib/destinations/webhook.test.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/webhook.test.ts rename to apps/sim/ee/data-drains/lib/destinations/webhook.test.ts index 38a6f37029d..a2cdd26e25c 100644 --- a/apps/sim/lib/data-drains/destinations/webhook.test.ts +++ b/apps/sim/ee/data-drains/lib/destinations/webhook.test.ts @@ -7,7 +7,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' vi.mock('@/lib/core/security/input-validation.server', () => inputValidationMock) -import { webhookDestination } from '@/lib/data-drains/destinations/webhook' +import { webhookDestination } from '@/ee/data-drains/lib/destinations/webhook' const config = { url: 'https://example.com/hook' } const credentials = { signingSecret: 'super-secret-key' } diff --git a/apps/sim/lib/data-drains/destinations/webhook.ts b/apps/sim/ee/data-drains/lib/destinations/webhook.ts similarity index 98% rename from apps/sim/lib/data-drains/destinations/webhook.ts rename to apps/sim/ee/data-drains/lib/destinations/webhook.ts index 54c480f6dd0..6060d9cf8b0 100644 --- a/apps/sim/lib/data-drains/destinations/webhook.ts +++ b/apps/sim/ee/data-drains/lib/destinations/webhook.ts @@ -8,8 +8,8 @@ import { secureFetchWithPinnedIP, validateUrlWithDNS, } from '@/lib/core/security/input-validation.server' -import { sleepUntilAborted } from '@/lib/data-drains/destinations/utils' -import type { DeliveryMetadata, DrainDestination } from '@/lib/data-drains/types' +import { sleepUntilAborted } from '@/ee/data-drains/lib/destinations/utils' +import type { DeliveryMetadata, DrainDestination } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainWebhookDestination') diff --git a/apps/sim/lib/data-drains/dispatcher.test.ts b/apps/sim/ee/data-drains/lib/dispatcher.test.ts similarity index 97% rename from apps/sim/lib/data-drains/dispatcher.test.ts rename to apps/sim/ee/data-drains/lib/dispatcher.test.ts index cb51659b0a5..9e3de98243c 100644 --- a/apps/sim/lib/data-drains/dispatcher.test.ts +++ b/apps/sim/ee/data-drains/lib/dispatcher.test.ts @@ -18,7 +18,7 @@ vi.mock('@/lib/billing/core/subscription', () => ({ })) vi.mock('@/lib/core/async-jobs', () => ({ getJobQueue: mockGetJobQueue })) -import { dispatchDueDrains, reapOrphanedRuns } from '@/lib/data-drains/dispatcher' +import { dispatchDueDrains, reapOrphanedRuns } from '@/ee/data-drains/lib/dispatcher' function mockCandidates(rows: Array<{ id: string; organizationId: string }>) { // db.select().from().where() — override `from` so awaiting `.where(pred)` diff --git a/apps/sim/lib/data-drains/dispatcher.ts b/apps/sim/ee/data-drains/lib/dispatcher.ts similarity index 100% rename from apps/sim/lib/data-drains/dispatcher.ts rename to apps/sim/ee/data-drains/lib/dispatcher.ts diff --git a/apps/sim/lib/data-drains/encryption.ts b/apps/sim/ee/data-drains/lib/encryption.ts similarity index 100% rename from apps/sim/lib/data-drains/encryption.ts rename to apps/sim/ee/data-drains/lib/encryption.ts diff --git a/apps/sim/lib/data-drains/serializers.ts b/apps/sim/ee/data-drains/lib/serializers.ts similarity index 96% rename from apps/sim/lib/data-drains/serializers.ts rename to apps/sim/ee/data-drains/lib/serializers.ts index cbc9843a3f8..9724bec974f 100644 --- a/apps/sim/lib/data-drains/serializers.ts +++ b/apps/sim/ee/data-drains/lib/serializers.ts @@ -1,6 +1,6 @@ import type { dataDrainRuns, dataDrains } from '@sim/db/schema' import { type DataDrain, type DataDrainRun, dataDrainSchema } from '@/lib/api/contracts/data-drains' -import { getDestination } from '@/lib/data-drains/destinations/registry' +import { getDestination } from '@/ee/data-drains/lib/destinations/registry' type DataDrainRow = typeof dataDrains.$inferSelect type DataDrainRunRow = typeof dataDrainRuns.$inferSelect diff --git a/apps/sim/lib/data-drains/service.test.ts b/apps/sim/ee/data-drains/lib/service.test.ts similarity index 93% rename from apps/sim/lib/data-drains/service.test.ts rename to apps/sim/ee/data-drains/lib/service.test.ts index 328ea105462..7c841a8e6c2 100644 --- a/apps/sim/lib/data-drains/service.test.ts +++ b/apps/sim/ee/data-drains/lib/service.test.ts @@ -10,11 +10,13 @@ const { mockGetSource, mockGetDestination, mockDecryptCredentials } = vi.hoisted mockDecryptCredentials: vi.fn(), })) -vi.mock('@/lib/data-drains/sources/registry', () => ({ getSource: mockGetSource })) -vi.mock('@/lib/data-drains/destinations/registry', () => ({ getDestination: mockGetDestination })) -vi.mock('@/lib/data-drains/encryption', () => ({ decryptCredentials: mockDecryptCredentials })) +vi.mock('@/ee/data-drains/lib/sources/registry', () => ({ getSource: mockGetSource })) +vi.mock('@/ee/data-drains/lib/destinations/registry', () => ({ + getDestination: mockGetDestination, +})) +vi.mock('@/ee/data-drains/lib/encryption', () => ({ decryptCredentials: mockDecryptCredentials })) -import { runDrain } from '@/lib/data-drains/service' +import { runDrain } from '@/ee/data-drains/lib/service' type Row = { id: string; ts: string } diff --git a/apps/sim/lib/data-drains/service.ts b/apps/sim/ee/data-drains/lib/service.ts similarity index 95% rename from apps/sim/lib/data-drains/service.ts rename to apps/sim/ee/data-drains/lib/service.ts index 418d475137b..ae53b8ec990 100644 --- a/apps/sim/lib/data-drains/service.ts +++ b/apps/sim/ee/data-drains/lib/service.ts @@ -4,10 +4,10 @@ import { createLogger } from '@sim/logger' import { toError } from '@sim/utils/errors' import { generateId } from '@sim/utils/id' import { eq } from 'drizzle-orm' -import { getDestination } from '@/lib/data-drains/destinations/registry' -import { decryptCredentials } from '@/lib/data-drains/encryption' -import { getSource } from '@/lib/data-drains/sources/registry' -import type { Cursor, RunTrigger } from '@/lib/data-drains/types' +import { getDestination } from '@/ee/data-drains/lib/destinations/registry' +import { decryptCredentials } from '@/ee/data-drains/lib/encryption' +import { getSource } from '@/ee/data-drains/lib/sources/registry' +import type { Cursor, RunTrigger } from '@/ee/data-drains/lib/types' const logger = createLogger('DataDrainsService') diff --git a/apps/sim/lib/data-drains/sources/audit-logs.ts b/apps/sim/ee/data-drains/lib/sources/audit-logs.ts similarity index 91% rename from apps/sim/lib/data-drains/sources/audit-logs.ts rename to apps/sim/ee/data-drains/lib/sources/audit-logs.ts index b94ce50ae8b..4552d166bfc 100644 --- a/apps/sim/lib/data-drains/sources/audit-logs.ts +++ b/apps/sim/ee/data-drains/lib/sources/audit-logs.ts @@ -7,9 +7,9 @@ import { timeCursorOrderBy, timeCursorPredicate, timeCursorStabilityBound, -} from '@/lib/data-drains/sources/cursor' -import { getOrganizationWorkspaceIds } from '@/lib/data-drains/sources/helpers' -import type { Cursor, DrainSource, SourcePageInput } from '@/lib/data-drains/types' +} from '@/ee/data-drains/lib/sources/cursor' +import { getOrganizationWorkspaceIds } from '@/ee/data-drains/lib/sources/helpers' +import type { Cursor, DrainSource, SourcePageInput } from '@/ee/data-drains/lib/types' type AuditLogRow = typeof auditLog.$inferSelect diff --git a/apps/sim/lib/data-drains/sources/copilot-chats.ts b/apps/sim/ee/data-drains/lib/sources/copilot-chats.ts similarity index 95% rename from apps/sim/lib/data-drains/sources/copilot-chats.ts rename to apps/sim/ee/data-drains/lib/sources/copilot-chats.ts index 773b5f2257d..406834c0944 100644 --- a/apps/sim/lib/data-drains/sources/copilot-chats.ts +++ b/apps/sim/ee/data-drains/lib/sources/copilot-chats.ts @@ -7,9 +7,9 @@ import { timeCursorOrderBy, timeCursorPredicate, timeCursorStabilityBound, -} from '@/lib/data-drains/sources/cursor' -import { getOrganizationWorkspaceIds } from '@/lib/data-drains/sources/helpers' -import type { Cursor, DrainSource, SourcePageInput } from '@/lib/data-drains/types' +} from '@/ee/data-drains/lib/sources/cursor' +import { getOrganizationWorkspaceIds } from '@/ee/data-drains/lib/sources/helpers' +import type { Cursor, DrainSource, SourcePageInput } from '@/ee/data-drains/lib/types' /** * The transcript no longer lives on `copilot_chats.messages` — it is assembled diff --git a/apps/sim/lib/data-drains/sources/copilot-runs.ts b/apps/sim/ee/data-drains/lib/sources/copilot-runs.ts similarity index 91% rename from apps/sim/lib/data-drains/sources/copilot-runs.ts rename to apps/sim/ee/data-drains/lib/sources/copilot-runs.ts index b6270c09456..845964ebb54 100644 --- a/apps/sim/lib/data-drains/sources/copilot-runs.ts +++ b/apps/sim/ee/data-drains/lib/sources/copilot-runs.ts @@ -7,9 +7,9 @@ import { timeCursorOrderBy, timeCursorPredicate, timeCursorStabilityBound, -} from '@/lib/data-drains/sources/cursor' -import { getOrganizationWorkspaceIds } from '@/lib/data-drains/sources/helpers' -import type { Cursor, DrainSource, SourcePageInput } from '@/lib/data-drains/types' +} from '@/ee/data-drains/lib/sources/cursor' +import { getOrganizationWorkspaceIds } from '@/ee/data-drains/lib/sources/helpers' +import type { Cursor, DrainSource, SourcePageInput } from '@/ee/data-drains/lib/types' type CopilotRunRow = typeof copilotRuns.$inferSelect diff --git a/apps/sim/lib/data-drains/sources/cursor.test.ts b/apps/sim/ee/data-drains/lib/sources/cursor.test.ts similarity index 97% rename from apps/sim/lib/data-drains/sources/cursor.test.ts rename to apps/sim/ee/data-drains/lib/sources/cursor.test.ts index 341739981f2..1869e109ebd 100644 --- a/apps/sim/lib/data-drains/sources/cursor.test.ts +++ b/apps/sim/ee/data-drains/lib/sources/cursor.test.ts @@ -7,7 +7,7 @@ import { decodeTimeCursor, encodeTimeCursor, timeCursorPredicate, -} from '@/lib/data-drains/sources/cursor' +} from '@/ee/data-drains/lib/sources/cursor' describe('time cursor encoding', () => { it('round-trips a valid cursor', () => { diff --git a/apps/sim/lib/data-drains/sources/cursor.ts b/apps/sim/ee/data-drains/lib/sources/cursor.ts similarity index 97% rename from apps/sim/lib/data-drains/sources/cursor.ts rename to apps/sim/ee/data-drains/lib/sources/cursor.ts index 9d8dd709a74..7531f4f3343 100644 --- a/apps/sim/lib/data-drains/sources/cursor.ts +++ b/apps/sim/ee/data-drains/lib/sources/cursor.ts @@ -1,6 +1,6 @@ import { type SQL, sql } from 'drizzle-orm' import type { PgColumn } from 'drizzle-orm/pg-core' -import type { Cursor } from '@/lib/data-drains/types' +import type { Cursor } from '@/ee/data-drains/lib/types' /** * Composite cursor for time-ordered tables. Pairs a timestamp with the row's id diff --git a/apps/sim/lib/data-drains/sources/helpers.ts b/apps/sim/ee/data-drains/lib/sources/helpers.ts similarity index 100% rename from apps/sim/lib/data-drains/sources/helpers.ts rename to apps/sim/ee/data-drains/lib/sources/helpers.ts diff --git a/apps/sim/lib/data-drains/sources/job-logs.ts b/apps/sim/ee/data-drains/lib/sources/job-logs.ts similarity index 93% rename from apps/sim/lib/data-drains/sources/job-logs.ts rename to apps/sim/ee/data-drains/lib/sources/job-logs.ts index d842fefbfa8..79a39a12034 100644 --- a/apps/sim/lib/data-drains/sources/job-logs.ts +++ b/apps/sim/ee/data-drains/lib/sources/job-logs.ts @@ -2,16 +2,16 @@ import { dbReplica } from '@sim/db' import { jobExecutionLogs } from '@sim/db/schema' import { and, inArray, isNotNull } from 'drizzle-orm' import { MATERIALIZE_CONCURRENCY, mapWithConcurrency } from '@/lib/core/utils/concurrency' +import { materializeExecutionDataForDisplay } from '@/lib/logs/execution/trace-store' import { decodeTimeCursor, encodeTimeCursor, timeCursorOrderBy, timeCursorPredicate, timeCursorStabilityBound, -} from '@/lib/data-drains/sources/cursor' -import { getOrganizationWorkspaceIds } from '@/lib/data-drains/sources/helpers' -import type { Cursor, DrainSource, SourcePageInput } from '@/lib/data-drains/types' -import { materializeExecutionDataForDisplay } from '@/lib/logs/execution/trace-store' +} from '@/ee/data-drains/lib/sources/cursor' +import { getOrganizationWorkspaceIds } from '@/ee/data-drains/lib/sources/helpers' +import type { Cursor, DrainSource, SourcePageInput } from '@/ee/data-drains/lib/types' type JobLogRow = typeof jobExecutionLogs.$inferSelect diff --git a/apps/sim/ee/data-drains/lib/sources/registry.ts b/apps/sim/ee/data-drains/lib/sources/registry.ts new file mode 100644 index 00000000000..c7cf1155ceb --- /dev/null +++ b/apps/sim/ee/data-drains/lib/sources/registry.ts @@ -0,0 +1,18 @@ +import { auditLogsSource } from '@/ee/data-drains/lib/sources/audit-logs' +import { copilotChatsSource } from '@/ee/data-drains/lib/sources/copilot-chats' +import { copilotRunsSource } from '@/ee/data-drains/lib/sources/copilot-runs' +import { jobLogsSource } from '@/ee/data-drains/lib/sources/job-logs' +import { workflowLogsSource } from '@/ee/data-drains/lib/sources/workflow-logs' +import type { DrainSource, SourceType } from '@/ee/data-drains/lib/types' + +export const SOURCE_REGISTRY = { + workflow_logs: workflowLogsSource, + job_logs: jobLogsSource, + audit_logs: auditLogsSource, + copilot_chats: copilotChatsSource, + copilot_runs: copilotRunsSource, +} as const satisfies Record + +export function getSource(type: SourceType): DrainSource { + return SOURCE_REGISTRY[type] +} diff --git a/apps/sim/lib/data-drains/sources/workflow-logs.ts b/apps/sim/ee/data-drains/lib/sources/workflow-logs.ts similarity index 94% rename from apps/sim/lib/data-drains/sources/workflow-logs.ts rename to apps/sim/ee/data-drains/lib/sources/workflow-logs.ts index 5d198a435c7..d78395fc630 100644 --- a/apps/sim/lib/data-drains/sources/workflow-logs.ts +++ b/apps/sim/ee/data-drains/lib/sources/workflow-logs.ts @@ -2,16 +2,16 @@ import { dbReplica } from '@sim/db' import { workflowExecutionLogColumns, workflowExecutionLogs } from '@sim/db/schema' import { and, inArray, isNotNull } from 'drizzle-orm' import { MATERIALIZE_CONCURRENCY, mapWithConcurrency } from '@/lib/core/utils/concurrency' +import { materializeExecutionDataForDisplay } from '@/lib/logs/execution/trace-store' import { decodeTimeCursor, encodeTimeCursor, timeCursorOrderBy, timeCursorPredicate, timeCursorStabilityBound, -} from '@/lib/data-drains/sources/cursor' -import { getOrganizationWorkspaceIds } from '@/lib/data-drains/sources/helpers' -import type { Cursor, DrainSource, SourcePageInput } from '@/lib/data-drains/types' -import { materializeExecutionDataForDisplay } from '@/lib/logs/execution/trace-store' +} from '@/ee/data-drains/lib/sources/cursor' +import { getOrganizationWorkspaceIds } from '@/ee/data-drains/lib/sources/helpers' +import type { Cursor, DrainSource, SourcePageInput } from '@/ee/data-drains/lib/types' type WorkflowLogRow = Omit diff --git a/apps/sim/lib/data-drains/types.ts b/apps/sim/ee/data-drains/lib/types.ts similarity index 100% rename from apps/sim/lib/data-drains/types.ts rename to apps/sim/ee/data-drains/lib/types.ts diff --git a/apps/sim/lib/billing/retention.test.ts b/apps/sim/ee/data-retention/lib/retention.test.ts similarity index 99% rename from apps/sim/lib/billing/retention.test.ts rename to apps/sim/ee/data-retention/lib/retention.test.ts index 4c35d68948f..4dcb6966dac 100644 --- a/apps/sim/lib/billing/retention.test.ts +++ b/apps/sim/ee/data-retention/lib/retention.test.ts @@ -9,7 +9,7 @@ import { getForeignWorkspaceTargetsReason, resolveEffectivePiiRedaction, resolveEffectiveRetentionHours, -} from '@/lib/billing/retention' +} from '@/ee/data-retention/lib/retention' function settings(rules: PiiRedactionRule[]): DataRetentionSettings { return { piiRedaction: { rules } } diff --git a/apps/sim/lib/billing/retention.ts b/apps/sim/ee/data-retention/lib/retention.ts similarity index 100% rename from apps/sim/lib/billing/retention.ts rename to apps/sim/ee/data-retention/lib/retention.ts diff --git a/apps/sim/lib/billing/application/organization-usage/authorized-organization-usage-use-case.ts b/apps/sim/ee/organization-usage/lib/authorized-organization-usage-use-case.ts similarity index 98% rename from apps/sim/lib/billing/application/organization-usage/authorized-organization-usage-use-case.ts rename to apps/sim/ee/organization-usage/lib/authorized-organization-usage-use-case.ts index edef9a963ec..f5d8c34d7ce 100644 --- a/apps/sim/lib/billing/application/organization-usage/authorized-organization-usage-use-case.ts +++ b/apps/sim/ee/organization-usage/lib/authorized-organization-usage-use-case.ts @@ -1,8 +1,4 @@ import type { Principal } from '@sim/auth/principal' -import type { - OrganizationUsageOperation, - OrganizationUsagePrincipal, -} from '@/lib/billing/application/organization-usage/operations' import { getOrganizationSubscription } from '@/lib/billing/core/billing' import { type ResolvedUsagePeriod, @@ -13,6 +9,10 @@ import type { BillingEntity } from '@/lib/billing/core/usage-log' import { canUserManageBillingEntity } from '@/lib/billing/core/workspace-billing-authority' import { ForbiddenOperationError, type OperationUseCase } from '@/lib/core/application' import { isUsageMonitoringEnabled } from '@/lib/core/config/env-flags' +import type { + OrganizationUsageOperation, + OrganizationUsagePrincipal, +} from '@/ee/organization-usage/lib/operations' export interface AuthorizedOrganizationUsageContext { organizationId: string diff --git a/apps/sim/lib/billing/application/organization-usage/export-organization-usage-events.ts b/apps/sim/ee/organization-usage/lib/export-organization-usage-events.ts similarity index 94% rename from apps/sim/lib/billing/application/organization-usage/export-organization-usage-events.ts rename to apps/sim/ee/organization-usage/lib/export-organization-usage-events.ts index c5cd4a51ade..a2547157a60 100644 --- a/apps/sim/lib/billing/application/organization-usage/export-organization-usage-events.ts +++ b/apps/sim/ee/organization-usage/lib/export-organization-usage-events.ts @@ -1,5 +1,3 @@ -import { defineAuthorizedOrganizationUsageUseCase } from '@/lib/billing/application/organization-usage/authorized-organization-usage-use-case' -import { organizationUsageOperations } from '@/lib/billing/application/organization-usage/operations' import { resolveUsageAnalyticsWindow, type UsageWindowPreset, @@ -8,6 +6,8 @@ import { import { getBillingEntityUsageLogs } from '@/lib/billing/core/usage-log' import { CREDIT_MULTIPLIER } from '@/lib/billing/credits/conversion' import type { InternalUsageLogSource } from '@/lib/billing/usage-sources' +import { defineAuthorizedOrganizationUsageUseCase } from '@/ee/organization-usage/lib/authorized-organization-usage-use-case' +import { organizationUsageOperations } from '@/ee/organization-usage/lib/operations' /** * Circuit breaker, not a UX boundary. An enterprise ledger is genuinely large, so diff --git a/apps/sim/lib/billing/application/organization-usage/get-organization-usage-breakdown.ts b/apps/sim/ee/organization-usage/lib/get-organization-usage-breakdown.ts similarity index 97% rename from apps/sim/lib/billing/application/organization-usage/get-organization-usage-breakdown.ts rename to apps/sim/ee/organization-usage/lib/get-organization-usage-breakdown.ts index 4e5ea54fea3..2d413c3d59d 100644 --- a/apps/sim/lib/billing/application/organization-usage/get-organization-usage-breakdown.ts +++ b/apps/sim/ee/organization-usage/lib/get-organization-usage-breakdown.ts @@ -1,5 +1,3 @@ -import { defineAuthorizedOrganizationUsageUseCase } from '@/lib/billing/application/organization-usage/authorized-organization-usage-use-case' -import { organizationUsageOperations } from '@/lib/billing/application/organization-usage/operations' import { buildUsageAnalyticsScope, foldUsageBreakdown, @@ -20,6 +18,8 @@ import { type InternalUsageLogSource, toBillingUsageLogSource, } from '@/lib/billing/usage-sources' +import { defineAuthorizedOrganizationUsageUseCase } from '@/ee/organization-usage/lib/authorized-organization-usage-use-case' +import { organizationUsageOperations } from '@/ee/organization-usage/lib/operations' import { getProviderFromModel, PROVIDER_DEFINITIONS } from '@/providers/models' export interface OrganizationUsageBreakdownInput { diff --git a/apps/sim/lib/billing/application/organization-usage/get-organization-usage-summary.ts b/apps/sim/ee/organization-usage/lib/get-organization-usage-summary.ts similarity index 95% rename from apps/sim/lib/billing/application/organization-usage/get-organization-usage-summary.ts rename to apps/sim/ee/organization-usage/lib/get-organization-usage-summary.ts index 611f229be8e..13d52d73bca 100644 --- a/apps/sim/lib/billing/application/organization-usage/get-organization-usage-summary.ts +++ b/apps/sim/ee/organization-usage/lib/get-organization-usage-summary.ts @@ -1,5 +1,3 @@ -import { defineAuthorizedOrganizationUsageUseCase } from '@/lib/billing/application/organization-usage/authorized-organization-usage-use-case' -import { organizationUsageOperations } from '@/lib/billing/application/organization-usage/operations' import type { UsagePeriodSource } from '@/lib/billing/core/reporting-period' import { buildUsageAnalyticsScope, @@ -13,6 +11,8 @@ import { } from '@/lib/billing/core/usage-analytics' import { readUsageTimeSeries, readUsageTotals } from '@/lib/billing/core/usage-analytics-queries' import { apportionCredits, dollarsToCredits } from '@/lib/billing/credits/conversion' +import { defineAuthorizedOrganizationUsageUseCase } from '@/ee/organization-usage/lib/authorized-organization-usage-use-case' +import { organizationUsageOperations } from '@/ee/organization-usage/lib/operations' export interface OrganizationUsageSummaryInput { organizationId: string diff --git a/apps/sim/lib/billing/application/organization-usage/list-organization-usage-events.ts b/apps/sim/ee/organization-usage/lib/list-organization-usage-events.ts similarity index 91% rename from apps/sim/lib/billing/application/organization-usage/list-organization-usage-events.ts rename to apps/sim/ee/organization-usage/lib/list-organization-usage-events.ts index 9a1e2b80607..5cb1054d3dc 100644 --- a/apps/sim/lib/billing/application/organization-usage/list-organization-usage-events.ts +++ b/apps/sim/ee/organization-usage/lib/list-organization-usage-events.ts @@ -1,5 +1,3 @@ -import { defineAuthorizedOrganizationUsageUseCase } from '@/lib/billing/application/organization-usage/authorized-organization-usage-use-case' -import { organizationUsageOperations } from '@/lib/billing/application/organization-usage/operations' import { resolveUsageAnalyticsWindow, type UsageWindowPreset, @@ -8,6 +6,8 @@ import { import { getBillingEntityUsageLogs } from '@/lib/billing/core/usage-log' import { dollarsToCredits } from '@/lib/billing/credits/conversion' import type { InternalUsageLogSource } from '@/lib/billing/usage-sources' +import { defineAuthorizedOrganizationUsageUseCase } from '@/ee/organization-usage/lib/authorized-organization-usage-use-case' +import { organizationUsageOperations } from '@/ee/organization-usage/lib/operations' export interface OrganizationUsageEventsInput { organizationId: string diff --git a/apps/sim/lib/billing/application/organization-usage/operations.ts b/apps/sim/ee/organization-usage/lib/operations.ts similarity index 100% rename from apps/sim/lib/billing/application/organization-usage/operations.ts rename to apps/sim/ee/organization-usage/lib/operations.ts diff --git a/apps/sim/lib/billing/application/organization-usage/organization-usage-use-cases.test.ts b/apps/sim/ee/organization-usage/lib/organization-usage-use-cases.test.ts similarity index 97% rename from apps/sim/lib/billing/application/organization-usage/organization-usage-use-cases.test.ts rename to apps/sim/ee/organization-usage/lib/organization-usage-use-cases.test.ts index 22120ef90ff..3d7d9dbbd9d 100644 --- a/apps/sim/lib/billing/application/organization-usage/organization-usage-use-cases.test.ts +++ b/apps/sim/ee/organization-usage/lib/organization-usage-use-cases.test.ts @@ -29,8 +29,8 @@ vi.mock('@/lib/billing/core/usage-analytics-queries', () => ({ readUsageEntityNames: vi.fn(), })) -import { getOrganizationUsageSummary } from '@/lib/billing/application/organization-usage/get-organization-usage-summary' import { ForbiddenOperationError } from '@/lib/core/application' +import { getOrganizationUsageSummary } from '@/ee/organization-usage/lib/get-organization-usage-summary' const ORG = 'org-1' const session: SessionPrincipal = { kind: 'session', userId: 'admin-1', sessionId: 'session-1' } diff --git a/apps/sim/lib/auth/session-policy.test.ts b/apps/sim/ee/session-policy/lib/session-policy.test.ts similarity index 96% rename from apps/sim/lib/auth/session-policy.test.ts rename to apps/sim/ee/session-policy/lib/session-policy.test.ts index 6484f179b91..d367423d98d 100644 --- a/apps/sim/lib/auth/session-policy.test.ts +++ b/apps/sim/ee/session-policy/lib/session-policy.test.ts @@ -3,7 +3,10 @@ */ import { describe, expect, it } from 'vitest' import { MIN_IDLE_TIMEOUT_HOURS } from '@/lib/api/contracts/organization' -import { clampSessionExpiry, type ResolvedSessionPolicy } from '@/lib/auth/session-policy' +import { + clampSessionExpiry, + type ResolvedSessionPolicy, +} from '@/ee/session-policy/lib/session-policy' const HOUR_MS = 60 * 60 * 1000 diff --git a/apps/sim/lib/auth/session-policy.ts b/apps/sim/ee/session-policy/lib/session-policy.ts similarity index 100% rename from apps/sim/lib/auth/session-policy.ts rename to apps/sim/ee/session-policy/lib/session-policy.ts diff --git a/apps/sim/lib/auth/sso/application/admit-sso-user.test.ts b/apps/sim/ee/sso/lib/application/admit-sso-user.test.ts similarity index 98% rename from apps/sim/lib/auth/sso/application/admit-sso-user.test.ts rename to apps/sim/ee/sso/lib/application/admit-sso-user.test.ts index 06194b17a02..96cdb5e0ddf 100644 --- a/apps/sim/lib/auth/sso/application/admit-sso-user.test.ts +++ b/apps/sim/ee/sso/lib/application/admit-sso-user.test.ts @@ -36,7 +36,7 @@ vi.mock('@/lib/billing/organizations/membership', () => ({ ensureUserInOrganizationTx: mockEnsureUserInOrganizationTx, })) -vi.mock('@/lib/auth/session-policy', () => ({ +vi.mock('@/ee/session-policy/lib/session-policy', () => ({ applySessionPolicyToNewMember: mockApplySessionPolicyToNewMember, })) @@ -52,7 +52,7 @@ vi.mock('@/lib/posthog/server', () => ({ captureServerEvent: mockCaptureServerEvent, })) -import { admitSsoUser } from '@/lib/auth/sso/application/admit-sso-user' +import { admitSsoUser } from '@/ee/sso/lib/application/admit-sso-user' const principal = { kind: 'session' as const, userId: 'user-1', sessionId: 'session-1' } diff --git a/apps/sim/lib/auth/sso/application/admit-sso-user.ts b/apps/sim/ee/sso/lib/application/admit-sso-user.ts similarity index 98% rename from apps/sim/lib/auth/sso/application/admit-sso-user.ts rename to apps/sim/ee/sso/lib/application/admit-sso-user.ts index 3207660bacc..bd01424536e 100644 --- a/apps/sim/lib/auth/sso/application/admit-sso-user.ts +++ b/apps/sim/ee/sso/lib/application/admit-sso-user.ts @@ -14,8 +14,6 @@ import { createLogger } from '@sim/logger' import { normalizeSSODomain } from '@sim/utils/sso-domain' import { normalizeEmail } from '@sim/utils/string' import { and, desc, eq, gt, inArray, isNull, sql } from 'drizzle-orm' -import { applySessionPolicyToNewMember } from '@/lib/auth/session-policy' -import { ssoJitAdmissionOperation } from '@/lib/auth/sso/application/operations' import { syncUsageLimitsFromSubscription } from '@/lib/billing/core/usage' import { acquireOrganizationUserMutationLocks, @@ -26,6 +24,8 @@ import { isTeam } from '@/lib/billing/plan-helpers' import { ENTITLED_SUBSCRIPTION_STATUSES } from '@/lib/billing/subscriptions/utils' import { assertOperationPrincipal, type OperationUseCase } from '@/lib/core/application/operation' import { captureServerEvent } from '@/lib/posthog/server' +import { applySessionPolicyToNewMember } from '@/ee/session-policy/lib/session-policy' +import { ssoJitAdmissionOperation } from '@/ee/sso/lib/application/operations' const logger = createLogger('SsoJitAdmission') diff --git a/apps/sim/lib/auth/sso/application/operations.ts b/apps/sim/ee/sso/lib/application/operations.ts similarity index 100% rename from apps/sim/lib/auth/sso/application/operations.ts rename to apps/sim/ee/sso/lib/application/operations.ts diff --git a/apps/sim/lib/auth/sso/callback-provider.test.ts b/apps/sim/ee/sso/lib/callback-provider.test.ts similarity index 93% rename from apps/sim/lib/auth/sso/callback-provider.test.ts rename to apps/sim/ee/sso/lib/callback-provider.test.ts index cf2225b7993..667d7330447 100644 --- a/apps/sim/lib/auth/sso/callback-provider.test.ts +++ b/apps/sim/ee/sso/lib/callback-provider.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest' -import { resolveSsoCallbackProviderId } from '@/lib/auth/sso/callback-provider' +import { resolveSsoCallbackProviderId } from '@/ee/sso/lib/callback-provider' describe('SSO callback provider resolution', () => { it.each([ diff --git a/apps/sim/lib/auth/sso/callback-provider.ts b/apps/sim/ee/sso/lib/callback-provider.ts similarity index 100% rename from apps/sim/lib/auth/sso/callback-provider.ts rename to apps/sim/ee/sso/lib/callback-provider.ts diff --git a/apps/sim/lib/auth/sso/domain-verification.test.ts b/apps/sim/ee/sso/lib/domain-verification.test.ts similarity index 99% rename from apps/sim/lib/auth/sso/domain-verification.test.ts rename to apps/sim/ee/sso/lib/domain-verification.test.ts index 842a1b72609..10ea0d350f0 100644 --- a/apps/sim/lib/auth/sso/domain-verification.test.ts +++ b/apps/sim/ee/sso/lib/domain-verification.test.ts @@ -22,7 +22,7 @@ import { generateVerificationToken, SSO_CHALLENGE_HOST_PREFIX, toDomainResponse, -} from '@/lib/auth/sso/domain-verification' +} from '@/ee/sso/lib/domain-verification' describe('domain-verification helpers', () => { it('builds the challenge host on the underscore-prefixed label', () => { diff --git a/apps/sim/lib/auth/sso/domain-verification.ts b/apps/sim/ee/sso/lib/domain-verification.ts similarity index 100% rename from apps/sim/lib/auth/sso/domain-verification.ts rename to apps/sim/ee/sso/lib/domain-verification.ts diff --git a/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.test.ts b/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.test.ts index 9e335097c70..5fb5ab45695 100644 --- a/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.test.ts +++ b/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.test.ts @@ -7,7 +7,7 @@ import type { WorkflowState } from '@/stores/workflows/workflow/types' const { mockResolveBinding } = vi.hoisted(() => ({ mockResolveBinding: vi.fn() })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ resolveCustomBlockToolBinding: mockResolveBinding, })) diff --git a/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.ts b/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.ts index 60ba062e578..958993e46a2 100644 --- a/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.ts +++ b/apps/sim/ee/workspace-forking/lib/mapping/custom-block-reconfigs.ts @@ -1,8 +1,8 @@ import { createLogger } from '@sim/logger' import { getErrorMessage } from '@sim/utils/errors' import type { ForkDependentReconfig } from '@/lib/api/contracts/workspace-fork' -import { resolveCustomBlockToolBinding } from '@/lib/workflows/custom-blocks/operations' import { isCustomBlockType } from '@/blocks/custom/build-config' +import { resolveCustomBlockToolBinding } from '@/ee/custom-blocks/lib/operations' import type { ForkBlockIdResolver } from '@/ee/workspace-forking/lib/remap/block-identity' import { customBlockInputStorageKey, diff --git a/apps/sim/executor/handlers/agent/agent-handler.ts b/apps/sim/executor/handlers/agent/agent-handler.ts index 857643acec7..06085b46e8b 100644 --- a/apps/sim/executor/handlers/agent/agent-handler.ts +++ b/apps/sim/executor/handlers/agent/agent-handler.ts @@ -40,7 +40,6 @@ import { } from '@/lib/uploads/utils/file-utils' import { selectModelBoundFileInputPaths } from '@/lib/uploads/utils/model-input' import { hydrateUserFilesWithBase64 } from '@/lib/uploads/utils/user-file-base64.server' -import { resolveCustomBlockToolBinding } from '@/lib/workflows/custom-blocks/operations' import { getAllBlocks, getBlock } from '@/blocks' import { assembleCustomBlockInputMapping, isCustomBlockType } from '@/blocks/custom/build-config' import type { BlockOutput } from '@/blocks/types' @@ -50,6 +49,7 @@ import { validateBlockType, validateModelProvider, } from '@/ee/access-control/utils/permission-check' +import { resolveCustomBlockToolBinding } from '@/ee/custom-blocks/lib/operations' import { AGENT, BlockType, DEFAULTS, stripCustomToolPrefix } from '@/executor/constants' import { memoryService } from '@/executor/handlers/agent/memory' import { diff --git a/apps/sim/executor/handlers/pi/cloud/babysit/backend.test.ts b/apps/sim/executor/handlers/pi/cloud/babysit/backend.test.ts index 000c3b24c51..a64f3e0f68b 100644 --- a/apps/sim/executor/handlers/pi/cloud/babysit/backend.test.ts +++ b/apps/sim/executor/handlers/pi/cloud/babysit/backend.test.ts @@ -31,7 +31,7 @@ const { vi.mock('@/lib/execution/remote-sandbox', () => ({ withPiSandbox: mockWithPiSandbox, })) -vi.mock('@/lib/data-drains/destinations/utils', () => ({ +vi.mock('@/ee/data-drains/lib/destinations/utils', () => ({ sleepUntilAborted: mockSleepUntilAborted, })) vi.mock('@/lib/execution/remote-sandbox/pi-lifetime', async (importOriginal) => { diff --git a/apps/sim/executor/handlers/pi/cloud/babysit/backend.ts b/apps/sim/executor/handlers/pi/cloud/babysit/backend.ts index 08d4af65ac5..4aa7c59d704 100644 --- a/apps/sim/executor/handlers/pi/cloud/babysit/backend.ts +++ b/apps/sim/executor/handlers/pi/cloud/babysit/backend.ts @@ -7,12 +7,12 @@ import { createLogger } from '@sim/logger' import { getErrorMessage } from '@sim/utils/errors' import { truncate } from '@sim/utils/string' -import { sleepUntilAborted } from '@/lib/data-drains/destinations/utils' import { type PiSandboxRunner, withPiSandbox } from '@/lib/execution/remote-sandbox' import { resolvePiRunLifetimeMs, resolvePiSandboxLifetimeMs, } from '@/lib/execution/remote-sandbox/pi-lifetime' +import { sleepUntilAborted } from '@/ee/data-drains/lib/destinations/utils' import { assertBabysitPinned, type BabysitCheck, diff --git a/apps/sim/executor/handlers/pi/local/sim-tools.ts b/apps/sim/executor/handlers/pi/local/sim-tools.ts index acb590d644c..ce19fce037c 100644 --- a/apps/sim/executor/handlers/pi/local/sim-tools.ts +++ b/apps/sim/executor/handlers/pi/local/sim-tools.ts @@ -14,8 +14,8 @@ import { readWorkflowInputFieldsForTool, readWorkflowMetadataForTool, } from '@/lib/internal/workflows/read-tool-enrichment' -import { resolveCustomBlockToolBinding } from '@/lib/workflows/custom-blocks/operations' import { getAllBlocks } from '@/blocks/registry' +import { resolveCustomBlockToolBinding } from '@/ee/custom-blocks/lib/operations' import type { ToolInput } from '@/executor/handlers/agent/types' import type { PiToolResult, PiToolSpec } from '@/executor/handlers/pi/core/backend' import type { ExecutionContext } from '@/executor/types' diff --git a/apps/sim/executor/handlers/workflow/workflow-handler.test.ts b/apps/sim/executor/handlers/workflow/workflow-handler.test.ts index 6b1d4283ef3..c47fae6589f 100644 --- a/apps/sim/executor/handlers/workflow/workflow-handler.test.ts +++ b/apps/sim/executor/handlers/workflow/workflow-handler.test.ts @@ -101,7 +101,7 @@ vi.mock('@/lib/core/security/encryption', () => ({ encryptSecret: encryptionMockFns.mockEncryptSecret, })) -vi.mock('@/lib/workflows/custom-blocks/child-execution', () => ({ +vi.mock('@/ee/custom-blocks/lib/child-execution', () => ({ admitCustomBlockChildExecution: mockAdmitCustomBlockChildExecution, trackChildRun: mockTrackChildRun, buildCustomBlockCorrelation: (params: Record) => @@ -129,7 +129,7 @@ vi.mock('@/lib/billing/core/billing-attribution', () => ({ const mockGetPersonalAndWorkspaceEnv = environmentUtilsMockFns.mockGetPersonalAndWorkspaceEnv -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ getCustomBlockAuthority: mockGetCustomBlockAuthority, })) diff --git a/apps/sim/executor/handlers/workflow/workflow-handler.ts b/apps/sim/executor/handlers/workflow/workflow-handler.ts index 3eb08c62779..e1307103af1 100644 --- a/apps/sim/executor/handlers/workflow/workflow-handler.ts +++ b/apps/sim/executor/handlers/workflow/workflow-handler.ts @@ -13,13 +13,6 @@ import { LoggingSession } from '@/lib/logs/execution/logging-session' import { snapshotService } from '@/lib/logs/execution/snapshot/service' import { buildTraceSpans } from '@/lib/logs/execution/trace-spans/trace-spans' import type { TraceSpan } from '@/lib/logs/types' -import { - admitCustomBlockChildExecution, - buildCustomBlockCorrelation, - createChildCancellationSignal, - trackChildRun, -} from '@/lib/workflows/custom-blocks/child-execution' -import { getCustomBlockAuthority } from '@/lib/workflows/custom-blocks/operations' import { resolveStartBlockRunIdentity, type StartBlockRunIdentity, @@ -32,6 +25,13 @@ import { import { parseWorkflowVariables } from '@/lib/workflows/variables/parse' import { type CustomBlockOutput, isCustomBlockType } from '@/blocks/custom/build-config' import type { BlockOutput } from '@/blocks/types' +import { + admitCustomBlockChildExecution, + buildCustomBlockCorrelation, + createChildCancellationSignal, + trackChildRun, +} from '@/ee/custom-blocks/lib/child-execution' +import { getCustomBlockAuthority } from '@/ee/custom-blocks/lib/operations' import { Executor } from '@/executor' import { BlockType, diff --git a/apps/sim/executor/types.ts b/apps/sim/executor/types.ts index 36c7256967b..c90f8e494e7 100644 --- a/apps/sim/executor/types.ts +++ b/apps/sim/executor/types.ts @@ -1,8 +1,8 @@ import type { WorkflowExecutionAuthority, WorkflowExecutionPrincipal } from '@sim/auth/principal' import type { BillingAttributionSnapshot } from '@/lib/billing/core/billing-attribution' import type { TraceSpan } from '@/lib/logs/types' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' import type { BlockOutput } from '@/blocks/types' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' import type { ChildWorkflowContext, ExecutionCallbacks, diff --git a/apps/sim/hooks/use-operation-access.ts b/apps/sim/hooks/use-operation-access.ts index 1395e20658c..603e1c8c9c8 100644 --- a/apps/sim/hooks/use-operation-access.ts +++ b/apps/sim/hooks/use-operation-access.ts @@ -10,7 +10,7 @@ import { type OperationGateBlock, pickDefaultOperation, type SeedValueGate, -} from '@/lib/permission-groups/operation-access' +} from '@/ee/access-control/lib/operation-access' import { usePermissionConfig } from '@/hooks/use-permission-config' export interface OperationAccess { diff --git a/apps/sim/hooks/use-permission-config.ts b/apps/sim/hooks/use-permission-config.ts index 36dc856180b..56b3701d60a 100644 --- a/apps/sim/hooks/use-permission-config.ts +++ b/apps/sim/hooks/use-permission-config.ts @@ -14,21 +14,21 @@ import { isDeploymentGatedIntegrationType, resolveIntegrationAvailabilityStateForVisibility, } from '@/lib/integrations/availability' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' +import { useOptionalWorkspaceHostContext } from '@/app/workspace/[workspaceId]/providers/workspace-host-provider' +import { useCustomBlockOverlayVersion } from '@/blocks/custom/client-overlay' +import { overlayVisibility } from '@/blocks/visibility/context' +import { useUserPermissionConfig } from '@/ee/access-control/hooks/permission-groups' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' import { DEFAULT_PERMISSION_GROUP_CONFIG, type PermissionGroupConfig, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' import { intersectAccessControlAllowlists, resolveAccessControlBlockType, -} from '@/lib/permission-groups/integration-allowlist' -import { createModelAccessGate } from '@/lib/permission-groups/model-access' -import { createToolAccessGate } from '@/lib/permission-groups/operation-access' -import { useOptionalWorkspaceHostContext } from '@/app/workspace/[workspaceId]/providers/workspace-host-provider' -import { useCustomBlockOverlayVersion } from '@/blocks/custom/client-overlay' -import { overlayVisibility } from '@/blocks/visibility/context' -import { useUserPermissionConfig } from '@/ee/access-control/hooks/permission-groups' +} from '@/ee/access-control/lib/integration-allowlist' +import { createModelAccessGate } from '@/ee/access-control/lib/model-access' +import { createToolAccessGate } from '@/ee/access-control/lib/operation-access' export interface PermissionConfigResult { config: PermissionGroupConfig diff --git a/apps/sim/lib/api/contracts/data-drains.ts b/apps/sim/lib/api/contracts/data-drains.ts index ace4ddeb017..f63856c929d 100644 --- a/apps/sim/lib/api/contracts/data-drains.ts +++ b/apps/sim/lib/api/contracts/data-drains.ts @@ -1,7 +1,7 @@ import { z } from 'zod' import { defineRouteContract } from '@/lib/api/contracts/types' import { validateExternalUrl } from '@/lib/core/security/input-validation' -import { CADENCE_TYPES, DESTINATION_TYPES, SOURCE_TYPES } from '@/lib/data-drains/types' +import { CADENCE_TYPES, DESTINATION_TYPES, SOURCE_TYPES } from '@/ee/data-drains/lib/types' /** AWS S3 bucket: 3-63 chars, lowercase alnum + . / -, see s3.ts for full rules. */ const S3_BUCKET_NAME_RE = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/ diff --git a/apps/sim/lib/api/contracts/organization.ts b/apps/sim/lib/api/contracts/organization.ts index f8cf72bed90..9d568e8295f 100644 --- a/apps/sim/lib/api/contracts/organization.ts +++ b/apps/sim/lib/api/contracts/organization.ts @@ -107,7 +107,7 @@ export const organizationDataRetentionResponseSchema = z.object({ /** * Session-policy bounds — the single source for the contract validation, the - * server-side clamp (`@/lib/auth/session-policy`), and the settings UI. + * server-side clamp (`@/ee/session-policy/lib/session-policy`), and the settings UI. * `MIN_IDLE_TIMEOUT_HOURS` is twice the session cookie-cache window (24h): * cached reads never record activity, so a continuously active user only * refreshes their session when the cookie cache expires. A floor of one diff --git a/apps/sim/lib/api/contracts/permission-groups.test.ts b/apps/sim/lib/api/contracts/permission-groups.test.ts index 6359763d60f..d0cd0dcc366 100644 --- a/apps/sim/lib/api/contracts/permission-groups.test.ts +++ b/apps/sim/lib/api/contracts/permission-groups.test.ts @@ -10,7 +10,7 @@ import { import { DEFAULT_PERMISSION_GROUP_CONFIG, parsePermissionGroupConfig, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' describe('createPermissionGroupBodySchema', () => { it('accepts a name-only body (scope is resolved and validated server-side)', () => { diff --git a/apps/sim/lib/api/contracts/permission-groups.ts b/apps/sim/lib/api/contracts/permission-groups.ts index 6d80ee68d18..000d57cb507 100644 --- a/apps/sim/lib/api/contracts/permission-groups.ts +++ b/apps/sim/lib/api/contracts/permission-groups.ts @@ -4,7 +4,7 @@ import { defineRouteContract } from '@/lib/api/contracts/types' import { permissionGroupConfigSchema, permissionGroupReadShape, -} from '@/lib/permission-groups/fields' +} from '@/ee/access-control/lib/fields' /** * The wire shape of a resolved config: every key present, in registry order. diff --git a/apps/sim/lib/api/contracts/v2/shared.ts b/apps/sim/lib/api/contracts/v2/shared.ts index fd594f14f90..45ca3d9fec2 100644 --- a/apps/sim/lib/api/contracts/v2/shared.ts +++ b/apps/sim/lib/api/contracts/v2/shared.ts @@ -134,7 +134,7 @@ import { * whose page boundary is not expressible as one, mints its own — a bare * `encodeCursor({ version })` on `GET /workflows/{workflowId}/versions` and * `encodeCursor({ email })` on the workspace member list, the audit-log and run-log - * codecs in `lib/audit-logs/query.ts` and `lib/logs/list-logs.ts`, the table-row + * codecs in `ee/audit-logs/lib/query.ts` and `lib/logs/list-logs.ts`, the table-row * codec in `lib/table/rows/cursor.ts`, and a usage-event id passed straight * through by `GET /billing/logs`. Those tokens stay opaque and untouched, but the * three whose sequence a caller can re-filter are wrapped in diff --git a/apps/sim/lib/auth/auth.ts b/apps/sim/lib/auth/auth.ts index e01cc509be7..80e06c8e03c 100644 --- a/apps/sim/lib/auth/auth.ts +++ b/apps/sim/lib/auth/auth.ts @@ -38,10 +38,7 @@ import { isSignInProviderAllowed, } from '@/lib/auth/constants' import { getSessionCookieCacheVersion } from '@/lib/auth/security-policy' -import { clampExpiryForSession } from '@/lib/auth/session-policy' import { getActiveOrganizationId } from '@/lib/auth/session-response' -import { admitSsoUser } from '@/lib/auth/sso/application/admit-sso-user' -import { resolveSsoCallbackProviderId } from '@/lib/auth/sso/callback-provider' import { guardSubscriptionPlanWrites } from '@/lib/auth/stripe-adapter-guard' import { sendPlanWelcomeEmail } from '@/lib/billing' import { @@ -132,7 +129,10 @@ import { getCanonicalScopesForProvider } from '@/lib/oauth/utils' import { joinInstanceOrganization } from '@/lib/organizations/instance-org' import { captureServerEvent, getPostHogClient } from '@/lib/posthog/server' import { disableUserResources } from '@/lib/workflows/lifecycle' +import { clampExpiryForSession } from '@/ee/session-policy/lib/session-policy' import { SSO_TRUSTED_PROVIDERS } from '@/ee/sso/constants' +import { admitSsoUser } from '@/ee/sso/lib/application/admit-sso-user' +import { resolveSsoCallbackProviderId } from '@/ee/sso/lib/callback-provider' const logger = createLogger('Auth') diff --git a/apps/sim/lib/billing/application/authorized-billing-read-use-case.ts b/apps/sim/lib/billing/application/authorized-billing-read-use-case.ts index 5a6105d6cf1..3cc9e14b762 100644 --- a/apps/sim/lib/billing/application/authorized-billing-read-use-case.ts +++ b/apps/sim/lib/billing/application/authorized-billing-read-use-case.ts @@ -16,11 +16,11 @@ import { WorkspaceApiKeyScopeAuthorizationError, } from '@/lib/core/application/workspace-authorization' import { OrchestrationError } from '@/lib/core/orchestration/types' -import { isCapabilityWithheldForUser } from '@/lib/permission-groups/user-scope.server' import { type ActiveWorkspaceApplicationContext, loadActiveWorkspaceApplicationContext, } from '@/lib/workspaces/application/workspace-context' +import { isCapabilityWithheldForUser } from '@/ee/access-control/lib/user-scope.server' export type BillingReadScope = | { kind: 'account'; userId: string } diff --git a/apps/sim/lib/billing/application/billing-use-cases.test.ts b/apps/sim/lib/billing/application/billing-use-cases.test.ts index 0665c709b26..0e826dd3786 100644 --- a/apps/sim/lib/billing/application/billing-use-cases.test.ts +++ b/apps/sim/lib/billing/application/billing-use-cases.test.ts @@ -9,7 +9,7 @@ import { } from '@sim/testing' import { beforeEach, describe, expect, it, vi } from 'vitest' -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) const mocks = vi.hoisted(() => ({ loadWorkspace: vi.fn(), @@ -36,7 +36,7 @@ const mocks = vi.hoisted(() => ({ isCapabilityWithheldForUser: vi.fn(), })) -vi.mock('@/lib/permission-groups/user-scope.server', () => ({ +vi.mock('@/ee/access-control/lib/user-scope.server', () => ({ isCapabilityWithheldForUser: mocks.isCapabilityWithheldForUser, })) @@ -91,7 +91,7 @@ vi.mock('@sim/audit', () => ({ recordAudit: mocks.recordAudit })) import { getBillingStatus } from '@/lib/billing/application/get-billing-status' import { listBillingLogs } from '@/lib/billing/application/list-billing-logs' import { PersonalApiKeysDisabledError } from '@/lib/core/application' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const workspaceContext = { workspaceId: 'workspace-1', diff --git a/apps/sim/lib/billing/cleanup-dispatcher.ts b/apps/sim/lib/billing/cleanup-dispatcher.ts index b53f7ae7faf..6a3acdb229d 100644 --- a/apps/sim/lib/billing/cleanup-dispatcher.ts +++ b/apps/sim/lib/billing/cleanup-dispatcher.ts @@ -8,7 +8,6 @@ import { and, asc, eq, gt, isNull } from 'drizzle-orm' import { getOrganizationSubscription } from '@/lib/billing/core/billing' import { getHighestPriorityPersonalSubscription } from '@/lib/billing/core/subscription' import { getPlanType, type PlanCategory } from '@/lib/billing/plan-helpers' -import { type RetentionHoursKey, resolveEffectiveRetentionHours } from '@/lib/billing/retention' import { getJobQueue } from '@/lib/core/async-jobs' import { shouldExecuteInline } from '@/lib/core/async-jobs/config' import { resolveTriggerRegion } from '@/lib/core/async-jobs/region' @@ -16,6 +15,10 @@ import type { EnqueueOptions } from '@/lib/core/async-jobs/types' import { isBillingEnabled, isDataRetentionEnabled } from '@/lib/core/config/env-flags' import { isTriggerAvailable } from '@/lib/knowledge/documents/service' import { isOrganizationWorkspace, WORKSPACE_MODE } from '@/lib/workspaces/policy' +import { + type RetentionHoursKey, + resolveEffectiveRetentionHours, +} from '@/ee/data-retention/lib/retention' const logger = createLogger('RetentionDispatcher') diff --git a/apps/sim/lib/billing/organizations/membership.ts b/apps/sim/lib/billing/organizations/membership.ts index b60cca4b149..1ffbae8bd28 100644 --- a/apps/sim/lib/billing/organizations/membership.ts +++ b/apps/sim/lib/billing/organizations/membership.ts @@ -25,7 +25,6 @@ import { generateId } from '@sim/utils/id' import { normalizeEmail } from '@sim/utils/string' import { and, count, desc, eq, inArray, isNull, ne, or, sql } from 'drizzle-orm' import { invalidateMembershipCache } from '@/lib/auth/security-policy' -import { applySessionPolicyToNewMember } from '@/lib/auth/session-policy' import { syncUsageLimitsFromSubscription } from '@/lib/billing/core/usage' import { assertNoUnresolvedEnterpriseIssuance, @@ -52,6 +51,7 @@ import { reassignWorkflowOwnershipForWorkspaceMemberRemovalTx, WorkspaceBillingAccountRemovalError, } from '@/lib/workspaces/utils' +import { applySessionPolicyToNewMember } from '@/ee/session-policy/lib/session-policy' export { acquireUserBillingIdentityLock } from '@/lib/billing/organizations/billing-identity-lock' export { WORKSPACE_BILLING_ACCOUNT_REMOVAL_ERROR } from '@/lib/workspaces/utils' diff --git a/apps/sim/lib/catalog/application/catalog-context.ts b/apps/sim/lib/catalog/application/catalog-context.ts index f06375a630e..ee805dc5839 100644 --- a/apps/sim/lib/catalog/application/catalog-context.ts +++ b/apps/sim/lib/catalog/application/catalog-context.ts @@ -3,9 +3,6 @@ import { type BlockVisibilityState, getBlockVisibility } from '@/lib/core/config import { OrchestrationError } from '@/lib/core/orchestration/types' import { isIntegrationDeploymentAvailableForVisibility } from '@/lib/integrations/availability.server' import { allowedIntegrationTypes, principalUserId } from '@/lib/integrations/principal-scope.server' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import { resolveAccessControlBlockType } from '@/lib/permission-groups/integration-allowlist' -import { listCustomBlocksWithInputsForWorkspace } from '@/lib/workflows/custom-blocks/operations' import { type ActiveWorkspaceApplicationContext, loadActiveWorkspaceApplicationContext, @@ -14,6 +11,9 @@ import { withCustomBlockOverlay } from '@/blocks/custom/server-overlay' import type { BlockConfig } from '@/blocks/types' import { isHiddenUnder } from '@/blocks/visibility/context' import { withBlockVisibility } from '@/blocks/visibility/server-context' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import { resolveAccessControlBlockType } from '@/ee/access-control/lib/integration-allowlist' +import { listCustomBlocksWithInputsForWorkspace } from '@/ee/custom-blocks/lib/operations' /** * The per-caller, per-workspace state every catalog read is filtered through. diff --git a/apps/sim/lib/catalog/application/catalog-reads.test.ts b/apps/sim/lib/catalog/application/catalog-reads.test.ts index fa9b0b6f346..602382d1761 100644 --- a/apps/sim/lib/catalog/application/catalog-reads.test.ts +++ b/apps/sim/lib/catalog/application/catalog-reads.test.ts @@ -46,7 +46,7 @@ vi.mock('@/lib/core/config/block-visibility', () => ({ getBlockVisibility: mocks.getBlockVisibility, })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ listCustomBlocksWithInputsForWorkspace: mocks.listCustomBlocks, })) diff --git a/apps/sim/lib/catalog/application/operations.test.ts b/apps/sim/lib/catalog/application/operations.test.ts index 7b1ce4d4421..580c574f468 100644 --- a/apps/sim/lib/catalog/application/operations.test.ts +++ b/apps/sim/lib/catalog/application/operations.test.ts @@ -15,12 +15,12 @@ vi.mock('@sim/platform-authz/workspace', () => ({ resolveEffectiveWorkspacePermission: mocks.resolvePermission, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import { catalogOperations } from '@/lib/catalog/application/operations' import type { WorkspaceOperation } from '@/lib/core/application' import { authorizeWorkspaceOperation, PermissionGroupCapabilityError } from '@/lib/core/application' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' /** * Operation metadata is executable policy, not documentation: it decides which diff --git a/apps/sim/lib/compare/data/sim.ts b/apps/sim/lib/compare/data/sim.ts index 8bf43d4c589..92cf3eda88e 100644 --- a/apps/sim/lib/compare/data/sim.ts +++ b/apps/sim/lib/compare/data/sim.ts @@ -888,7 +888,7 @@ export const simProfile: CompetitorProfile = { asOf: '2026-07-02', }, { - url: 'https://github.com/simstudioai/sim/blob/main/apps/sim/lib/permission-groups/types.ts', + url: 'https://github.com/simstudioai/sim/blob/main/apps/sim/ee/access-control/lib/types.ts', label: 'Sim codebase: permission groups', asOf: '2026-07-04', }, @@ -935,7 +935,7 @@ export const simProfile: CompetitorProfile = { confidence: 'verified', sources: [ { - url: 'https://github.com/simstudioai/sim/blob/main/apps/sim/lib/permission-groups/types.ts', + url: 'https://github.com/simstudioai/sim/blob/main/apps/sim/ee/access-control/lib/types.ts', label: 'Sim codebase: PermissionGroupConfig (allowedModelProviders, deniedModels, deniedTools)', asOf: '2026-07-02', @@ -961,7 +961,7 @@ export const simProfile: CompetitorProfile = { asOf: '2026-07-02', }, { - url: 'https://github.com/simstudioai/sim/blob/main/apps/sim/lib/permission-groups/types.ts', + url: 'https://github.com/simstudioai/sim/blob/main/apps/sim/ee/access-control/lib/types.ts', label: 'Sim codebase: PermissionGroupConfig (allowedIntegrations)', asOf: '2026-07-02', }, diff --git a/apps/sim/lib/copilot/chat/payload.test.ts b/apps/sim/lib/copilot/chat/payload.test.ts index 0906a56a5b3..8f32d8094bd 100644 --- a/apps/sim/lib/copilot/chat/payload.test.ts +++ b/apps/sim/lib/copilot/chat/payload.test.ts @@ -137,7 +137,7 @@ vi.mock('@/lib/integrations/availability.server', () => ({ isOAuthServiceDeploymentAvailable: mockIsOAuthServiceDeploymentAvailable, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, })) diff --git a/apps/sim/lib/copilot/chat/payload.ts b/apps/sim/lib/copilot/chat/payload.ts index cec2b962bfe..9cc449bc805 100644 --- a/apps/sim/lib/copilot/chat/payload.ts +++ b/apps/sim/lib/copilot/chat/payload.ts @@ -161,7 +161,7 @@ export async function buildIntegrationToolSchemas( let permissionConfig: IntegrationGateConfig | null = null if (workspaceId) { const { resolvePermissionGroupConfig } = await import( - '@/lib/permission-groups/config-scope.server' + '@/ee/access-control/lib/config-scope.server' ) permissionConfig = await resolvePermissionGroupConfig(userId, workspaceId, undefined) } diff --git a/apps/sim/lib/copilot/chat/post.test.ts b/apps/sim/lib/copilot/chat/post.test.ts index 7e178dfe1e8..5c12e211b07 100644 --- a/apps/sim/lib/copilot/chat/post.test.ts +++ b/apps/sim/lib/copilot/chat/post.test.ts @@ -168,7 +168,7 @@ vi.mock('@/lib/copilot/resources/persistence', () => ({ persistChatResources, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/copilot/chat-status', () => ({ chatPubSub: { @@ -177,7 +177,7 @@ vi.mock('@/lib/copilot/chat-status', () => ({ })) import { chatOperations } from '@/lib/copilot/application/operations' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' import { handleUnifiedChatPost } from './post' describe('handleUnifiedChatPost', () => { diff --git a/apps/sim/lib/copilot/chat/post.ts b/apps/sim/lib/copilot/chat/post.ts index e19cb5ea417..15ea92b6216 100644 --- a/apps/sim/lib/copilot/chat/post.ts +++ b/apps/sim/lib/copilot/chat/post.ts @@ -66,8 +66,6 @@ import { import { prepareExecutionContext } from '@/lib/copilot/tools/handlers/context' import type { AtomicClaimResult } from '@/lib/core/idempotency' import { chatSendIdempotency } from '@/lib/core/idempotency' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' -import { capabilityRefusalResponse } from '@/lib/permission-groups/capability-response' import { captureServerEvent } from '@/lib/posthog/server' import { resolveWorkflowIdForUser } from '@/lib/workflows/utils' import { @@ -75,6 +73,8 @@ import { isWorkspaceAccessDeniedError, type PermissionType, } from '@/lib/workspaces/permissions/utils' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' +import { capabilityRefusalResponse } from '@/ee/access-control/lib/capability-response' import type { ChatContext } from '@/stores/panel' export const maxDuration = 3600 diff --git a/apps/sim/lib/copilot/chat/process-contents-log-projection.test.ts b/apps/sim/lib/copilot/chat/process-contents-log-projection.test.ts index 7c57beded3e..3e0a4cb698e 100644 --- a/apps/sim/lib/copilot/chat/process-contents-log-projection.test.ts +++ b/apps/sim/lib/copilot/chat/process-contents-log-projection.test.ts @@ -26,13 +26,13 @@ import { import { beforeEach, describe, expect, it, vi } from 'vitest' import type { ChatContext } from '@/stores/panel' -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) /** Folder listing is untouched by `@log` mentions; the real module drags in the block and trigger registries. */ vi.mock('@/lib/workflows/utils', () => workflowsUtilsMock) import { processContextsServer } from '@/lib/copilot/chat/process-contents' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' function queueRun(): void { dbChainMockFns.limit.mockResolvedValueOnce([ diff --git a/apps/sim/lib/copilot/chat/process-contents.test.ts b/apps/sim/lib/copilot/chat/process-contents.test.ts index cc0482b272b..5e8089887fb 100644 --- a/apps/sim/lib/copilot/chat/process-contents.test.ts +++ b/apps/sim/lib/copilot/chat/process-contents.test.ts @@ -45,7 +45,7 @@ const { vi.mock('@/blocks/registry', () => ({ getBlock, getBlockRegistry })) vi.mock('@/lib/copilot/block-visibility', () => ({ getBlockVisibilityForCopilot })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ getUserPermissionConfig })) +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig })) vi.mock('@/lib/integrations/availability.server', () => ({ isIntegrationDeploymentAvailableForVisibility: isIntegrationDeploymentAvailable, })) diff --git a/apps/sim/lib/copilot/chat/process-contents.ts b/apps/sim/lib/copilot/chat/process-contents.ts index 6b4207c6fc7..28f34bfb37f 100644 --- a/apps/sim/lib/copilot/chat/process-contents.ts +++ b/apps/sim/lib/copilot/chat/process-contents.ts @@ -41,12 +41,6 @@ import { toOverview } from '@/lib/logs/log-views' import type { TraceSpan } from '@/lib/logs/types' import { mcpService } from '@/lib/mcp/service' import { createMcpToolId } from '@/lib/mcp/utils' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import { - intersectIntegrationAllowlists, - resolveAccessControlBlockType, -} from '@/lib/permission-groups/integration-allowlist' import { getColumnId } from '@/lib/table/column-keys' import { getRowsByIds } from '@/lib/table/rows/service' import { getTableById } from '@/lib/table/service' @@ -56,6 +50,12 @@ import { getSkillById } from '@/lib/workflows/skills/operations' import { listFolders } from '@/lib/workflows/utils' import { readWorkspaceFileMetadata } from '@/lib/workspace-files/application/read-workspace-file-metadata' import { parseWorkspaceFileFolderDisplayPath } from '@/lib/workspace-files/folder-display-path' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' +import { + intersectIntegrationAllowlists, + resolveAccessControlBlockType, +} from '@/ee/access-control/lib/integration-allowlist' import { escapeRegExp } from '@/executor/constants' import type { ResolvedSecretTraceRegistry } from '@/executor/utils/resolved-secret-trace-registry' import type { BrowserTextSelection, ChatContext, TerminalTextSelection } from '@/stores/panel' diff --git a/apps/sim/lib/copilot/chat/workspace-context.ts b/apps/sim/lib/copilot/chat/workspace-context.ts index 3652b14547f..9ba808a912c 100644 --- a/apps/sim/lib/copilot/chat/workspace-context.ts +++ b/apps/sim/lib/copilot/chat/workspace-context.ts @@ -24,7 +24,6 @@ import { getAccessibleOAuthCredentials, } from '@/lib/credentials/environment' import { listWorkspaceSandboxes } from '@/lib/execution/remote-sandbox/workspace-sandboxes' -import { listCustomBlockSummariesForWorkspace } from '@/lib/workflows/custom-blocks/operations' import { listCustomTools } from '@/lib/workflows/custom-tools/operations' import { listSkillsForUser } from '@/lib/workflows/skills/operations' import { listAllWorkspaceFiles } from '@/lib/workspace-files/application/list-workspace-files' @@ -33,6 +32,7 @@ import { getUsersWithPermissions, type WorkspaceAccess, } from '@/lib/workspaces/permissions/utils' +import { listCustomBlockSummariesForWorkspace } from '@/ee/custom-blocks/lib/operations' const logger = createLogger('WorkspaceContext') diff --git a/apps/sim/lib/copilot/entitlements.ts b/apps/sim/lib/copilot/entitlements.ts index 402ea9169af..07c53fefcdd 100644 --- a/apps/sim/lib/copilot/entitlements.ts +++ b/apps/sim/lib/copilot/entitlements.ts @@ -2,8 +2,8 @@ import { createLogger } from '@sim/logger' import { getErrorMessage } from '@sim/utils/errors' import { LRUCache } from 'lru-cache' import { hasWorkspaceSandboxAccess } from '@/lib/billing/core/subscription' -import { isCustomBlocksEligible } from '@/lib/workflows/custom-blocks/operations' import { getWorkspaceWithOwner } from '@/lib/workspaces/permissions/utils' +import { isCustomBlocksEligible } from '@/ee/custom-blocks/lib/operations' const logger = createLogger('CopilotEntitlements') diff --git a/apps/sim/lib/copilot/integration-tool-projection.ts b/apps/sim/lib/copilot/integration-tool-projection.ts index de4efa9b5f5..27bcc4e747f 100644 --- a/apps/sim/lib/copilot/integration-tool-projection.ts +++ b/apps/sim/lib/copilot/integration-tool-projection.ts @@ -6,20 +6,20 @@ import { import type { BlockVisibilityState } from '@/lib/core/config/block-visibility' import { getAllowedIntegrationsFromEnv } from '@/lib/core/config/env-flags' import { isIntegrationDeploymentAvailableForVisibility } from '@/lib/integrations/availability.server' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' +import { BLOCK_REGISTRY } from '@/blocks/registry-maps' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' import { intersectIntegrationAllowlists, resolveAccessControlBlockType, toAccessControlAllowlist, -} from '@/lib/permission-groups/integration-allowlist' +} from '@/ee/access-control/lib/integration-allowlist' import { collectDeniedOperationIds, createToolAccessGate, getOperationOptionIds, type IsToolAllowed, NO_DENIED_OPERATIONS, -} from '@/lib/permission-groups/operation-access' -import { BLOCK_REGISTRY } from '@/blocks/registry-maps' +} from '@/ee/access-control/lib/operation-access' /** The slice of a permission group the integration gate reads. */ export type IntegrationGateConfig = Pick< diff --git a/apps/sim/lib/copilot/integration-tools.ts b/apps/sim/lib/copilot/integration-tools.ts index c8190886bc2..f345a8b8b57 100644 --- a/apps/sim/lib/copilot/integration-tools.ts +++ b/apps/sim/lib/copilot/integration-tools.ts @@ -1,7 +1,7 @@ import type { BlockVisibilityState } from '@/lib/core/config/block-visibility' -import type { IsToolAllowed } from '@/lib/permission-groups/operation-access' import { BLOCK_REGISTRY } from '@/blocks/registry-maps' import { isHiddenUnder } from '@/blocks/visibility/context' +import type { IsToolAllowed } from '@/ee/access-control/lib/operation-access' import { tools as toolRegistry } from '@/tools/registry' import type { ExecutableToolConfig } from '@/tools/types' import { getLatestVersionTools, stripVersionSuffix } from '@/tools/utils' diff --git a/apps/sim/lib/copilot/request/lifecycle/run.test.ts b/apps/sim/lib/copilot/request/lifecycle/run.test.ts index 5e698416cba..fed4128c362 100644 --- a/apps/sim/lib/copilot/request/lifecycle/run.test.ts +++ b/apps/sim/lib/copilot/request/lifecycle/run.test.ts @@ -114,7 +114,7 @@ vi.mock('@/lib/copilot/persistence/tool-permission/auto-allow', () => ({ addChatAutoAllowedTool: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, })) diff --git a/apps/sim/lib/copilot/request/lifecycle/run.ts b/apps/sim/lib/copilot/request/lifecycle/run.ts index 1e48ca9e1d9..cd4d4a10dfd 100644 --- a/apps/sim/lib/copilot/request/lifecycle/run.ts +++ b/apps/sim/lib/copilot/request/lifecycle/run.ts @@ -64,8 +64,8 @@ import { getMothershipBaseURL, getMothershipSourceEnvHeaders } from '@/lib/copil import { prepareExecutionContext } from '@/lib/copilot/tools/handlers/context' import { env } from '@/lib/core/config/env' import { isCopilotToolPermissionsEnabled, isHosted } from '@/lib/core/config/env-flags' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' import { filterModelSafeWorkspaceFileAttachments } from '@/lib/uploads/contexts/workspace/workspace-file-secret-provenance' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' import { refuseResolvedSecretProjection } from '@/executor/utils/resolved-secret-projection-refusal' import type { ResolvedSecretTraceRegistry } from '@/executor/utils/resolved-secret-trace-registry' diff --git a/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.test.ts b/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.test.ts index d79a2f6c09d..f81c58f6e9e 100644 --- a/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.test.ts +++ b/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.test.ts @@ -65,7 +65,7 @@ vi.mock('@/lib/uploads/utils/file-utils', () => ({ isImageFileType: (type: string) => type.startsWith('image/'), })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => { +vi.mock('@/ee/custom-blocks/lib/operations', () => { class CustomBlockValidationError extends Error {} return { CustomBlockValidationError, diff --git a/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.ts b/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.ts index 45158307b63..eb5eef83628 100644 --- a/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.ts +++ b/apps/sim/lib/copilot/tools/handlers/deployment/custom-block.ts @@ -13,6 +13,9 @@ import { canonicalizeVfsPath } from '@/lib/copilot/vfs/path-utils' import { buildStorageKeySegment } from '@/lib/uploads/core/storage-key' import { uploadFile } from '@/lib/uploads/core/storage-service' import { isImageFileType } from '@/lib/uploads/utils/file-utils' +import { fileOperations } from '@/lib/workspace-files/application/operations' +import { readWorkspaceFileContent } from '@/lib/workspace-files/application/read-workspace-file-content' +import { getWorkspaceWithOwner } from '@/lib/workspaces/permissions/utils' import { CustomBlockValidationError, type CustomBlockWithInputs, @@ -22,10 +25,7 @@ import { isCustomBlocksEligibleForOrganization, publishCustomBlock, updateCustomBlock, -} from '@/lib/workflows/custom-blocks/operations' -import { fileOperations } from '@/lib/workspace-files/application/operations' -import { readWorkspaceFileContent } from '@/lib/workspace-files/application/read-workspace-file-content' -import { getWorkspaceWithOwner } from '@/lib/workspaces/permissions/utils' +} from '@/ee/custom-blocks/lib/operations' import { ensureWorkflowAccess } from '../access' import type { DeployCustomBlockParams } from '../param-types' diff --git a/apps/sim/lib/copilot/tools/handlers/integration-tools.ts b/apps/sim/lib/copilot/tools/handlers/integration-tools.ts index 35a3e66ab23..d99b4e2404e 100644 --- a/apps/sim/lib/copilot/tools/handlers/integration-tools.ts +++ b/apps/sim/lib/copilot/tools/handlers/integration-tools.ts @@ -1,7 +1,7 @@ import { getBlockVisibilityForCopilot } from '@/lib/copilot/block-visibility' import { projectIntegrationToolsForViewer } from '@/lib/copilot/integration-tool-projection' import type { ExecutionContext, ToolCallResult } from '@/lib/copilot/request/types' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' import { stripVersionSuffix } from '@/tools/utils' export async function executeListIntegrationTools( diff --git a/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-projection.test.ts b/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-projection.test.ts index a4e5ecc4297..82a83716cdc 100644 --- a/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-projection.test.ts +++ b/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-projection.test.ts @@ -25,7 +25,7 @@ const mocks = vi.hoisted(() => ({ isDeploymentAvailable: vi.fn(() => true), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) diff --git a/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.test.ts b/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.test.ts index 3fb868b0731..54627ba38f3 100644 --- a/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.test.ts +++ b/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.test.ts @@ -9,7 +9,7 @@ const { mockGetUserPermissionConfig, mockIsIntegrationDeploymentAvailable } = vi mockIsIntegrationDeploymentAvailable: vi.fn(() => true), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, })) diff --git a/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.ts b/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.ts index 0c0796bc55e..ad6c0e4f14b 100644 --- a/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.ts +++ b/apps/sim/lib/copilot/tools/server/blocks/get-blocks-metadata-tool.ts @@ -17,22 +17,22 @@ import type { BaseServerTool } from '@/lib/copilot/tools/server/base-tool' import { getAllowedIntegrationsFromEnv, isHosted } from '@/lib/core/config/env-flags' import { isIntegrationDeploymentAvailableForVisibility } from '@/lib/integrations/availability.server' import { getServiceAccountProviderForProviderId } from '@/lib/oauth/utils' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' +import { getBlock } from '@/blocks/registry' +import { AuthMode, type BlockConfig, type SubBlockConfig } from '@/blocks/types' +import { isHiddenUnder, overlayVisibility } from '@/blocks/visibility/context' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' import { intersectIntegrationAllowlists, resolveAccessControlBlockType, -} from '@/lib/permission-groups/integration-allowlist' +} from '@/ee/access-control/lib/integration-allowlist' import { collectDeniedOperationIds, createToolAccessGate, type IsToolAllowed, OPERATION_SUBBLOCK_ID, type OperationGateBlock, -} from '@/lib/permission-groups/operation-access' -import { getBlock } from '@/blocks/registry' -import { AuthMode, type BlockConfig, type SubBlockConfig } from '@/blocks/types' -import { isHiddenUnder, overlayVisibility } from '@/blocks/visibility/context' +} from '@/ee/access-control/lib/operation-access' /** * The block shape this tool reports, projected by the shared catalog projection diff --git a/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.test.ts b/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.test.ts index f93858ab953..231ce7d4c23 100644 --- a/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.test.ts +++ b/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.test.ts @@ -21,7 +21,7 @@ vi.mock('@/blocks/registry', () => ({ getBlock: mockGetBlock, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, })) diff --git a/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.ts b/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.ts index 389dbc334d2..7d23b0ddfcc 100644 --- a/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.ts +++ b/apps/sim/lib/copilot/tools/server/blocks/get-trigger-blocks.ts @@ -3,14 +3,14 @@ import { z } from 'zod' import type { BaseServerTool } from '@/lib/copilot/tools/server/base-tool' import { getAllowedIntegrationsFromEnv } from '@/lib/core/config/env-flags' import { isIntegrationDeploymentAvailableForVisibility } from '@/lib/integrations/availability.server' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' +import { getAllBlocks } from '@/blocks/registry' +import { overlayVisibility } from '@/blocks/visibility/context' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' import { intersectIntegrationAllowlists, resolveAccessControlBlockType, -} from '@/lib/permission-groups/integration-allowlist' -import { getAllBlocks } from '@/blocks/registry' -import { overlayVisibility } from '@/blocks/visibility/context' +} from '@/ee/access-control/lib/integration-allowlist' export const GetTriggerBlocksInput = z.object({}) export const GetTriggerBlocksResult = z.object({ diff --git a/apps/sim/lib/copilot/tools/server/router.ts b/apps/sim/lib/copilot/tools/server/router.ts index 025a1195123..d6a44f610fa 100644 --- a/apps/sim/lib/copilot/tools/server/router.ts +++ b/apps/sim/lib/copilot/tools/server/router.ts @@ -62,9 +62,9 @@ import { setEnvironmentVariablesServerTool } from '@/lib/copilot/tools/server/us import { editWorkflowServerTool } from '@/lib/copilot/tools/server/workflow/edit-workflow' import { queryLogsServerTool } from '@/lib/copilot/tools/server/workflow/query-logs' import { OrchestrationError } from '@/lib/core/orchestration/types' -import { listCustomBlocksWithInputsForWorkspace } from '@/lib/workflows/custom-blocks/operations' import { withCustomBlockOverlay } from '@/blocks/custom/server-overlay' import { withBlockVisibility } from '@/blocks/visibility/server-context' +import { listCustomBlocksWithInputsForWorkspace } from '@/ee/custom-blocks/lib/operations' export type ExecuteResponseSuccess = z.output diff --git a/apps/sim/lib/copilot/tools/server/user/get-credentials.test.ts b/apps/sim/lib/copilot/tools/server/user/get-credentials.test.ts index 2b8aebdf221..96444fdeab9 100644 --- a/apps/sim/lib/copilot/tools/server/user/get-credentials.test.ts +++ b/apps/sim/lib/copilot/tools/server/user/get-credentials.test.ts @@ -80,7 +80,7 @@ vi.mock('@/lib/core/config/env-flags', () => ({ getAllowedIntegrationsFromEnv: vi.fn(() => null), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: getUserPermissionConfigMock, })) diff --git a/apps/sim/lib/copilot/tools/server/user/get-credentials.ts b/apps/sim/lib/copilot/tools/server/user/get-credentials.ts index 9b5398201c5..7beb910029c 100644 --- a/apps/sim/lib/copilot/tools/server/user/get-credentials.ts +++ b/apps/sim/lib/copilot/tools/server/user/get-credentials.ts @@ -17,10 +17,10 @@ import { credentialProviderMatchesService, getAllOAuthServices, } from '@/lib/oauth' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import { intersectIntegrationAllowlists } from '@/lib/permission-groups/integration-allowlist' import { checkWorkspaceAccess, type WorkspaceAccess } from '@/lib/workspaces/permissions/utils' import { overlayVisibility } from '@/blocks/visibility/context' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' +import { intersectIntegrationAllowlists } from '@/ee/access-control/lib/integration-allowlist' interface GetCredentialsParams { workflowId?: string diff --git a/apps/sim/lib/copilot/vfs/serializers.ts b/apps/sim/lib/copilot/vfs/serializers.ts index 40d2d5a04cd..ca89c5a44be 100644 --- a/apps/sim/lib/copilot/vfs/serializers.ts +++ b/apps/sim/lib/copilot/vfs/serializers.ts @@ -14,13 +14,13 @@ import { import { type FilterFieldType, getOperatorsForFieldType } from '@/lib/knowledge/filters/types' import { SLACK_CUSTOM_BOT_PROVIDER_ID } from '@/lib/oauth/types' import { getServiceAccountProviderForProviderId } from '@/lib/oauth/utils' -import { type IsToolAllowed, OPERATION_SUBBLOCK_ID } from '@/lib/permission-groups/operation-access' import { isRetryEligibleBlock } from '@/lib/workflows/blocks/retry-eligibility' import { isSubBlockHidden } from '@/lib/workflows/subblocks/visibility' import { getBlock } from '@/blocks' import { isCustomBlockType } from '@/blocks/custom/build-config' import type { BlockConfig, SubBlockConfig } from '@/blocks/types' import { isHiddenUnder } from '@/blocks/visibility/context' +import { type IsToolAllowed, OPERATION_SUBBLOCK_ID } from '@/ee/access-control/lib/operation-access' import { DYNAMIC_MODEL_PROVIDERS, PROVIDER_DEFINITIONS, diff --git a/apps/sim/lib/copilot/vfs/workspace-vfs.test.ts b/apps/sim/lib/copilot/vfs/workspace-vfs.test.ts index 1d71c652022..e228935de79 100644 --- a/apps/sim/lib/copilot/vfs/workspace-vfs.test.ts +++ b/apps/sim/lib/copilot/vfs/workspace-vfs.test.ts @@ -38,7 +38,7 @@ vi.mock('@/lib/workspace-files/application/read-workspace-file-content', () => ( readWorkspaceFileContent: { execute: readWorkspaceFileContentExecute }, })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ isCustomBlocksEligible, listCustomBlocksWithInputsForWorkspace, })) diff --git a/apps/sim/lib/copilot/vfs/workspace-vfs.ts b/apps/sim/lib/copilot/vfs/workspace-vfs.ts index eec6cca7c2a..eb2924cd6cb 100644 --- a/apps/sim/lib/copilot/vfs/workspace-vfs.ts +++ b/apps/sim/lib/copilot/vfs/workspace-vfs.ts @@ -142,18 +142,6 @@ import { listKnowledgeBases, } from '@/lib/knowledge/application/knowledge-bases' import { validateMermaidSource } from '@/lib/mermaid/validate' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import { getActivePermissionGroupRestrictions } from '@/lib/permission-groups/features' -import { - intersectIntegrationAllowlists, - toAccessControlAllowlist, -} from '@/lib/permission-groups/integration-allowlist' -import type { IsToolAllowed } from '@/lib/permission-groups/operation-access' -import { - listOrganizationWorkspaceRefs, - listPermissionGroupRoster, -} from '@/lib/permission-groups/queries' import { listTables } from '@/lib/table/service' import { listTableViewsByWorkspace, @@ -168,10 +156,6 @@ import type { WorkspaceFileSecretProvenanceIdentity, } from '@/lib/uploads/contexts/workspace/workspace-file-secret-provenance' import { isImageFileType, resolveEffectiveMimeType } from '@/lib/uploads/utils/file-utils' -import { - type CustomBlockWithInputs, - listCustomBlocksWithInputsForWorkspace, -} from '@/lib/workflows/custom-blocks/operations' import { getCustomToolById } from '@/lib/workflows/custom-tools/operations' import { checkNeedsRedeployment } from '@/lib/workflows/deployment-status' import { collectWorkflowFieldIssues, lintEditedWorkflowState } from '@/lib/workflows/editing/lint' @@ -205,7 +189,23 @@ import { BLOCK_REGISTRY } from '@/blocks/registry-maps' import type { BlockConfig, BlockIcon } from '@/blocks/types' import { isHiddenUnder, overlayVisibility } from '@/blocks/visibility/context' import { CONNECTOR_REGISTRY } from '@/connectors/registry.server' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' +import { getActivePermissionGroupRestrictions } from '@/ee/access-control/lib/features' +import { + intersectIntegrationAllowlists, + toAccessControlAllowlist, +} from '@/ee/access-control/lib/integration-allowlist' +import type { IsToolAllowed } from '@/ee/access-control/lib/operation-access' +import { + listOrganizationWorkspaceRefs, + listPermissionGroupRoster, +} from '@/ee/access-control/lib/queries' import { resolveVerifiedUserAccessControlContext } from '@/ee/access-control/utils/permission-check' +import { + type CustomBlockWithInputs, + listCustomBlocksWithInputsForWorkspace, +} from '@/ee/custom-blocks/lib/operations' import { isForkingAvailableForWorkspace } from '@/ee/workspace-forking/lib/lineage/authz' import { getForkChildren, getForkParent } from '@/ee/workspace-forking/lib/lineage/lineage' import { loadForkBlockMap } from '@/ee/workspace-forking/lib/mapping/block-map-store' diff --git a/apps/sim/lib/core/application/index.ts b/apps/sim/lib/core/application/index.ts index 75d6ba3ce2d..93ba94c755f 100644 --- a/apps/sim/lib/core/application/index.ts +++ b/apps/sim/lib/core/application/index.ts @@ -52,4 +52,4 @@ export { type PrincipalForOperation, type WorkspaceOperation, } from '@/lib/core/application/workspace-operation' -export { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' +export { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' diff --git a/apps/sim/lib/core/application/operation.ts b/apps/sim/lib/core/application/operation.ts index dc712d55a50..cb48cc2603c 100644 --- a/apps/sim/lib/core/application/operation.ts +++ b/apps/sim/lib/core/application/operation.ts @@ -3,7 +3,7 @@ import type { OrchestrationRequestContext } from '@/lib/core/orchestration/types import { CAPABILITY_RULES, type StaticPermissionGroupCapability, -} from '@/lib/permission-groups/capabilities' +} from '@/ee/access-control/lib/capabilities' /** * A capability that governs the PRINCIPAL rather than any one operation. diff --git a/apps/sim/lib/core/application/workspace-authorization.test.ts b/apps/sim/lib/core/application/workspace-authorization.test.ts index b19260d860b..b0d30508594 100644 --- a/apps/sim/lib/core/application/workspace-authorization.test.ts +++ b/apps/sim/lib/core/application/workspace-authorization.test.ts @@ -24,7 +24,7 @@ vi.mock('@sim/platform-authz/workspace', () => ({ resolveEffectiveWorkspacePermission: mocks.resolvePermission, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import { authorizeWorkspaceOperation, @@ -38,7 +38,7 @@ import { WorkspaceApiKeyAuthorizationError, WorkspaceApiKeyScopeAuthorizationError, } from '@/lib/core/application' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const writeOperation = defineWorkspaceOperation({ id: 'test.write', diff --git a/apps/sim/lib/core/application/workspace-authorization.ts b/apps/sim/lib/core/application/workspace-authorization.ts index 2b834162911..235dc575a1d 100644 --- a/apps/sim/lib/core/application/workspace-authorization.ts +++ b/apps/sim/lib/core/application/workspace-authorization.ts @@ -18,8 +18,8 @@ import { OrchestrationError } from '@/lib/core/orchestration/types' import { assertWorkspaceCapability, capabilityDeniedBy, -} from '@/lib/permission-groups/capability-assertions' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' +} from '@/ee/access-control/lib/capability-assertions' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' /** * The person whose permission group governs `principal`, or `null` when no diff --git a/apps/sim/lib/core/utils/with-route-handler.ts b/apps/sim/lib/core/utils/with-route-handler.ts index eb6c91d1c96..e5c70f4c9bc 100644 --- a/apps/sim/lib/core/utils/with-route-handler.ts +++ b/apps/sim/lib/core/utils/with-route-handler.ts @@ -5,7 +5,7 @@ import { NextResponse } from 'next/server' import { getRateLimitHeaders } from '@/lib/api/server/rate-limit-context' import { HttpError } from '@/lib/core/utils/http-error' import { generateRequestId } from '@/lib/core/utils/request' -import { withPermissionGroupScope } from '@/lib/permission-groups/request-scope.server' +import { withPermissionGroupScope } from '@/ee/access-control/lib/request-scope.server' const logger = createLogger('RouteHandler') diff --git a/apps/sim/lib/credentials/application/authorized-user-use-case.ts b/apps/sim/lib/credentials/application/authorized-user-use-case.ts index 77010182ee9..c4138ba6ae7 100644 --- a/apps/sim/lib/credentials/application/authorized-user-use-case.ts +++ b/apps/sim/lib/credentials/application/authorized-user-use-case.ts @@ -5,8 +5,8 @@ import type { OperationUseCase } from '@/lib/core/application' import type { OrchestrationRequestContext } from '@/lib/core/orchestration/types' import { OrchestrationError } from '@/lib/core/orchestration/types' import type { CredentialUserOperation } from '@/lib/credentials/application/operations' -import { refuseCapability } from '@/lib/permission-groups/capabilities' -import { isOrganizationCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' +import { refuseCapability } from '@/ee/access-control/lib/capabilities' +import { isOrganizationCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' export interface CredentialUserAuditEntry { workspaceId: string | null diff --git a/apps/sim/lib/credentials/application/capability-gate.test.ts b/apps/sim/lib/credentials/application/capability-gate.test.ts index 3e3f3b4ce2c..44fc346866c 100644 --- a/apps/sim/lib/credentials/application/capability-gate.test.ts +++ b/apps/sim/lib/credentials/application/capability-gate.test.ts @@ -33,7 +33,7 @@ vi.mock('@/lib/billing/organizations/membership', () => ({ getUserOrganization: mockGetUserOrganization, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: vi.fn(), getUserPermissionConfigForOrganization: mockGetOrgPermissionConfig, resolveVerifiedUserAccessControlContext: vi.fn(), @@ -51,11 +51,11 @@ vi.mock('@/lib/credentials/oauth-accounts', () => ({ OAuthProviderRevocationError: class OAuthProviderRevocationError extends Error {}, })) -import { capabilityRefusal } from '@/lib/permission-groups/capability-assertions' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { GET as listConnectedAccounts } from '@/app/api/auth/accounts/route' import { GET as listConnections } from '@/app/api/auth/oauth/connections/route' import { POST as disconnect } from '@/app/api/auth/oauth/disconnect/route' +import { capabilityRefusal } from '@/ee/access-control/lib/capability-assertions' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const USER_ID = 'user-1' const ORGANIZATION_ID = 'org-1' diff --git a/apps/sim/lib/credentials/application/connection-target.test.ts b/apps/sim/lib/credentials/application/connection-target.test.ts index fc6cef25692..55d4cf0b3af 100644 --- a/apps/sim/lib/credentials/application/connection-target.test.ts +++ b/apps/sim/lib/credentials/application/connection-target.test.ts @@ -10,7 +10,7 @@ const mocks = vi.hoisted(() => ({ assertWorkspaceCapability: vi.fn(), })) -vi.mock('@/lib/permission-groups/capability-assertions', () => ({ +vi.mock('@/ee/access-control/lib/capability-assertions', () => ({ assertWorkspaceCapability: mocks.assertWorkspaceCapability, })) diff --git a/apps/sim/lib/credentials/application/connection-target.ts b/apps/sim/lib/credentials/application/connection-target.ts index c30d685d38a..832fd7ac287 100644 --- a/apps/sim/lib/credentials/application/connection-target.ts +++ b/apps/sim/lib/credentials/application/connection-target.ts @@ -11,8 +11,8 @@ import { } from '@/lib/credentials/application/provider-catalog' import { getWorkspaceCredential } from '@/lib/credentials/queries' import { credentialProviderMatchesService } from '@/lib/oauth/utils' -import { assertWorkspaceCapability } from '@/lib/permission-groups/capability-assertions' import type { ActiveWorkspaceApplicationContext } from '@/lib/workspaces/application/workspace-context' +import { assertWorkspaceCapability } from '@/ee/access-control/lib/capability-assertions' export interface ResolvedCredentialConnectionTarget { provider: OAuthCredentialProviderCatalogEntry diff --git a/apps/sim/lib/credentials/application/credential-crud.test.ts b/apps/sim/lib/credentials/application/credential-crud.test.ts index 0ba3a46a136..b00e488279c 100644 --- a/apps/sim/lib/credentials/application/credential-crud.test.ts +++ b/apps/sim/lib/credentials/application/credential-crud.test.ts @@ -44,7 +44,7 @@ vi.mock('@/lib/credentials/orchestration', () => ({ createCredentialRecord: mocks.createRecord, isProviderOutageCode: () => false, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/credentials/oauth', () => ({ syncWorkspaceOAuthCredentialsForUser: vi.fn() })) vi.mock('@/lib/posthog/server', () => ({ captureServerEvent: vi.fn() })) vi.mock('@/lib/workspaces/permissions/utils', () => ({ checkWorkspaceAccess: vi.fn() })) @@ -56,7 +56,7 @@ import { updateWorkspaceCredentialUseCase, } from '@/lib/credentials/application/credential-crud' import { credentialOperations } from '@/lib/credentials/application/operations' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const WORKSPACE_ID = 'workspace-1' const OTHER_WORKSPACE_ID = 'workspace-2' diff --git a/apps/sim/lib/credentials/application/credential-crud.ts b/apps/sim/lib/credentials/application/credential-crud.ts index 13938cb9abd..4635cf886ef 100644 --- a/apps/sim/lib/credentials/application/credential-crud.ts +++ b/apps/sim/lib/credentials/application/credential-crud.ts @@ -33,10 +33,10 @@ import { } from '@/lib/credentials/queries' import { getServiceAccountGatingBlockType } from '@/lib/credentials/service-account-provider-ids' import { createIntegrationCredentialVisibility } from '@/lib/integrations/credential-visibility.server' -import { assertWorkspaceCapability } from '@/lib/permission-groups/capability-assertions' import { captureServerEvent } from '@/lib/posthog/server' import { loadActiveWorkspaceApplicationContext } from '@/lib/workspaces/application/workspace-context' import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' +import { assertWorkspaceCapability } from '@/ee/access-control/lib/capability-assertions' export class CredentialProviderOperationError extends OrchestrationError { constructor( diff --git a/apps/sim/lib/credentials/application/credential-members.ts b/apps/sim/lib/credentials/application/credential-members.ts index 48736ffceae..ac672d126e2 100644 --- a/apps/sim/lib/credentials/application/credential-members.ts +++ b/apps/sim/lib/credentials/application/credential-members.ts @@ -16,8 +16,8 @@ import { removeCredentialMember, upsertCredentialMember, } from '@/lib/credentials/members' -import { isWorkspaceCapabilityWithheld } from '@/lib/permission-groups/capability-assertions' import { captureServerEvent } from '@/lib/posthog/server' +import { isWorkspaceCapabilityWithheld } from '@/ee/access-control/lib/capability-assertions' interface CredentialMemberResourceInput { credentialId: string diff --git a/apps/sim/lib/credentials/application/membership-projection.test.ts b/apps/sim/lib/credentials/application/membership-projection.test.ts index 9f92845b680..b328e552e71 100644 --- a/apps/sim/lib/credentials/application/membership-projection.test.ts +++ b/apps/sim/lib/credentials/application/membership-projection.test.ts @@ -25,13 +25,13 @@ vi.mock('@/lib/billing/organizations/membership', () => ({ getUserOrganization: mockGetUserOrganization, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: vi.fn(), getUserPermissionConfigForOrganization: mockGetOrgPermissionConfig, resolveVerifiedUserAccessControlContext: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/credentials/members', () => ({ leaveCredentialMembership: mockLeave, @@ -41,8 +41,8 @@ vi.mock('@/lib/credentials/members', () => ({ upsertCredentialMember: vi.fn(), })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { DELETE, GET } from '@/app/api/credentials/memberships/route' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const USER_ID = 'user-1' const GOVERNED_WORKSPACE = 'workspace-governed' diff --git a/apps/sim/lib/credentials/application/operations.ts b/apps/sim/lib/credentials/application/operations.ts index 43f773bf7ce..9120990cea1 100644 --- a/apps/sim/lib/credentials/application/operations.ts +++ b/apps/sim/lib/credentials/application/operations.ts @@ -1,7 +1,7 @@ import type { ApplicationOperation, OperationDeclarableCapability } from '@/lib/core/application' import { defineWorkspaceOperation, type WorkspaceOperation } from '@/lib/core/application' -import { CAPABILITY_RULES } from '@/lib/permission-groups/capabilities' import { CREDENTIAL_GROUP_CREDENTIAL_USE_ACTION } from '@/lib/resource-policies/registry' +import { CAPABILITY_RULES } from '@/ee/access-control/lib/capabilities' export type CredentialRole = 'member' | 'admin' diff --git a/apps/sim/lib/credentials/application/provider-catalog.test.ts b/apps/sim/lib/credentials/application/provider-catalog.test.ts index f76c2c097ef..8a123be60f7 100644 --- a/apps/sim/lib/credentials/application/provider-catalog.test.ts +++ b/apps/sim/lib/credentials/application/provider-catalog.test.ts @@ -20,7 +20,7 @@ vi.mock('@/lib/core/config/env-flags', () => ({ getAllowedIntegrationsFromEnv: mocks.getAllowedIntegrationsFromEnv, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) @@ -29,7 +29,7 @@ vi.mock('@/lib/permission-groups/resolve.server', () => ({ * this stub keeps the intersection semantics without the map, because the ids * used here are fixtures rather than real block types. */ -vi.mock('@/lib/permission-groups/integration-allowlist', () => { +vi.mock('@/ee/access-control/lib/integration-allowlist', () => { const intersect = ( permissionGroup: readonly string[] | null, deployment: readonly string[] | null diff --git a/apps/sim/lib/data-drains/destinations/registry.ts b/apps/sim/lib/data-drains/destinations/registry.ts deleted file mode 100644 index d0b775289aa..00000000000 --- a/apps/sim/lib/data-drains/destinations/registry.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { azureBlobDestination } from '@/lib/data-drains/destinations/azure_blob' -import { bigqueryDestination } from '@/lib/data-drains/destinations/bigquery' -import { datadogDestination } from '@/lib/data-drains/destinations/datadog' -import { gcsDestination } from '@/lib/data-drains/destinations/gcs' -import { s3Destination } from '@/lib/data-drains/destinations/s3' -import { snowflakeDestination } from '@/lib/data-drains/destinations/snowflake' -import { webhookDestination } from '@/lib/data-drains/destinations/webhook' -import type { DestinationType, DrainDestination } from '@/lib/data-drains/types' - -export const DESTINATION_REGISTRY = { - s3: s3Destination, - gcs: gcsDestination, - azure_blob: azureBlobDestination, - datadog: datadogDestination, - bigquery: bigqueryDestination, - snowflake: snowflakeDestination, - webhook: webhookDestination, -} as const satisfies Record - -export function getDestination(type: DestinationType): DrainDestination { - return DESTINATION_REGISTRY[type] -} diff --git a/apps/sim/lib/data-drains/sources/registry.ts b/apps/sim/lib/data-drains/sources/registry.ts deleted file mode 100644 index a75073e46de..00000000000 --- a/apps/sim/lib/data-drains/sources/registry.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { auditLogsSource } from '@/lib/data-drains/sources/audit-logs' -import { copilotChatsSource } from '@/lib/data-drains/sources/copilot-chats' -import { copilotRunsSource } from '@/lib/data-drains/sources/copilot-runs' -import { jobLogsSource } from '@/lib/data-drains/sources/job-logs' -import { workflowLogsSource } from '@/lib/data-drains/sources/workflow-logs' -import type { DrainSource, SourceType } from '@/lib/data-drains/types' - -export const SOURCE_REGISTRY = { - workflow_logs: workflowLogsSource, - job_logs: jobLogsSource, - audit_logs: auditLogsSource, - copilot_chats: copilotChatsSource, - copilot_runs: copilotRunsSource, -} as const satisfies Record - -export function getSource(type: SourceType): DrainSource { - return SOURCE_REGISTRY[type] -} diff --git a/apps/sim/lib/integrations/principal-scope.server.ts b/apps/sim/lib/integrations/principal-scope.server.ts index 3e239092b15..b76fb288323 100644 --- a/apps/sim/lib/integrations/principal-scope.server.ts +++ b/apps/sim/lib/integrations/principal-scope.server.ts @@ -1,7 +1,7 @@ import type { Principal } from '@sim/auth/principal' import { getAllowedIntegrationsFromEnv } from '@/lib/core/config/env-flags' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' -import { intersectAccessControlAllowlists } from '@/lib/permission-groups/integration-allowlist' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' +import { intersectAccessControlAllowlists } from '@/ee/access-control/lib/integration-allowlist' /** * The workspace integration gate, shared by every catalog that projects diff --git a/apps/sim/lib/invitations/core.ts b/apps/sim/lib/invitations/core.ts index f0cb61d32c2..8c51a865ed8 100644 --- a/apps/sim/lib/invitations/core.ts +++ b/apps/sim/lib/invitations/core.ts @@ -18,7 +18,6 @@ import { isOrgAdminRole, PERMISSION_RANK, type PermissionType } from '@sim/platf import { generateId } from '@sim/utils/id' import { normalizeEmail } from '@sim/utils/string' import { and, asc, count, eq, inArray, lte, sql } from 'drizzle-orm' -import { applySessionPolicyToNewMember } from '@/lib/auth/session-policy' import { getOrganizationSubscription } from '@/lib/billing/core/billing' import { getHighestPriorityPersonalSubscription } from '@/lib/billing/core/plan' import { syncUsageLimitsFromSubscription } from '@/lib/billing/core/usage' @@ -46,6 +45,7 @@ import { } from '@/lib/workspaces/organization-workspaces' import { getWorkspaceWithOwner, type WorkspaceWithOwner } from '@/lib/workspaces/permissions/utils' import { getInvitePlanCategoryForUser } from '@/lib/workspaces/policy' +import { applySessionPolicyToNewMember } from '@/ee/session-policy/lib/session-policy' const logger = createLogger('InvitationCore') diff --git a/apps/sim/lib/knowledge/application/connectors.test.ts b/apps/sim/lib/knowledge/application/connectors.test.ts index 6425cb7bf07..c297f17a2e2 100644 --- a/apps/sim/lib/knowledge/application/connectors.test.ts +++ b/apps/sim/lib/knowledge/application/connectors.test.ts @@ -73,7 +73,7 @@ vi.mock('@/lib/oauth/credential-service', () => ({ refreshAccessTokenIfNeeded: mocks.refreshToken, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) @@ -94,8 +94,8 @@ import { updateKnowledgeConnector, updateKnowledgeConnectorDocuments, } from '@/lib/knowledge/application/connectors' -import { capabilityRefusal } from '@/lib/permission-groups/capability-assertions' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { capabilityRefusal } from '@/ee/access-control/lib/capability-assertions' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const crossWorkspaceContext = { workspaceId: 'workspace-b', diff --git a/apps/sim/lib/knowledge/application/connectors.ts b/apps/sim/lib/knowledge/application/connectors.ts index 729ce72b0dc..789ae843fb4 100644 --- a/apps/sim/lib/knowledge/application/connectors.ts +++ b/apps/sim/lib/knowledge/application/connectors.ts @@ -66,9 +66,9 @@ import type { import { isMemberSyncStatus } from '@/lib/knowledge/types' import { credentialProviderMatchesService, type ServiceProviderIdentity } from '@/lib/oauth' import { refreshAccessTokenIfNeeded } from '@/lib/oauth/credential-service' -import { CAPABILITY_RULES, refuseCapability } from '@/lib/permission-groups/capabilities' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' import { getConnectorMeta } from '@/connectors/registry' +import { CAPABILITY_RULES, refuseCapability } from '@/ee/access-control/lib/capabilities' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' interface KnowledgeConnectorApplicationInput { assertedWorkspaceId?: string diff --git a/apps/sim/lib/knowledge/application/sim-search.test.ts b/apps/sim/lib/knowledge/application/sim-search.test.ts index 8ec011f4310..f70dda62602 100644 --- a/apps/sim/lib/knowledge/application/sim-search.test.ts +++ b/apps/sim/lib/knowledge/application/sim-search.test.ts @@ -67,7 +67,7 @@ vi.mock('@/lib/knowledge/application/connector-access', () => ({ startKnowledgeConnectorMemberEnrollment: { execute: mocks.enroll }, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) @@ -102,7 +102,7 @@ vi.mock('@/connectors/registry', () => ({ })) import { connectSimSearchConnector } from '@/lib/knowledge/application/sim-search' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const workspaceContext = { workspaceId: 'workspace-1', diff --git a/apps/sim/lib/logs/application/list-logs.test.ts b/apps/sim/lib/logs/application/list-logs.test.ts index 2e534ab544b..fc233426a4c 100644 --- a/apps/sim/lib/logs/application/list-logs.test.ts +++ b/apps/sim/lib/logs/application/list-logs.test.ts @@ -28,10 +28,10 @@ vi.mock('@sim/platform-authz/workspace', () => ({ resolveEffectiveWorkspacePermission: mocks.resolvePermission, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import { listLogsUseCase } from '@/lib/logs/application/list-logs' -import { PermissionGroupCapabilityError } from '@/lib/permission-groups/capability-error' +import { PermissionGroupCapabilityError } from '@/ee/access-control/lib/capability-error' const WORKSPACE_ID = 'workspace-1' const SESSION: Principal = { kind: 'session', userId: 'user-1', sessionId: 'session-1' } diff --git a/apps/sim/lib/logs/application/public-log-projection.test.ts b/apps/sim/lib/logs/application/public-log-projection.test.ts index 6532246d979..f2f5622067b 100644 --- a/apps/sim/lib/logs/application/public-log-projection.test.ts +++ b/apps/sim/lib/logs/application/public-log-projection.test.ts @@ -33,7 +33,7 @@ const mocks = vi.hoisted(() => ({ recordAudit: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/workspaces/application/workspace-context', () => ({ loadActiveWorkspaceApplicationContext: mocks.loadWorkspace, @@ -71,7 +71,7 @@ vi.mock('@sim/audit', () => ({ recordAudit: mocks.recordAudit })) import { getPublicLog } from '@/lib/logs/application/get-public-log' import { listPublicLogs } from '@/lib/logs/application/list-public-logs' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const WORKSPACE_ID = 'workspace-1' diff --git a/apps/sim/lib/logs/application/read-execution-snapshot.test.ts b/apps/sim/lib/logs/application/read-execution-snapshot.test.ts index 30df45ff087..91592457798 100644 --- a/apps/sim/lib/logs/application/read-execution-snapshot.test.ts +++ b/apps/sim/lib/logs/application/read-execution-snapshot.test.ts @@ -28,7 +28,7 @@ const mocks = vi.hoisted(() => ({ recordAudit: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@sim/db', () => ({ db: { select: mocks.select } })) @@ -57,7 +57,7 @@ vi.mock('@/lib/logs/execution/hydrate-child-traces', () => ({ })) import { readExecutionSnapshotUseCase } from '@/lib/logs/application/read-execution-snapshot' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const WORKSPACE_ID = 'workspace-1' diff --git a/apps/sim/lib/logs/application/read-log-detail.test.ts b/apps/sim/lib/logs/application/read-log-detail.test.ts index 8960be8fd09..c3d2b4f4cf5 100644 --- a/apps/sim/lib/logs/application/read-log-detail.test.ts +++ b/apps/sim/lib/logs/application/read-log-detail.test.ts @@ -28,7 +28,7 @@ vi.mock('@/lib/workspaces/application/workspace-context', () => ({ resolveActiveWorkspaceApplicationContext: mocks.resolveWorkspace, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@sim/platform-authz/workspace', () => ({ permissionSatisfies: (held: string | null, required: string) => diff --git a/apps/sim/lib/logs/execution/logger.ts b/apps/sim/lib/logs/execution/logger.ts index 840f5804247..4c17e36dfa6 100644 --- a/apps/sim/lib/logs/execution/logger.ts +++ b/apps/sim/lib/logs/execution/logger.ts @@ -29,7 +29,6 @@ import { recordUsage, stableEventKey, } from '@/lib/billing/core/usage-log' -import { resolveEffectivePiiRedaction } from '@/lib/billing/retention' import { checkAndBillPayerOverageThreshold } from '@/lib/billing/threshold-billing' import { isBillingEnabled } from '@/lib/core/config/env-flags' import { redactApiKeys } from '@/lib/core/security/redaction' @@ -69,6 +68,7 @@ import type { WorkflowState, } from '@/lib/logs/types' import { emitExecutionCompletedEvent } from '@/lib/workspace-events/emitter' +import { resolveEffectivePiiRedaction } from '@/ee/data-retention/lib/retention' import type { SerializableExecutionState } from '@/executor/execution/types' const logger = createLogger('ExecutionLogger') diff --git a/apps/sim/lib/logs/log-projection.ts b/apps/sim/lib/logs/log-projection.ts index 50bb9eb79a5..a2b10d47a6d 100644 --- a/apps/sim/lib/logs/log-projection.ts +++ b/apps/sim/lib/logs/log-projection.ts @@ -1,9 +1,9 @@ import type { Principal } from '@sim/auth/principal' import { capabilityGovernedPrincipalUserId } from '@/lib/core/application' import { withheldExecutionData, withheldSpendData } from '@/lib/logs/fetch-log-detail' -import { refuseCapability } from '@/lib/permission-groups/capabilities' -import { capabilityDeniedBy } from '@/lib/permission-groups/capability-assertions' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' +import { refuseCapability } from '@/ee/access-control/lib/capabilities' +import { capabilityDeniedBy } from '@/ee/access-control/lib/capability-assertions' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' /** * What a viewer's permission group withholds from a log response. diff --git a/apps/sim/lib/mcp/application/operations.test.ts b/apps/sim/lib/mcp/application/operations.test.ts index 4238e5c4b83..cd64073c06f 100644 --- a/apps/sim/lib/mcp/application/operations.test.ts +++ b/apps/sim/lib/mcp/application/operations.test.ts @@ -15,12 +15,12 @@ vi.mock('@sim/platform-authz/workspace', () => ({ resolveEffectiveWorkspacePermission: mocks.resolvePermission, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import type { WorkspaceOperation } from '@/lib/core/application' import { authorizeWorkspaceOperation, PermissionGroupCapabilityError } from '@/lib/core/application' import { mcpServerOperations } from '@/lib/mcp/application/operations' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' describe('MCP server operation registry', () => { it('requires a human subject for tool discovery', () => { diff --git a/apps/sim/lib/mcp/middleware.test.ts b/apps/sim/lib/mcp/middleware.test.ts index 6f1a15efecc..142be618a4f 100644 --- a/apps/sim/lib/mcp/middleware.test.ts +++ b/apps/sim/lib/mcp/middleware.test.ts @@ -37,10 +37,10 @@ vi.mock('@/lib/auth/hybrid', async () => { vi.mock('@/lib/workspaces/permissions/utils', () => ({ getUserEntityPermissions: mocks.permissions, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import { withMcpAuth } from '@/lib/mcp/middleware' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const resolveGroupConfigMock = permissionGroupScopeMockFns.mockResolvePermissionGroupConfig diff --git a/apps/sim/lib/mcp/middleware.ts b/apps/sim/lib/mcp/middleware.ts index 88be4b04c39..abd4cecda46 100644 --- a/apps/sim/lib/mcp/middleware.ts +++ b/apps/sim/lib/mcp/middleware.ts @@ -15,12 +15,12 @@ import { readStreamToBufferWithLimit, } from '@/lib/core/utils/stream-limits' import { createMcpErrorResponse } from '@/lib/mcp/utils' -import type { StaticPermissionGroupCapability } from '@/lib/permission-groups/capabilities' +import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' +import type { StaticPermissionGroupCapability } from '@/ee/access-control/lib/capabilities' import { capabilityRefusal, isWorkspaceCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' -import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils' +} from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('McpAuthMiddleware') const MAX_MCP_MANAGEMENT_BODY_BYTES = 10 * 1024 * 1024 diff --git a/apps/sim/lib/platform-context/application/platform-context-use-cases.test.ts b/apps/sim/lib/platform-context/application/platform-context-use-cases.test.ts index 44976130c67..68d96bbef07 100644 --- a/apps/sim/lib/platform-context/application/platform-context-use-cases.test.ts +++ b/apps/sim/lib/platform-context/application/platform-context-use-cases.test.ts @@ -34,13 +34,13 @@ vi.mock('@/lib/workspaces/host-context', () => ({ getWorkspaceHostContextForViewer: mocks.getWorkspaceHostContextForViewer, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ resolveVerifiedUserAccessControlContext: mocks.resolveVerifiedUserAccessControlContext, })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { readAccountBilling } from '@/lib/platform-context/application/read-account-billing' import { readEnterpriseContext } from '@/lib/platform-context/application/read-enterprise-context' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const workspace = { workspaceId: 'workspace-1', diff --git a/apps/sim/lib/platform-context/application/read-enterprise-context.ts b/apps/sim/lib/platform-context/application/read-enterprise-context.ts index cbca10f2ca6..bd41b9936d1 100644 --- a/apps/sim/lib/platform-context/application/read-enterprise-context.ts +++ b/apps/sim/lib/platform-context/application/read-enterprise-context.ts @@ -2,12 +2,12 @@ import { requirePrincipalSubjectUserId } from '@sim/auth/principal' import { permissionSatisfies } from '@sim/platform-authz/workspace' import { defineAuthorizedWorkspaceUseCase } from '@/lib/core/application' import { OrchestrationError } from '@/lib/core/orchestration/types' -import { capabilityDeniedBy } from '@/lib/permission-groups/capability-assertions' -import { getActivePermissionGroupRestrictions } from '@/lib/permission-groups/features' import { platformContextDelegationPolicy } from '@/lib/platform-context/application/authorization' import { resolvePlatformContextWorkspace } from '@/lib/platform-context/application/context' import { platformContextOperations } from '@/lib/platform-context/application/operations' import { getWorkspaceHostContextForViewer } from '@/lib/workspaces/host-context' +import { capabilityDeniedBy } from '@/ee/access-control/lib/capability-assertions' +import { getActivePermissionGroupRestrictions } from '@/ee/access-control/lib/features' import { resolveVerifiedUserAccessControlContext } from '@/ee/access-control/utils/permission-check' const ENTERPRISE_PERMISSION_DOCUMENTATION = [ diff --git a/apps/sim/lib/sandboxes/application/operations.test.ts b/apps/sim/lib/sandboxes/application/operations.test.ts index 45840fde188..a612003b4c1 100644 --- a/apps/sim/lib/sandboxes/application/operations.test.ts +++ b/apps/sim/lib/sandboxes/application/operations.test.ts @@ -16,12 +16,12 @@ vi.mock('@sim/platform-authz/workspace', () => ({ resolveEffectiveWorkspacePermission: mocks.resolvePermission, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import type { WorkspaceOperation } from '@/lib/core/application' import { authorizeWorkspaceOperation, PermissionGroupCapabilityError } from '@/lib/core/application' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { sandboxOperations } from '@/lib/sandboxes/application/operations' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' describe('sandbox operation registry', () => { it('lets any member, and a workspace key, read what the workspace built', () => { diff --git a/apps/sim/lib/sandboxes/application/use-cases.test.ts b/apps/sim/lib/sandboxes/application/use-cases.test.ts index e01f0524c92..6e8608b897b 100644 --- a/apps/sim/lib/sandboxes/application/use-cases.test.ts +++ b/apps/sim/lib/sandboxes/application/use-cases.test.ts @@ -30,7 +30,7 @@ vi.mock('@sim/platform-authz/workspace', () => ({ actual === 'admin' || actual === required || (actual === 'write' && required === 'read'), resolveEffectiveWorkspacePermission: mocks.resolvePermission, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@sim/audit', () => ({ AuditAction: { SANDBOX_CREATED: 'sandbox.created', @@ -65,7 +65,6 @@ import { WorkspaceApiKeyAuthorizationError, } from '@/lib/core/application' import { OrchestrationError } from '@/lib/core/orchestration/types' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { SANDBOX_DELEGATION_AUDIENCE } from '@/lib/sandboxes/application/authorization' import { SandboxBuildBudgetExceededError } from '@/lib/sandboxes/application/build-budget' import { @@ -75,6 +74,7 @@ import { listWorkspaceSandboxesUseCase, updateWorkspaceSandboxUseCase, } from '@/lib/sandboxes/application/use-cases' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const workspace = { workspaceId: 'workspace-1', diff --git a/apps/sim/lib/selectors/application/execute-selector.test.ts b/apps/sim/lib/selectors/application/execute-selector.test.ts index 60f75064fa7..63bc4ed1f20 100644 --- a/apps/sim/lib/selectors/application/execute-selector.test.ts +++ b/apps/sim/lib/selectors/application/execute-selector.test.ts @@ -62,13 +62,12 @@ vi.mock('@/lib/selectors/server/sanitize', () => ({ sanitizeSelectorResult: mocks.sanitize, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) const mockResolvePermissionGroupConfig = permissionGroupScopeMockFns.mockResolvePermissionGroupConfig import { selectorScopeSchema } from '@/lib/api/contracts/selectors/execute' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { executeSelector } from '@/lib/selectors/application/execute-selector' import { getSelectorManifestEntry } from '@/lib/selectors/manifest' import { @@ -76,6 +75,7 @@ import { SelectorOptionsUnavailableError, } from '@/lib/selectors/server/errors' import type { ExecuteServerSelectorArgs } from '@/lib/selectors/server/types' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' import { IntegrationNotAllowedError } from '@/ee/access-control/utils/permission-check' const principal = { kind: 'session' as const, userId: 'user-1', sessionId: 'session-1' } diff --git a/apps/sim/lib/selectors/server/integration-access.ts b/apps/sim/lib/selectors/server/integration-access.ts index a1fc5a513cb..484544863f1 100644 --- a/apps/sim/lib/selectors/server/integration-access.ts +++ b/apps/sim/lib/selectors/server/integration-access.ts @@ -2,12 +2,12 @@ import type { Principal } from '@sim/auth/principal' import { getIntegrationTypesForOAuthServiceId } from '@sim/deployment-config/integration-availability' import { createLogger } from '@sim/logger' import { allowedIntegrationTypes } from '@/lib/integrations/principal-scope.server' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import { resolveAccessControlBlockType } from '@/lib/permission-groups/integration-allowlist' import type { SelectorCredentialPolicy, ServerSelectorAttachment, } from '@/lib/selectors/server/types' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import { resolveAccessControlBlockType } from '@/ee/access-control/lib/integration-allowlist' import { IntegrationNotAllowedError } from '@/ee/access-control/utils/permission-check' const logger = createLogger('SelectorIntegrationAccess') diff --git a/apps/sim/lib/settings/application/workspace-section-access.test.ts b/apps/sim/lib/settings/application/workspace-section-access.test.ts index 9e94ffb2828..e7937805700 100644 --- a/apps/sim/lib/settings/application/workspace-section-access.test.ts +++ b/apps/sim/lib/settings/application/workspace-section-access.test.ts @@ -73,7 +73,7 @@ vi.mock('@/lib/organizations/settings-access', () => ({ canOpenOrganizationSettingsSection: mocks.canOpenOrganizationSettingsSection, })) vi.mock('@/lib/permissions/super-user', () => ({ isPlatformAdmin: mocks.isPlatformAdmin })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ isCustomBlocksEligibleForOrganization: mocks.isCustomBlocksEligibleForOrganization, })) vi.mock('@/lib/workspaces/permissions/utils', () => ({ diff --git a/apps/sim/lib/settings/application/workspace-section-access.ts b/apps/sim/lib/settings/application/workspace-section-access.ts index 8f2194a6e2f..294643d47e3 100644 --- a/apps/sim/lib/settings/application/workspace-section-access.ts +++ b/apps/sim/lib/settings/application/workspace-section-access.ts @@ -14,9 +14,9 @@ import { getDeploymentShape } from '@/lib/core/config/deployment-shape' import { isCredentialGroupsAvailable } from '@/lib/credential-groups/availability' import { canOpenOrganizationSettingsSection } from '@/lib/organizations/settings-access' import { isPlatformAdmin } from '@/lib/permissions/super-user' -import { isCustomBlocksEligibleForOrganization } from '@/lib/workflows/custom-blocks/operations' import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils' import { resolveVerifiedUserAccessControlContext } from '@/ee/access-control/utils/permission-check' +import { isCustomBlocksEligibleForOrganization } from '@/ee/custom-blocks/lib/operations' import { isForkingAvailableForWorkspace } from '@/ee/workspace-forking/lib/lineage/authz' export type WorkspaceSettingsSectionAccess = diff --git a/apps/sim/lib/skills/application/operations.test.ts b/apps/sim/lib/skills/application/operations.test.ts index a9152130d80..4da1ec5177d 100644 --- a/apps/sim/lib/skills/application/operations.test.ts +++ b/apps/sim/lib/skills/application/operations.test.ts @@ -16,12 +16,12 @@ vi.mock('@sim/platform-authz/workspace', () => ({ resolveEffectiveWorkspacePermission: mocks.resolvePermission, })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) import type { WorkspaceOperation } from '@/lib/core/application' import { authorizeWorkspaceOperation, PermissionGroupCapabilityError } from '@/lib/core/application' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { skillOperations } from '@/lib/skills/application/operations' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' /** * Pins the workspace-API-key split on skills. diff --git a/apps/sim/lib/table/application/exports.test.ts b/apps/sim/lib/table/application/exports.test.ts index 10d48cbf25c..c30865be53a 100644 --- a/apps/sim/lib/table/application/exports.test.ts +++ b/apps/sim/lib/table/application/exports.test.ts @@ -27,7 +27,7 @@ vi.mock('@sim/platform-authz/workspace', () => ({ permissionSatisfies: () => true, resolveEffectiveWorkspacePermission: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/table', () => ({ getTableById: mocks.getTable })) vi.mock('@/lib/table/application/context', () => ({ resolveActiveTableContext: mocks.resolveContext, @@ -43,12 +43,12 @@ vi.mock('@/lib/uploads/core/storage-service', () => ({ generatePresignedDownloadUrl: vi.fn(), })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { cancelTableExportUseCase, createTableExportUseCase, readTableExportUseCase, } from '@/lib/table/application/exports' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const now = new Date('2026-08-01T00:00:00.000Z') const table: TableDefinition = { diff --git a/apps/sim/lib/table/application/imports.test.ts b/apps/sim/lib/table/application/imports.test.ts index 162f762fe2f..66d5575e35e 100644 --- a/apps/sim/lib/table/application/imports.test.ts +++ b/apps/sim/lib/table/application/imports.test.ts @@ -25,7 +25,7 @@ const mocks = vi.hoisted(() => ({ getUserPermissionConfig: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) @@ -76,7 +76,6 @@ vi.mock('@/lib/uploads/contexts/workspace/workspace-file-manager', () => ({ getWorkspaceFile: mocks.getWorkspaceFile, })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { cancelTableImportUseCase, completeTableImportUseCase, @@ -84,6 +83,7 @@ import { createTableImportUseCase, readTableImportUseCase, } from '@/lib/table/application/imports' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const createdAt = new Date('2026-08-01T00:00:00.000Z') const record = { diff --git a/apps/sim/lib/table/application/imports.ts b/apps/sim/lib/table/application/imports.ts index ba596f1dfb1..5871eb526d6 100644 --- a/apps/sim/lib/table/application/imports.ts +++ b/apps/sim/lib/table/application/imports.ts @@ -9,7 +9,6 @@ import { MAX_FOLDERS_PER_WORKSPACE } from '@/lib/folders/constants' import { withFolderTreeLock } from '@/lib/folders/locks' import { ROOT_FOLDER_PATH } from '@/lib/folders/paths' import { loadActiveFolderPathIndex, resolveFolderPathFromIndex } from '@/lib/folders/queries' -import { assertWorkspaceCapability } from '@/lib/permission-groups/capability-assertions' import { type TableAuthorizationContext, tableDelegationPolicy, @@ -45,6 +44,7 @@ import { createUploadPartUrls, type UploadSessionRecord, } from '@/lib/uploads/upload-session/service' +import { assertWorkspaceCapability } from '@/ee/access-control/lib/capability-assertions' const logger = createLogger('TableImportApplication') diff --git a/apps/sim/lib/tool-execution/application/execute-tool.test.ts b/apps/sim/lib/tool-execution/application/execute-tool.test.ts index e12f018fdcf..a2952bd23a8 100644 --- a/apps/sim/lib/tool-execution/application/execute-tool.test.ts +++ b/apps/sim/lib/tool-execution/application/execute-tool.test.ts @@ -47,7 +47,7 @@ vi.mock('@/lib/core/config/block-visibility', () => ({ getBlockVisibility: mocks.getBlockVisibility, })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ listCustomBlocksWithInputsForWorkspace: mocks.listCustomBlocks, })) diff --git a/apps/sim/lib/workflows/application/apply-workflow-operations.test.ts b/apps/sim/lib/workflows/application/apply-workflow-operations.test.ts index a88a6d652b4..4dde926dab2 100644 --- a/apps/sim/lib/workflows/application/apply-workflow-operations.test.ts +++ b/apps/sim/lib/workflows/application/apply-workflow-operations.test.ts @@ -85,7 +85,7 @@ vi.mock('@/lib/billing/core/subscription', () => ({ hasWorkspaceSandboxAccess: mocks.sandboxAccess, })) vi.mock('@/lib/core/config/block-visibility', () => ({ getBlockVisibility: mocks.blockVisibility })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.permissionConfig, /** * The use case passes the organization it already loaded, so the resolver diff --git a/apps/sim/lib/workflows/application/apply-workflow-operations.ts b/apps/sim/lib/workflows/application/apply-workflow-operations.ts index 08504768d7a..0d38bd95d06 100644 --- a/apps/sim/lib/workflows/application/apply-workflow-operations.ts +++ b/apps/sim/lib/workflows/application/apply-workflow-operations.ts @@ -9,7 +9,6 @@ import { ForbiddenOperationError, principalAuditSource } from '@/lib/core/applic import { getBlockVisibility } from '@/lib/core/config/block-visibility' import { OrchestrationError } from '@/lib/core/orchestration/types' import { MAX_PLAN_REQUIRED } from '@/lib/execution/remote-sandbox/entitlement' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' import { notifyWorkflowUpdated } from '@/lib/realtime/notify' import { defineAuthorizedWorkflowUseCase } from '@/lib/workflows/application/authorized-workflow-use-case' import { @@ -55,6 +54,7 @@ import { import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils' import { validateWorkflowState } from '@/lib/workflows/sanitization/validation' import { withBlockVisibility } from '@/blocks/visibility/server-context' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/workflow/utils' import { normalizeWorkflowState } from '@/stores/workflows/workflow/validation' diff --git a/apps/sim/lib/workflows/application/list-workflow-runs.test.ts b/apps/sim/lib/workflows/application/list-workflow-runs.test.ts index 17a21a13841..d5437b7939e 100644 --- a/apps/sim/lib/workflows/application/list-workflow-runs.test.ts +++ b/apps/sim/lib/workflows/application/list-workflow-runs.test.ts @@ -26,7 +26,7 @@ const mocks = vi.hoisted(() => ({ recordAudit: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/workspaces/application/workspace-context', () => ({ loadActiveWorkspaceApplicationContext: mocks.loadWorkspace, @@ -48,8 +48,8 @@ vi.mock('@/lib/workflows/executor/execution-queries', () => ({ vi.mock('@sim/audit', () => ({ recordAudit: mocks.recordAudit })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { listWorkflowRuns } from '@/lib/workflows/application/list-workflow-runs' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const WORKSPACE_ID = 'workspace-1' const WORKFLOW_ID = 'workflow-1' diff --git a/apps/sim/lib/workflows/blocks/canvas-sentence.ts b/apps/sim/lib/workflows/blocks/canvas-sentence.ts index b8979245a5d..13d728cf48a 100644 --- a/apps/sim/lib/workflows/blocks/canvas-sentence.ts +++ b/apps/sim/lib/workflows/blocks/canvas-sentence.ts @@ -1,4 +1,3 @@ -import { OPERATION_SUBBLOCK_ID } from '@/lib/permission-groups/operation-access' import { resolveFieldNoun } from '@/lib/workflows/blocks/canvas-sentence-noun' import { resolveTriggerSentence } from '@/lib/workflows/blocks/canvas-trigger-sentence' import type { @@ -7,6 +6,7 @@ import type { CanvasSentenceClause, SubBlockConfig, } from '@/blocks/types' +import { OPERATION_SUBBLOCK_ID } from '@/ee/access-control/lib/operation-access' /** * Resolves a block's declarative card summary into rendered segments. diff --git a/apps/sim/lib/workflows/editing/builders.ts b/apps/sim/lib/workflows/editing/builders.ts index 3b45b30325c..2197c6ef8df 100644 --- a/apps/sim/lib/workflows/editing/builders.ts +++ b/apps/sim/lib/workflows/editing/builders.ts @@ -8,15 +8,6 @@ import { } from '@sim/workflow-types/workflow' import { isIntegrationDeploymentAvailableForVisibility } from '@/lib/integrations/availability.server' import { MCP_SERVER_ADVANCED_TOOL_TYPE } from '@/lib/mcp/shared' -import { capabilityDeniedBy } from '@/lib/permission-groups/capability-assertions' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' -import { createModelAccessGate } from '@/lib/permission-groups/model-access' -import { - createToolAccessGate, - isOperationAllowed, - MODEL_SUBBLOCK_ID, - OPERATION_SUBBLOCK_ID, -} from '@/lib/permission-groups/operation-access' import { getEffectiveBlockOutputs } from '@/lib/workflows/blocks/block-outputs' import { isRetryEligibleBlock } from '@/lib/workflows/blocks/retry-eligibility' import { @@ -28,6 +19,15 @@ import { hasTriggerCapability } from '@/lib/workflows/triggers/trigger-utils' import { getBlock } from '@/blocks/registry' import type { BlockConfig } from '@/blocks/types' import { overlayVisibility } from '@/blocks/visibility/context' +import { capabilityDeniedBy } from '@/ee/access-control/lib/capability-assertions' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' +import { createModelAccessGate } from '@/ee/access-control/lib/model-access' +import { + createToolAccessGate, + isOperationAllowed, + MODEL_SUBBLOCK_ID, + OPERATION_SUBBLOCK_ID, +} from '@/ee/access-control/lib/operation-access' import { TRIGGER_RUNTIME_SUBBLOCK_IDS } from '@/triggers/constants' import type { EditWorkflowOperation, SkippedItem, ValidationError } from './types' import { logSkippedItem } from './types' diff --git a/apps/sim/lib/workflows/editing/engine.ts b/apps/sim/lib/workflows/editing/engine.ts index ba98f968ac4..63a04aa7fae 100644 --- a/apps/sim/lib/workflows/editing/engine.ts +++ b/apps/sim/lib/workflows/editing/engine.ts @@ -1,6 +1,6 @@ import { createLogger } from '@sim/logger' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' import { isValidKey } from '@/lib/workflows/sanitization/key-validation' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' import { validateEdges } from '@/stores/workflows/workflow/edge-validation' import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/workflow/utils' import { diff --git a/apps/sim/lib/workflows/editing/operations.test.ts b/apps/sim/lib/workflows/editing/operations.test.ts index c9f8511bc60..92bf7d76a3e 100644 --- a/apps/sim/lib/workflows/editing/operations.test.ts +++ b/apps/sim/lib/workflows/editing/operations.test.ts @@ -2,8 +2,8 @@ * @vitest-environment node */ import { describe, expect, it, vi } from 'vitest' -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { sanitizeForCopilot } from '@/lib/workflows/sanitization/json-sanitizer' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' import { applyOperationsToWorkflowState } from './engine' vi.mock('@/blocks/registry', () => { diff --git a/apps/sim/lib/workflows/editing/types.ts b/apps/sim/lib/workflows/editing/types.ts index a775b85e137..b4e365e0b17 100644 --- a/apps/sim/lib/workflows/editing/types.ts +++ b/apps/sim/lib/workflows/editing/types.ts @@ -1,5 +1,5 @@ import { createLogger } from '@sim/logger' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' /** Selector subblock types that can be validated */ export const SELECTOR_TYPES = new Set([ diff --git a/apps/sim/lib/workflows/editing/validation.ts b/apps/sim/lib/workflows/editing/validation.ts index 0103b946ced..6d7734c71e0 100644 --- a/apps/sim/lib/workflows/editing/validation.ts +++ b/apps/sim/lib/workflows/editing/validation.ts @@ -4,9 +4,6 @@ import { omit } from '@sim/utils/object' import { isHosted as isHostedDeployment } from '@/lib/core/config/env-flags' import { isIntegrationDeploymentAvailableForVisibility } from '@/lib/integrations/availability.server' import { MCP_SERVER_ADVANCED_TOOL_TYPE } from '@/lib/mcp/shared' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import type { PermissionGroupConfig } from '@/lib/permission-groups/fields' -import { resolveAccessControlBlockType } from '@/lib/permission-groups/integration-allowlist' import { getCustomToolById } from '@/lib/workflows/custom-tools/operations' import { validateSelectorIds } from '@/lib/workflows/editing/selector-validator' import { containsReference } from '@/lib/workflows/sanitization/references' @@ -22,6 +19,9 @@ import { getBlock } from '@/blocks/registry' import type { SubBlockConfig } from '@/blocks/types' import { getModelOptions } from '@/blocks/utils' import { overlayVisibility } from '@/blocks/visibility/context' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import type { PermissionGroupConfig } from '@/ee/access-control/lib/fields' +import { resolveAccessControlBlockType } from '@/ee/access-control/lib/integration-allowlist' import { BlockType, EDGE, normalizeName } from '@/executor/constants' import { isAutoModel, isKnownModelId, suggestModelIdsForUnknownModel } from '@/providers/models' import { isPiByokOnlyMode } from '@/providers/pi-providers' diff --git a/apps/sim/lib/workflows/executor/execute-service.ts b/apps/sim/lib/workflows/executor/execute-service.ts index 7edae7f8b2c..3cca3a06214 100644 --- a/apps/sim/lib/workflows/executor/execute-service.ts +++ b/apps/sim/lib/workflows/executor/execute-service.ts @@ -17,7 +17,6 @@ import { preprocessExecution } from '@/lib/execution/preprocessing' import { LoggingSession } from '@/lib/logs/execution/logging-session' import { MAX_MCP_WORKFLOW_RESPONSE_BYTES } from '@/lib/mcp/constants' import { hydrateUserFilesWithBase64 } from '@/lib/uploads/utils/user-file-base64.server' -import { getCustomBlockRowsForWorkspace } from '@/lib/workflows/custom-blocks/operations' import { enqueueWorkflowExecution } from '@/lib/workflows/executor/enqueue-execution' import { executeWorkflow } from '@/lib/workflows/executor/execute-workflow' import { executeWorkflowCore } from '@/lib/workflows/executor/execution-core' @@ -41,6 +40,7 @@ import { } from '@/lib/workflows/streaming/streaming' import { workflowHasResponseBlock } from '@/lib/workflows/utils' import { withCustomBlockOverlay } from '@/blocks/custom/server-overlay' +import { getCustomBlockRowsForWorkspace } from '@/ee/custom-blocks/lib/operations' import { ExecutionSnapshot } from '@/executor/execution/snapshot' import type { ExecutionMetadata, SerializableExecutionState } from '@/executor/execution/types' import type { NormalizedBlockOutput } from '@/executor/types' diff --git a/apps/sim/lib/workflows/executor/execution-core.test.ts b/apps/sim/lib/workflows/executor/execution-core.test.ts index 666493bf95a..41c7e3831be 100644 --- a/apps/sim/lib/workflows/executor/execution-core.test.ts +++ b/apps/sim/lib/workflows/executor/execution-core.test.ts @@ -81,7 +81,7 @@ vi.mock('@/lib/logs/execution/trace-spans/trace-spans', () => ({ vi.mock('@/lib/workflows/persistence/utils', () => workflowsPersistenceUtilsMock) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ getCustomBlockRowsForWorkspace: vi.fn().mockResolvedValue([]), })) diff --git a/apps/sim/lib/workflows/executor/execution-core.ts b/apps/sim/lib/workflows/executor/execution-core.ts index a38c7ad0ac3..5409e613d5c 100644 --- a/apps/sim/lib/workflows/executor/execution-core.ts +++ b/apps/sim/lib/workflows/executor/execution-core.ts @@ -13,7 +13,6 @@ import { mergeSubblockStateWithValues } from '@sim/workflow-persistence/subblock import type { Edge } from '@xyflow/react' import { eq } from 'drizzle-orm' import { z } from 'zod' -import { type EffectivePiiRedaction, resolveEffectivePiiRedaction } from '@/lib/billing/retention' import { getExecutionDeadlineAt, getTimeoutErrorMessage, @@ -27,8 +26,6 @@ import type { LoggingSession } from '@/lib/logs/execution/logging-session' import { redactLargeValueRefsInValue } from '@/lib/logs/execution/pii-large-values' import { redactObjectStrings } from '@/lib/logs/execution/pii-redaction' import { buildTraceSpans } from '@/lib/logs/execution/trace-spans/trace-spans' -import { waitForChildRuns } from '@/lib/workflows/custom-blocks/child-execution' -import { getCustomBlockRowsForWorkspace } from '@/lib/workflows/custom-blocks/operations' import { resolveStartBlockRunIdentity } from '@/lib/workflows/executor/start-run-identity' import { loadDeployedWorkflowState, @@ -38,6 +35,12 @@ import { import { TriggerUtils } from '@/lib/workflows/triggers/triggers' import { updateWorkflowRunCounts } from '@/lib/workflows/utils' import { withCustomBlockOverlay } from '@/blocks/custom/server-overlay' +import { waitForChildRuns } from '@/ee/custom-blocks/lib/child-execution' +import { getCustomBlockRowsForWorkspace } from '@/ee/custom-blocks/lib/operations' +import { + type EffectivePiiRedaction, + resolveEffectivePiiRedaction, +} from '@/ee/data-retention/lib/retention' import { Executor } from '@/executor' import type { ExecutionSnapshot } from '@/executor/execution/snapshot' import type { diff --git a/apps/sim/lib/workflows/executor/execution-status-projection.test.ts b/apps/sim/lib/workflows/executor/execution-status-projection.test.ts index 823629e610c..51535b7ee77 100644 --- a/apps/sim/lib/workflows/executor/execution-status-projection.test.ts +++ b/apps/sim/lib/workflows/executor/execution-status-projection.test.ts @@ -29,7 +29,7 @@ const { mockGetJob, mockMaterializeForDisplayWithBlockOutputs } = vi.hoisted(() mockMaterializeForDisplayWithBlockOutputs: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@/lib/core/async-jobs', () => ({ getJobQueue: vi.fn().mockResolvedValue({ getJob: mockGetJob }), @@ -43,8 +43,8 @@ vi.mock('@/lib/workflows/executor/paused-execution-metadata', () => ({ getAutomaticResumeWaitingMetadata: vi.fn().mockReturnValue(null), })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { getWorkflowExecutionStatus } from '@/lib/workflows/executor/execution-status' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const BLOCK_ID = 'block-1' diff --git a/apps/sim/lib/workflows/operations/import-workflow.test.ts b/apps/sim/lib/workflows/operations/import-workflow.test.ts index f4d3046d256..bcc1a1f1717 100644 --- a/apps/sim/lib/workflows/operations/import-workflow.test.ts +++ b/apps/sim/lib/workflows/operations/import-workflow.test.ts @@ -12,7 +12,7 @@ const mocks = vi.hoisted(() => ({ extractAndPersistCustomTools: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) vi.mock('@/lib/workflows/orchestration', () => ({ diff --git a/apps/sim/lib/workflows/persistence/block-access-guard.test.ts b/apps/sim/lib/workflows/persistence/block-access-guard.test.ts index 4e61d7bd556..d1d60e75eef 100644 --- a/apps/sim/lib/workflows/persistence/block-access-guard.test.ts +++ b/apps/sim/lib/workflows/persistence/block-access-guard.test.ts @@ -7,7 +7,7 @@ const mocks = vi.hoisted(() => ({ getUserPermissionConfig: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) diff --git a/apps/sim/lib/workflows/persistence/block-access-guard.ts b/apps/sim/lib/workflows/persistence/block-access-guard.ts index e7d624f012d..996d4c998ea 100644 --- a/apps/sim/lib/workflows/persistence/block-access-guard.ts +++ b/apps/sim/lib/workflows/persistence/block-access-guard.ts @@ -1,10 +1,10 @@ import { OrchestrationError } from '@/lib/core/orchestration/types' -import { isBlockTypeAccessControlExempt } from '@/lib/permission-groups/block-access' -import { resolvePermissionGroupConfig } from '@/lib/permission-groups/config-scope.server' +import { isBlockTypeAccessControlExempt } from '@/ee/access-control/lib/block-access' +import { resolvePermissionGroupConfig } from '@/ee/access-control/lib/config-scope.server' import { resolveAccessControlBlockType, toAccessControlAllowlist, -} from '@/lib/permission-groups/integration-allowlist' +} from '@/ee/access-control/lib/integration-allowlist' import { BlockType } from '@/executor/constants' /** diff --git a/apps/sim/lib/workflows/persistence/persist-block-access-gate.test.ts b/apps/sim/lib/workflows/persistence/persist-block-access-gate.test.ts index 2645bb64bdd..8147753da05 100644 --- a/apps/sim/lib/workflows/persistence/persist-block-access-gate.test.ts +++ b/apps/sim/lib/workflows/persistence/persist-block-access-gate.test.ts @@ -20,7 +20,7 @@ const mocks = vi.hoisted(() => ({ lock: vi.fn(), })) -vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) +vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) vi.mock('@sim/workflow-persistence/save', () => ({ saveWorkflowToNormalizedTables: mocks.saveRaw, })) diff --git a/apps/sim/lib/workflows/persistence/save-workflow-normalized-state.test.ts b/apps/sim/lib/workflows/persistence/save-workflow-normalized-state.test.ts index b18ca24a384..cb21a3e3440 100644 --- a/apps/sim/lib/workflows/persistence/save-workflow-normalized-state.test.ts +++ b/apps/sim/lib/workflows/persistence/save-workflow-normalized-state.test.ts @@ -15,7 +15,7 @@ const mocks = vi.hoisted(() => ({ getUserPermissionConfig: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mocks.getUserPermissionConfig, })) diff --git a/apps/sim/lib/workspace-files/application/download-workspace-file-items.test.ts b/apps/sim/lib/workspace-files/application/download-workspace-file-items.test.ts index e8374108526..f2bf1fcbfa6 100644 --- a/apps/sim/lib/workspace-files/application/download-workspace-file-items.test.ts +++ b/apps/sim/lib/workspace-files/application/download-workspace-file-items.test.ts @@ -29,7 +29,7 @@ const { mockGetUserPermissionConfig: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: mockGetUserPermissionConfig, /** The use case passes the organization the authorized context already loaded. */ resolveVerifiedUserAccessControlContext: async (userId: string, workspaceId: string) => ({ @@ -70,8 +70,8 @@ vi.mock('@sim/audit', () => ({ recordAudit: mockRecordAudit, })) -import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/lib/permission-groups/fields' import { downloadWorkspaceFileItems } from '@/lib/workspace-files/application/download-workspace-file-items' +import { DEFAULT_PERMISSION_GROUP_CONFIG } from '@/ee/access-control/lib/fields' const principal = { kind: 'session' as const, userId: 'u1', sessionId: 's1' } const delegatedPrincipal = { diff --git a/apps/sim/lib/workspace-files/application/download-workspace-file-items.ts b/apps/sim/lib/workspace-files/application/download-workspace-file-items.ts index 011dabaf0c7..b1c0f1bc4aa 100644 --- a/apps/sim/lib/workspace-files/application/download-workspace-file-items.ts +++ b/apps/sim/lib/workspace-files/application/download-workspace-file-items.ts @@ -6,7 +6,6 @@ import { import { OrchestrationError } from '@/lib/core/orchestration/types' import { PayloadSizeLimitError } from '@/lib/core/utils/stream-limits' import { parseFolderPath } from '@/lib/folders/paths' -import { assertWorkspaceCapability } from '@/lib/permission-groups/capability-assertions' import { buildWorkspaceFileFolderPathMap, listWorkspaceFileFolders, @@ -25,6 +24,7 @@ import { fetchAuthorizedServableWorkspaceFileBuffer } from '@/lib/workspace-file import { fileOperations } from '@/lib/workspace-files/application/operations' import { parseWorkspaceFileFolderDisplayPath } from '@/lib/workspace-files/folder-display-path' import { MAX_ZIP_DOWNLOAD_FILES } from '@/lib/workspace-files/limits' +import { assertWorkspaceCapability } from '@/ee/access-control/lib/capability-assertions' export const MAX_ZIP_DOWNLOAD_BYTES = 250 * 1024 * 1024 const MAX_REQUESTED_FILE_IDS = 1_000 diff --git a/apps/sim/lib/workspaces/admin-move-source-impact.ts b/apps/sim/lib/workspaces/admin-move-source-impact.ts index 696e11d8aff..ad7d3b5b043 100644 --- a/apps/sim/lib/workspaces/admin-move-source-impact.ts +++ b/apps/sim/lib/workspaces/admin-move-source-impact.ts @@ -26,7 +26,7 @@ import { isSubscriptionBackedEntitlement } from '@/lib/billing/core/subscription import { isEnterprise } from '@/lib/billing/plan-helpers' import { USABLE_SUBSCRIPTION_STATUSES } from '@/lib/billing/subscriptions/utils' import type { DbOrTx } from '@/lib/db/types' -import { getCustomBlockUsageCounts } from '@/lib/workflows/custom-blocks/operations' +import { getCustomBlockUsageCounts } from '@/ee/custom-blocks/lib/operations' /** * Everything the source organization loses when a workspace leaves it, plus the diff --git a/apps/sim/lib/workspaces/admin-move.test.ts b/apps/sim/lib/workspaces/admin-move.test.ts index 92f7d858949..b8cfba1d3eb 100644 --- a/apps/sim/lib/workspaces/admin-move.test.ts +++ b/apps/sim/lib/workspaces/admin-move.test.ts @@ -161,7 +161,7 @@ vi.mock('@/lib/invitations/send', () => ({ sendInvitationEmail, })) vi.mock('@/lib/table/billing', () => ({ invalidateWorkspaceTableLimitsCache })) -vi.mock('@/lib/workflows/custom-blocks/operations', () => ({ deleteCustomBlock })) +vi.mock('@/ee/custom-blocks/lib/operations', () => ({ deleteCustomBlock })) vi.mock('@/lib/workspaces/admin-move-source-impact', () => ({ cleanupSourceOrganizationArtifactsTx, collectWorkspaceCredentialSummary, diff --git a/apps/sim/lib/workspaces/admin-move.ts b/apps/sim/lib/workspaces/admin-move.ts index 2a662d07d2e..48ddb0e53b1 100644 --- a/apps/sim/lib/workspaces/admin-move.ts +++ b/apps/sim/lib/workspaces/admin-move.ts @@ -41,7 +41,6 @@ import { getInvitationById, isInvitationExpired } from '@/lib/invitations/core' import { acquireInvitationMutationLocks } from '@/lib/invitations/locks' import { PENDING_INVITATION_UNIQUE_INDEX, sendInvitationEmail } from '@/lib/invitations/send' import { invalidateWorkspaceTableLimitsCache } from '@/lib/table/billing' -import { deleteCustomBlock } from '@/lib/workflows/custom-blocks/operations' import { type CrossOrgForkEdge, cleanupSourceOrganizationArtifactsTx, @@ -62,6 +61,7 @@ import { partitionInvitationGrantsForWorkspaceMove, } from '@/lib/workspaces/invitation-migration-plan' import { WORKSPACE_MODE } from '@/lib/workspaces/policy' +import { deleteCustomBlock } from '@/ee/custom-blocks/lib/operations' const logger = createLogger('AdminWorkspaceMove') diff --git a/apps/sim/lib/workspaces/policy.test.ts b/apps/sim/lib/workspaces/policy.test.ts index a0b9fe2cd88..2e02892da14 100644 --- a/apps/sim/lib/workspaces/policy.test.ts +++ b/apps/sim/lib/workspaces/policy.test.ts @@ -34,14 +34,14 @@ const { mockIsOrganizationPermissionRegimeActive: vi.fn(), })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfigForOrganization: mockGetUserPermissionConfigForOrganization, getUserPermissionConfig: mockGetUserPermissionConfig, getEntitledOrganizationPermissionConfig: mockGetEntitledOrganizationPermissionConfig, isOrganizationPermissionRegimeActive: mockIsOrganizationPermissionRegimeActive, })) -vi.mock('@/lib/permission-groups/locks', () => ({ +vi.mock('@/ee/access-control/lib/locks', () => ({ acquirePermissionGroupOrgLock: mockAcquirePermissionGroupOrgLock, })) diff --git a/apps/sim/lib/workspaces/policy.ts b/apps/sim/lib/workspaces/policy.ts index 520f0e55e77..6a9a94d6068 100644 --- a/apps/sim/lib/workspaces/policy.ts +++ b/apps/sim/lib/workspaces/policy.ts @@ -14,16 +14,16 @@ import { getPlanType, isEnterprise, isMaxTier, isPro, isTeam } from '@/lib/billi import { hasUsableSubscriptionStatus } from '@/lib/billing/subscriptions/utils' import { isBillingEnabled } from '@/lib/core/config/env-flags' import type { DbOrTx } from '@/lib/db/types' -import { - capabilityRefusal, - isEntitledOrganizationCapabilityWithheld, -} from '@/lib/permission-groups/capability-assertions' -import { acquirePermissionGroupOrgLock } from '@/lib/permission-groups/locks' -import { isOrganizationPermissionRegimeActive } from '@/lib/permission-groups/resolve.server' import { CONTACT_OWNER_TO_UPGRADE_REASON, UPGRADE_TO_INVITE_REASON, } from '@/lib/workspaces/policy-constants' +import { + capabilityRefusal, + isEntitledOrganizationCapabilityWithheld, +} from '@/ee/access-control/lib/capability-assertions' +import { acquirePermissionGroupOrgLock } from '@/ee/access-control/lib/locks' +import { isOrganizationPermissionRegimeActive } from '@/ee/access-control/lib/resolve.server' const logger = createLogger('WorkspacePolicy') @@ -191,7 +191,7 @@ export async function resolveGoverningPermissionGroupOrganization(params: { * * LOCK ORDER: `organization-mutation:` → `user-billing-identity:` → * `:` → `permission_group:` (a leaf lock — see - * `lib/permission-groups/locks.ts`). The permission-group lock is taken LAST, + * `ee/access-control/lib/locks.ts`). The permission-group lock is taken LAST, * and only AFTER live membership has been confirmed, so a caller who turns out * not to belong to the organization never serializes against its admins. * diff --git a/apps/sim/providers/utils.ts b/apps/sim/providers/utils.ts index ba9d19a2728..34d94c79e02 100644 --- a/apps/sim/providers/utils.ts +++ b/apps/sim/providers/utils.ts @@ -11,7 +11,6 @@ import { normalizeStringRecord, normalizeWorkflowVariables, } from '@/lib/core/utils/records' -import type { CustomBlockToolBinding } from '@/lib/workflows/custom-blocks/operations' import { isFileFieldType, type WorkflowInputField } from '@/lib/workflows/input-format' import { buildCanonicalIndex, @@ -23,6 +22,7 @@ import { } from '@/lib/workflows/subblocks/visibility' import { assembleCustomBlockInputMapping, isCustomBlockType } from '@/blocks/custom/build-config' import type { SubBlockConfig } from '@/blocks/types' +import type { CustomBlockToolBinding } from '@/ee/custom-blocks/lib/operations' import { isCustomTool } from '@/executor/constants' import { getComputerUseModels, diff --git a/apps/sim/stores/modals/search/store.ts b/apps/sim/stores/modals/search/store.ts index 8c60ec9d152..e693ff54004 100644 --- a/apps/sim/stores/modals/search/store.ts +++ b/apps/sim/stores/modals/search/store.ts @@ -1,12 +1,12 @@ import { Repeat, Split } from '@sim/emcn/icons' import { create } from 'zustand' import { devtools } from 'zustand/middleware' -import { isOperationAllowed } from '@/lib/permission-groups/operation-access' import { toSearchToken } from '@/lib/search/tokens' import { getToolOperationsIndex } from '@/lib/search/tool-operations' import { getTriggersForSidebar } from '@/lib/workflows/triggers/trigger-utils' import { getAllBlocks, getBlock } from '@/blocks' import type { BlockConfig, SubBlockConfig } from '@/blocks/types' +import { isOperationAllowed } from '@/ee/access-control/lib/operation-access' import type { SearchBlockItem, SearchData, diff --git a/apps/sim/stores/modals/search/types.ts b/apps/sim/stores/modals/search/types.ts index 16a8d3b4821..0df145dff12 100644 --- a/apps/sim/stores/modals/search/types.ts +++ b/apps/sim/stores/modals/search/types.ts @@ -1,6 +1,6 @@ import type { ComponentType } from 'react' -import type { IsToolAllowed } from '@/lib/permission-groups/operation-access' import type { BlockConfig } from '@/blocks/types' +import type { IsToolAllowed } from '@/ee/access-control/lib/operation-access' /** * Represents a block item in the search results. diff --git a/apps/sim/stores/workflows/prepare-block-state.ts b/apps/sim/stores/workflows/prepare-block-state.ts index e039021a292..f79c6e72cfe 100644 --- a/apps/sim/stores/workflows/prepare-block-state.ts +++ b/apps/sim/stores/workflows/prepare-block-state.ts @@ -9,12 +9,12 @@ * workspace route for a function only the canvas drop handler calls. */ -import type { SeedValueGate } from '@/lib/permission-groups/operation-access' import { getEffectiveBlockOutputs } from '@/lib/workflows/blocks/block-outputs' import { createDefaultInputFormatField } from '@/lib/workflows/input-format' import { buildDefaultCanonicalModes } from '@/lib/workflows/subblocks/visibility' import { hasTriggerCapability } from '@/lib/workflows/triggers/trigger-utils' import { getBlock } from '@/blocks' +import type { SeedValueGate } from '@/ee/access-control/lib/operation-access' import type { BlockState, Position, SubBlockState } from '@/stores/workflows/workflow/types' export interface PrepareBlockStateOptions { diff --git a/apps/sim/tools/index.test.ts b/apps/sim/tools/index.test.ts index 1cb84748caa..59a85e7dbfe 100644 --- a/apps/sim/tools/index.test.ts +++ b/apps/sim/tools/index.test.ts @@ -119,7 +119,7 @@ vi.mock('@/ee/access-control/utils/permission-check', () => ({ PublicApiNotAllowedError: class PublicApiNotAllowedError extends Error {}, })) -vi.mock('@/lib/permission-groups/resolve.server', () => ({ +vi.mock('@/ee/access-control/lib/resolve.server', () => ({ getUserPermissionConfig: vi.fn().mockResolvedValue(null), })) diff --git a/packages/testing/src/mocks/permission-group-scope.mock.ts b/packages/testing/src/mocks/permission-group-scope.mock.ts index 01f332298cf..bdb8c10bf09 100644 --- a/packages/testing/src/mocks/permission-group-scope.mock.ts +++ b/packages/testing/src/mocks/permission-group-scope.mock.ts @@ -1,7 +1,7 @@ import { vi } from 'vitest' /** - * Controllable mock functions for `@/lib/permission-groups/config-scope.server`. + * Controllable mock functions for `@/ee/access-control/lib/config-scope.server`. * * `mockResolvePermissionGroupConfig` is the one seam every capability gate reads * — `assertWorkspaceCapability`, `isWorkspaceCapabilityWithheld`, and the @@ -17,7 +17,7 @@ import { vi } from 'vitest' * ```ts * import { permissionGroupScopeMock, permissionGroupScopeMockFns } from '@sim/testing' * - * vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) + * vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) * * permissionGroupScopeMockFns.mockResolvePermissionGroupConfig.mockResolvedValue({ * ...DEFAULT_PERMISSION_GROUP_CONFIG, @@ -30,16 +30,16 @@ export const permissionGroupScopeMockFns = { } /** - * Static mock module for `@/lib/permission-groups/config-scope.server`. + * Static mock module for `@/ee/access-control/lib/config-scope.server`. * * Only the resolver lives there. `withPermissionGroupScope` — which * `withRouteHandler` calls to wrap every route handler — lives in the - * import-free `@/lib/permission-groups/request-scope.server`, so mocking this + * import-free `@/ee/access-control/lib/request-scope.server`, so mocking this * module leaves the real scope wrapper in place and there is nothing to stub. * * @example * ```ts - * vi.mock('@/lib/permission-groups/config-scope.server', () => permissionGroupScopeMock) + * vi.mock('@/ee/access-control/lib/config-scope.server', () => permissionGroupScopeMock) * ``` */ export const permissionGroupScopeMock = { diff --git a/scripts/check-application-graph.test.ts b/scripts/check-application-graph.test.ts index a477dd07bc6..f72f5648a60 100644 --- a/scripts/check-application-graph.test.ts +++ b/scripts/check-application-graph.test.ts @@ -46,7 +46,7 @@ describe('runtimeSpecifiers', () => { describe('resolveSpecifier', () => { it('resolves an @/ specifier against apps/sim', () => { - expect(resolveSpecifier('@/lib/permission-groups/capabilities', __filename)).toMatch( + expect(resolveSpecifier('@/ee/access-control/lib/capabilities', __filename)).toMatch( /apps\/sim\/lib\/permission-groups\/capabilities\.ts$/ ) }) @@ -80,14 +80,14 @@ describe('the guarded roots', () => { * still pass if `findViolations` silently stopped finding anything. */ const violations = findViolations({ - root: 'lib/permission-groups/model-access.ts', + root: 'ee/access-control/lib/model-access.ts', forbidden: FORBIDDEN_PREFIXES, }) expect(violations).toHaveLength(1) expect(violations[0].forbidden).toBe('providers/utils.ts') expect(violations[0].reason).toBe(FORBIDDEN_PREFIXES['providers/']) expect(violations[0].path).toEqual([ - 'lib/permission-groups/model-access.ts', + 'ee/access-control/lib/model-access.ts', 'providers/utils.ts', ]) }) diff --git a/scripts/check-application-graph.ts b/scripts/check-application-graph.ts index 0281bde0a2c..3a03895b27b 100644 --- a/scripts/check-application-graph.ts +++ b/scripts/check-application-graph.ts @@ -4,7 +4,7 @@ * light. * * `@/lib/core/application` is imported by ~every domain `operations.ts`, and - * `lib/permission-groups/capabilities.ts` sits below it, so anything either one + * `ee/access-control/lib/capabilities.ts` sits below it, so anything either one * reaches at runtime is loaded by every surface that authorizes anything — * routes, jobs, the realtime prune graph and every use-case unit test. The * provider registry, the block/tool registries, the executor and the @@ -34,14 +34,14 @@ * FIVE entry points, listed in {@link GUARDED_ROOTS}: `lib/core/application`, * three permission-group modules (`capabilities`, `capability-assertions`, * `config-scope.server`) and the route wrapper. It is NOT "all of - * `lib/permission-groups/`", and the difference is not a rounding error: + * `ee/access-control/lib/`", and the difference is not a rounding error: * - * - `lib/permission-groups/model-access.ts` imports `providers/utils.ts` + * - `ee/access-control/lib/model-access.ts` imports `providers/utils.ts` * directly, on purpose — deciding which models a group allows is the one * permission-group question that genuinely needs the provider registry. It is * unguardable by construction, and the graph test uses it as its proof that * the walker can still fail. - * - `lib/permission-groups/user-scope.server.ts` — the user-global resolver — + * - `ee/access-control/lib/user-scope.server.ts` — the user-global resolver — * reaches the workflow graph today, through * `lib/billing/organizations/membership.ts` -> `lib/billing/core/usage.ts` -> * `components/emails`. Guarding it is therefore not free: it would go red on @@ -98,13 +98,13 @@ export const FORBIDDEN_PREFIXES: Record = { * domain, so it has no business loading those graphs. * * These sit on top of FORBIDDEN_PREFIXES for this root only. They are NOT - * app-wide bans — `lib/permission-groups/resolve.server.ts` legitimately reads + * app-wide bans — `ee/access-control/lib/resolve.server.ts` legitimately reads * the subscription to decide whether an organization is on an enterprise plan, * which is why `lib/billing/` stays allowed for the funnel roots below. */ const ROUTE_WRAPPER_FORBIDDEN_PREFIXES: Record = { 'lib/billing/': 'the billing graph — the route wrapper makes no plan or subscription decision', - 'lib/permission-groups/resolve.server': + 'ee/access-control/lib/resolve.server': 'the permission-group resolver — the wrapper only opens the memo scope; the resolver ' + 'belongs to the gate call sites, and it is what dragged billing in', 'lib/auth': 'the auth graph — the wrapper wraps handlers that authenticate, it does not', @@ -124,9 +124,9 @@ export interface GuardedRoot { */ export const GUARDED_ROOTS: readonly GuardedRoot[] = [ { root: 'lib/core/application/index.ts', forbidden: FORBIDDEN_PREFIXES }, - { root: 'lib/permission-groups/capabilities.ts', forbidden: FORBIDDEN_PREFIXES }, - { root: 'lib/permission-groups/capability-assertions.ts', forbidden: FORBIDDEN_PREFIXES }, - { root: 'lib/permission-groups/config-scope.server.ts', forbidden: FORBIDDEN_PREFIXES }, + { root: 'ee/access-control/lib/capabilities.ts', forbidden: FORBIDDEN_PREFIXES }, + { root: 'ee/access-control/lib/capability-assertions.ts', forbidden: FORBIDDEN_PREFIXES }, + { root: 'ee/access-control/lib/config-scope.server.ts', forbidden: FORBIDDEN_PREFIXES }, { root: 'lib/core/utils/with-route-handler.ts', forbidden: { ...FORBIDDEN_PREFIXES, ...ROUTE_WRAPPER_FORBIDDEN_PREFIXES }, diff --git a/scripts/check-capability-subject.test.ts b/scripts/check-capability-subject.test.ts index 56604fa2078..0ce3ad2b5e6 100644 --- a/scripts/check-capability-subject.test.ts +++ b/scripts/check-capability-subject.test.ts @@ -14,7 +14,7 @@ describe('assertion B — a v1 route may not decide a capability for itself', () it('reports a route that imports the user-global resolver directly', () => { const { findings } = auditSource( ROUTE, - "import { isCapabilityWithheldForUser } from '@/lib/permission-groups/user-scope.server'\n" + "import { isCapabilityWithheldForUser } from '@/ee/access-control/lib/user-scope.server'\n" ) expect(findings).toHaveLength(1) @@ -22,11 +22,11 @@ describe('assertion B — a v1 route may not decide a capability for itself', () }) it.each([ - '@/lib/permission-groups/capability-assertions', - '@/lib/permission-groups/capabilities', - '@/lib/permission-groups/resolve.server', - '@/lib/permission-groups/config-scope.server', - '@/lib/permission-groups/user-scope.server', + '@/ee/access-control/lib/capability-assertions', + '@/ee/access-control/lib/capabilities', + '@/ee/access-control/lib/resolve.server', + '@/ee/access-control/lib/config-scope.server', + '@/ee/access-control/lib/user-scope.server', ])('reports a route that imports %s', (module) => { const { findings } = auditSource(ROUTE, `import { thing } from '${module}'\n`) @@ -36,7 +36,7 @@ describe('assertion B — a v1 route may not decide a capability for itself', () it('allows the middleware itself, which is where the decision belongs', () => { const { findings } = auditSource( MIDDLEWARE, - "import { isCapabilityWithheldForUser } from '@/lib/permission-groups/user-scope.server'\n" + "import { isCapabilityWithheldForUser } from '@/ee/access-control/lib/user-scope.server'\n" ) expect(findings).toEqual([]) @@ -78,7 +78,7 @@ describe('assertion C — the two renames that made it a no-op', () => { const { findings, sinks } = auditSource( MIDDLEWARE, [ - "import { assertWorkspaceCapability as assertCap } from '@/lib/permission-groups/capability-assertions'", + "import { assertWorkspaceCapability as assertCap } from '@/ee/access-control/lib/capability-assertions'", "await assertCap(rateLimit.userId, workspaceId, 'tables.use')", ].join('\n') ) diff --git a/scripts/check-capability-subject.ts b/scripts/check-capability-subject.ts index 52ce08ebf0c..a27a9d6ad14 100644 --- a/scripts/check-capability-subject.ts +++ b/scripts/check-capability-subject.ts @@ -60,7 +60,7 @@ * route reads the whole log and blanks fields. `resolveLogFieldProjection` is * on the sink list instead, which is the stronger check of the two: B asks * only whether a module was imported, C asks what subject its sink was given. - * A capability decider added under `lib/permission-groups/` belongs on B; one + * A capability decider added under `ee/access-control/lib/` belongs on B; one * whose call site is legitimately a route belongs on C. * - The sink list is enumerated, not derived. A new helper that takes a user id * and resolves a capability is invisible until it is added to @@ -94,10 +94,10 @@ const GOVERNED = 'capabilityGovernedUserId' * these has stepped around the middleware and is deciding for itself. */ const CAPABILITY_MODULES = [ - '@/lib/permission-groups/capability-assertions', - '@/lib/permission-groups/capabilities', - '@/lib/permission-groups/resolve.server', - '@/lib/permission-groups/config-scope.server', + '@/ee/access-control/lib/capability-assertions', + '@/ee/access-control/lib/capabilities', + '@/ee/access-control/lib/resolve.server', + '@/ee/access-control/lib/config-scope.server', /** * The user-global resolver, which answers a capability for a caller who names * no workspace by falling back to the organization's default group. It takes @@ -105,7 +105,7 @@ const CAPABILITY_MODULES = [ * be one property access away from the key creator with nothing in between — * and being absent from this list is precisely how it would stay green. */ - '@/lib/permission-groups/user-scope.server', + '@/ee/access-control/lib/user-scope.server', ] /** diff --git a/scripts/check-permission-group-enforcement.ts b/scripts/check-permission-group-enforcement.ts index 6f16b5c825f..cc4dfa5cfd1 100644 --- a/scripts/check-permission-group-enforcement.ts +++ b/scripts/check-permission-group-enforcement.ts @@ -83,8 +83,8 @@ const ROOT = resolve(SCRIPT_DIR, '..') * (and `walk`) at the same time as moving one, not afterwards. */ const SCAN_ROOTS = ['apps/sim/lib', 'apps/sim/app', 'apps/sim/ee', 'apps/sim/executor'] -const CAPABILITIES_FILE = 'apps/sim/lib/permission-groups/capabilities.ts' -const FIELDS_FILE = 'apps/sim/lib/permission-groups/fields.ts' +const CAPABILITIES_FILE = 'apps/sim/ee/access-control/lib/capabilities.ts' +const FIELDS_FILE = 'apps/sim/ee/access-control/lib/fields.ts' const ENFORCED_ANNOTATION = 'permission-group-enforced:' const EXEMPT_ANNOTATION = 'permission-group-exempt:' const MAX_ANNOTATION_LOOKBACK = 3 diff --git a/scripts/check-tool-registry-boundary.baseline.json b/scripts/check-tool-registry-boundary.baseline.json index e54d2f37dbc..56afd6f02a0 100644 --- a/scripts/check-tool-registry-boundary.baseline.json +++ b/scripts/check-tool-registry-boundary.baseline.json @@ -722,8 +722,8 @@ "apps/sim/blocks/registry.ts": 511, "apps/sim/blocks/registry-maps.ts": 509, "apps/sim/blocks/blocks/credential-group.ts": 114, - "apps/sim/lib/permission-groups/config-scope.server.ts": 91, - "apps/sim/lib/permission-groups/resolve.server.ts": 89, + "apps/sim/ee/access-control/lib/config-scope.server.ts": 91, + "apps/sim/ee/access-control/lib/resolve.server.ts": 89, "apps/sim/stores/workflows/registry/store.ts": 88 } } diff --git a/scripts/generate-block-successors.ts b/scripts/generate-block-successors.ts index 5a60ddaa047..f90ada2f2db 100644 --- a/scripts/generate-block-successors.ts +++ b/scripts/generate-block-successors.ts @@ -4,7 +4,7 @@ * * The map answers one question — "which block type is an allowlist decision * about this id really made against?" — and it has to be answerable from - * `lib/permission-groups/`, which `scripts/check-application-graph.ts` forbids + * `ee/access-control/lib/`, which `scripts/check-application-graph.ts` forbids * from importing `blocks/`: the authorization funnel would pull every block * definition into every surface that authorizes anything. Before this file the * answer was reachable only through `getBlock`, so the env allowlist was @@ -26,7 +26,7 @@ import { formatGeneratedSource } from './format-generated-source' const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url)) const ROOT = resolve(SCRIPT_DIR, '..') -const OUTPUT_PATH = resolve(ROOT, 'apps/sim/lib/permission-groups/block-successors.generated.ts') +const OUTPUT_PATH = resolve(ROOT, 'apps/sim/ee/access-control/lib/block-successors.generated.ts') const CHECK_MODE = process.argv.includes('--check') interface SunsetBlock { @@ -112,7 +112,7 @@ function render(successors: ReadonlyMap): string { * * Maps a retired block type to the *terminal* type an access-control decision * about it is made against — \`sunset.replacedBy\`, followed transitively. It - * exists as a generated projection because \`lib/permission-groups/\` may not + * exists as a generated projection because \`ee/access-control/lib/\` may not * import \`blocks/\`; see \`scripts/generate-block-successors.ts\`. */ export const BLOCK_ACCESS_SUCCESSORS: Record = {