feat(ee): add enterprise modules (#3121)

This commit is contained in:
Waleed
2026-02-02 23:40:18 -08:00
committed by GitHub
parent a9b7d75d87
commit 9c3fd1f7af
36 changed files with 110 additions and 139 deletions

View File

@@ -1,6 +1,6 @@
import { redirect } from 'next/navigation'
import { getEnv, isTruthy } from '@/lib/core/config/env'
import SSOForm from '@/app/(auth)/sso/sso-form'
import SSOForm from '@/ee/sso/components/sso-form'
export const dynamic = 'force-dynamic'

View File

@@ -29,7 +29,7 @@ import { hasWorkspaceAdminAccess } from '@/lib/workspaces/permissions/utils'
import {
InvitationsNotAllowedError,
validateInvitationsAllowed,
} from '@/executor/utils/permission-check'
} from '@/ee/access-control/utils/permission-check'
const logger = createLogger('OrganizationInvitations')

View File

@@ -102,7 +102,7 @@ describe('Workspace Invitations API Route', () => {
inArray: vi.fn().mockImplementation((field, values) => ({ type: 'inArray', field, values })),
}))
vi.doMock('@/executor/utils/permission-check', () => ({
vi.doMock('@/ee/access-control/utils/permission-check', () => ({
validateInvitationsAllowed: vi.fn().mockResolvedValue(undefined),
InvitationsNotAllowedError: class InvitationsNotAllowedError extends Error {
constructor() {

View File

@@ -21,7 +21,7 @@ import { getFromEmailAddress } from '@/lib/messaging/email/utils'
import {
InvitationsNotAllowedError,
validateInvitationsAllowed,
} from '@/executor/utils/permission-check'
} from '@/ee/access-control/utils/permission-check'
export const dynamic = 'force-dynamic'
@@ -38,7 +38,6 @@ export async function GET(req: NextRequest) {
}
try {
// Get all workspaces where the user has permissions
const userWorkspaces = await db
.select({ id: workspace.id })
.from(workspace)
@@ -55,10 +54,8 @@ export async function GET(req: NextRequest) {
return NextResponse.json({ invitations: [] })
}
// Get all workspaceIds where the user is a member
const workspaceIds = userWorkspaces.map((w) => w.id)
// Find all invitations for those workspaces
const invitations = await db
.select()
.from(workspaceInvitation)

View File

@@ -14,11 +14,11 @@ import {
ChatMessageContainer,
EmailAuth,
PasswordAuth,
SSOAuth,
VoiceInterface,
} from '@/app/chat/components'
import { CHAT_ERROR_MESSAGES, CHAT_REQUEST_TIMEOUT_MS } from '@/app/chat/constants'
import { useAudioStreaming, useChatStreaming } from '@/app/chat/hooks'
import SSOAuth from '@/ee/sso/components/sso-auth'
const logger = createLogger('ChatClient')

View File

@@ -1,6 +1,5 @@
export { default as EmailAuth } from './auth/email/email-auth'
export { default as PasswordAuth } from './auth/password/password-auth'
export { default as SSOAuth } from './auth/sso/sso-auth'
export { ChatErrorState } from './error-state/error-state'
export { ChatHeader } from './header/header'
export { ChatInput } from './input/input'

View File

@@ -1,7 +1,7 @@
import { redirect } from 'next/navigation'
import { getSession } from '@/lib/auth'
import { verifyWorkspaceMembership } from '@/app/api/workflows/utils'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
import { Knowledge } from './knowledge'
interface KnowledgePageProps {
@@ -23,7 +23,6 @@ export default async function KnowledgePage({ params }: KnowledgePageProps) {
redirect('/')
}
// Check permission group restrictions
const permissionConfig = await getUserPermissionConfig(session.user.id)
if (permissionConfig?.hideKnowledgeBaseTab) {
redirect(`/workspace/${workspaceId}`)

View File

@@ -6,7 +6,7 @@ import { getSession } from '@/lib/auth'
import { verifyWorkspaceMembership } from '@/app/api/workflows/utils'
import type { Template as WorkspaceTemplate } from '@/app/workspace/[workspaceId]/templates/templates'
import Templates from '@/app/workspace/[workspaceId]/templates/templates'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
interface TemplatesPageProps {
params: Promise<{

View File

@@ -246,7 +246,6 @@ export function CredentialSets() {
setNewSetDescription('')
setNewSetProvider('google-email')
// Open detail view for the newly created group
if (result?.credentialSet) {
setViewingSet(result.credentialSet)
}
@@ -336,7 +335,6 @@ export function CredentialSets() {
email,
})
// Start 60s cooldown
setResendCooldowns((prev) => ({ ...prev, [invitationId]: 60 }))
const interval = setInterval(() => {
setResendCooldowns((prev) => {
@@ -393,7 +391,6 @@ export function CredentialSets() {
return <GmailIcon className='h-4 w-4' />
}
// All hooks must be called before any early returns
const activeMemberships = useMemo(
() => memberships.filter((m) => m.status === 'active'),
[memberships]
@@ -447,7 +444,6 @@ export function CredentialSets() {
<div className='flex h-full flex-col gap-[16px]'>
<div className='min-h-0 flex-1 overflow-y-auto'>
<div className='flex flex-col gap-[16px]'>
{/* Group Info */}
<div className='flex items-center gap-[16px]'>
<div className='flex items-center gap-[8px]'>
<span className='font-medium text-[13px] text-[var(--text-primary)]'>
@@ -471,7 +467,6 @@ export function CredentialSets() {
</div>
</div>
{/* Invite Section - Email Tags Input */}
<div className='flex flex-col gap-[4px]'>
<div className='flex items-center gap-[8px]'>
<TagInput
@@ -495,7 +490,6 @@ export function CredentialSets() {
{emailError && <p className='text-[12px] text-[var(--text-error)]'>{emailError}</p>}
</div>
{/* Members List - styled like team members */}
<div className='flex flex-col gap-[16px]'>
<h4 className='font-medium text-[14px] text-[var(--text-primary)]'>Members</h4>
@@ -519,7 +513,6 @@ export function CredentialSets() {
</p>
) : (
<div className='flex flex-col gap-[16px]'>
{/* Active Members */}
{activeMembers.map((member) => {
const name = member.userName || 'Unknown'
const avatarInitial = name.charAt(0).toUpperCase()
@@ -572,7 +565,6 @@ export function CredentialSets() {
)
})}
{/* Pending Invitations */}
{pendingInvitations.map((invitation) => {
const email = invitation.email || 'Unknown'
const emailPrefix = email.split('@')[0]
@@ -641,7 +633,6 @@ export function CredentialSets() {
</div>
</div>
{/* Footer Actions */}
<div className='mt-auto flex items-center justify-end'>
<Button onClick={handleBackToList} variant='tertiary'>
Back
@@ -822,7 +813,6 @@ export function CredentialSets() {
</div>
</div>
{/* Create Polling Group Modal */}
<Modal open={showCreateModal} onOpenChange={handleCloseCreateModal}>
<ModalContent size='sm'>
<ModalHeader>Create Polling Group</ModalHeader>
@@ -895,7 +885,6 @@ export function CredentialSets() {
</ModalContent>
</Modal>
{/* Leave Confirmation Modal */}
<Modal open={!!leavingMembership} onOpenChange={() => setLeavingMembership(null)}>
<ModalContent size='sm'>
<ModalHeader>Leave Polling Group</ModalHeader>
@@ -923,7 +912,6 @@ export function CredentialSets() {
</ModalContent>
</Modal>
{/* Delete Confirmation Modal */}
<Modal open={!!deletingSet} onOpenChange={() => setDeletingSet(null)}>
<ModalContent size='sm'>
<ModalHeader>Delete Polling Group</ModalHeader>

View File

@@ -1,4 +1,3 @@
export { AccessControl } from './access-control/access-control'
export { ApiKeys } from './api-keys/api-keys'
export { BYOK } from './byok/byok'
export { Copilot } from './copilot/copilot'
@@ -10,7 +9,6 @@ export { Files as FileUploads } from './files/files'
export { General } from './general/general'
export { Integrations } from './integrations/integrations'
export { MCP } from './mcp/mcp'
export { SSO } from './sso/sso'
export { Subscription } from './subscription/subscription'
export { TeamManagement } from './team-management/team-management'
export { WorkflowMcpServers } from './workflow-mcp-servers/workflow-mcp-servers'

View File

@@ -407,14 +407,12 @@ export function MCP({ initialServerId }: MCPProps) {
const [urlScrollLeft, setUrlScrollLeft] = useState(0)
const [headerScrollLeft, setHeaderScrollLeft] = useState<Record<string, number>>({})
// Auto-select server when initialServerId is provided
useEffect(() => {
if (initialServerId && servers.some((s) => s.id === initialServerId)) {
setSelectedServerId(initialServerId)
}
}, [initialServerId, servers])
// Force refresh tools when entering server detail view to detect stale schemas
useEffect(() => {
if (selectedServerId) {
forceRefreshTools(workspaceId)
@@ -717,7 +715,6 @@ export function MCP({ initialServerId }: MCPProps) {
`Refreshed MCP server: ${serverId}, workflows updated: ${result.workflowsUpdated}`
)
// If the active workflow was updated, reload its subblock values from DB
const activeWorkflowId = useWorkflowRegistry.getState().activeWorkflowId
if (activeWorkflowId && result.updatedWorkflowIds?.includes(activeWorkflowId)) {
logger.info(`Active workflow ${activeWorkflowId} was updated, reloading subblock values`)

View File

@@ -41,7 +41,6 @@ import { getEnv, isTruthy } from '@/lib/core/config/env'
import { isHosted } from '@/lib/core/config/feature-flags'
import { getUserRole } from '@/lib/workspaces/organization'
import {
AccessControl,
ApiKeys,
BYOK,
Copilot,
@@ -53,15 +52,16 @@ import {
General,
Integrations,
MCP,
SSO,
Subscription,
TeamManagement,
WorkflowMcpServers,
} from '@/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components'
import { TemplateProfile } from '@/app/workspace/[workspaceId]/w/components/sidebar/components/settings-modal/components/template-profile/template-profile'
import { AccessControl } from '@/ee/access-control/components/access-control'
import { SSO } from '@/ee/sso/components/sso-settings'
import { ssoKeys, useSSOProviders } from '@/ee/sso/hooks/sso'
import { generalSettingsKeys, useGeneralSettings } from '@/hooks/queries/general-settings'
import { organizationKeys, useOrganizations } from '@/hooks/queries/organization'
import { ssoKeys, useSSOProviders } from '@/hooks/queries/sso'
import { subscriptionKeys, useSubscriptionData } from '@/hooks/queries/subscription'
import { usePermissionConfig } from '@/hooks/use-permission-config'
import { useSettingsModalStore } from '@/stores/modals/settings/store'

43
apps/sim/ee/LICENSE Normal file
View File

@@ -0,0 +1,43 @@
Sim Enterprise License
Copyright (c) 2025-present Sim Studio, Inc.
This software and associated documentation files (the "Software") are licensed
under the following terms:
1. LICENSE GRANT
Subject to the terms of this license, Sim Studio, Inc. grants you a limited,
non-exclusive, non-transferable license to use the Software for:
- Development, testing, and evaluation purposes
- Internal non-production use
Production use of the Software requires a valid Sim Enterprise subscription.
2. RESTRICTIONS
You may not:
- Use the Software in production without a valid Enterprise subscription
- Modify, adapt, or create derivative works of the Software
- Redistribute, sublicense, or transfer the Software
- Remove or alter any proprietary notices in the Software
3. ENTERPRISE SUBSCRIPTION
Production deployment of enterprise features requires an active Sim Enterprise
subscription. Contact sales@simstudio.ai for licensing information.
4. DISCLAIMER
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
5. LIMITATION OF LIABILITY
IN NO EVENT SHALL SIM STUDIO, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
For questions about enterprise licensing, contact: sales@simstudio.ai

21
apps/sim/ee/README.md Normal file
View File

@@ -0,0 +1,21 @@
# Sim Enterprise Edition
This directory contains enterprise features that require a Sim Enterprise subscription
for production use.
## Features
- **SSO (Single Sign-On)**: OIDC and SAML authentication integration
- **Access Control**: Permission groups for fine-grained user access management
- **Credential Sets**: Shared credential pools for email polling workflows
## Licensing
See [LICENSE](./LICENSE) for terms. Development and testing use is permitted.
Production deployment requires an active Enterprise subscription.
## Architecture
Enterprise features are imported directly throughout the codebase. The `ee/` directory
is required at build time. Feature visibility is controlled at runtime via environment
variables (e.g., `NEXT_PUBLIC_ACCESS_CONTROL_ENABLED`, `NEXT_PUBLIC_SSO_ENABLED`).

View File

@@ -29,7 +29,6 @@ import type { PermissionGroupConfig } from '@/lib/permission-groups/types'
import { getUserColor } from '@/lib/workspaces/colors'
import { getUserRole } from '@/lib/workspaces/organization'
import { getAllBlocks } from '@/blocks'
import { useOrganization, useOrganizations } from '@/hooks/queries/organization'
import {
type PermissionGroup,
useBulkAddPermissionGroupMembers,
@@ -39,7 +38,8 @@ import {
usePermissionGroups,
useRemovePermissionGroupMember,
useUpdatePermissionGroup,
} from '@/hooks/queries/permission-groups'
} from '@/ee/access-control/hooks/permission-groups'
import { useOrganization, useOrganizations } from '@/hooks/queries/organization'
import { useSubscriptionData } from '@/hooks/queries/subscription'
import { PROVIDER_DEFINITIONS } from '@/providers/models'
import { getAllProviderIds } from '@/providers/utils'
@@ -255,7 +255,6 @@ export function AccessControl() {
queryEnabled
)
// Show loading while dependencies load, or while permission groups query is pending
const isLoading = orgsLoading || subLoading || (queryEnabled && groupsLoading)
const { data: organization } = useOrganization(activeOrganization?.id || '')
@@ -410,10 +409,8 @@ export function AccessControl() {
}, [viewingGroup, editingConfig])
const allBlocks = useMemo(() => {
// Filter out hidden blocks and start_trigger (which should never be disabled)
const blocks = getAllBlocks().filter((b) => !b.hideFromToolbar && b.type !== 'start_trigger')
return blocks.sort((a, b) => {
// Group by category: triggers first, then blocks, then tools
const categoryOrder = { triggers: 0, blocks: 1, tools: 2 }
const catA = categoryOrder[a.category] ?? 3
const catB = categoryOrder[b.category] ?? 3
@@ -555,10 +552,9 @@ export function AccessControl() {
}, [viewingGroup, editingConfig, activeOrganization?.id, updatePermissionGroup])
const handleOpenAddMembersModal = useCallback(() => {
const existingMemberUserIds = new Set(members.map((m) => m.userId))
setSelectedMemberIds(new Set())
setShowAddMembersModal(true)
}, [members])
}, [])
const handleAddSelectedMembers = useCallback(async () => {
if (!viewingGroup || selectedMemberIds.size === 0) return
@@ -891,7 +887,6 @@ export function AccessControl() {
prev
? {
...prev,
// When deselecting all, keep start_trigger allowed (it should never be disabled)
allowedIntegrations: allAllowed ? ['start_trigger'] : null,
}
: prev

View File

@@ -1,3 +1,5 @@
'use client'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import type { PermissionGroupConfig } from '@/lib/permission-groups/types'
import { fetchJson } from '@/hooks/selectors/helpers'

View File

@@ -11,55 +11,13 @@ import { isBillingEnabled } from '@/lib/core/config/feature-flags'
import { cn } from '@/lib/core/utils/cn'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { getUserRole } from '@/lib/workspaces/organization/utils'
import { SSO_TRUSTED_PROVIDERS } from '@/ee/sso/constants'
import { useConfigureSSO, useSSOProviders } from '@/ee/sso/hooks/sso'
import { useOrganizations } from '@/hooks/queries/organization'
import { useConfigureSSO, useSSOProviders } from '@/hooks/queries/sso'
import { useSubscriptionData } from '@/hooks/queries/subscription'
const logger = createLogger('SSO')
const TRUSTED_SSO_PROVIDERS = [
'okta',
'okta-saml',
'okta-prod',
'okta-dev',
'okta-staging',
'okta-test',
'azure-ad',
'azure-active-directory',
'azure-corp',
'azure-enterprise',
'adfs',
'adfs-company',
'adfs-corp',
'adfs-enterprise',
'auth0',
'auth0-prod',
'auth0-dev',
'auth0-staging',
'onelogin',
'onelogin-prod',
'onelogin-corp',
'jumpcloud',
'jumpcloud-prod',
'jumpcloud-corp',
'ping-identity',
'ping-federate',
'pingone',
'shibboleth',
'shibboleth-idp',
'google-workspace',
'google-sso',
'saml',
'saml2',
'saml-sso',
'oidc',
'oidc-sso',
'openid-connect',
'custom-sso',
'enterprise-sso',
'company-sso',
]
interface SSOProvider {
id: string
providerId: string
@@ -565,7 +523,7 @@ export function SSO() {
<Combobox
value={formData.providerId}
onChange={(value: string) => handleInputChange('providerId', value)}
options={TRUSTED_SSO_PROVIDERS.map((id) => ({
options={SSO_TRUSTED_PROVIDERS.map((id) => ({
label: id,
value: id,
}))}

View File

@@ -1,3 +1,7 @@
/**
* List of trusted SSO provider identifiers.
* Used for validation and autocomplete in SSO configuration.
*/
export const SSO_TRUSTED_PROVIDERS = [
'okta',
'okta-saml',

View File

@@ -1,3 +1,5 @@
'use client'
import { keepPreviousData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { organizationKeys } from '@/hooks/queries/organization'
@@ -75,39 +77,3 @@ export function useConfigureSSO() {
},
})
}
/**
* Delete SSO provider mutation
*/
interface DeleteSSOParams {
providerId: string
orgId?: string
}
export function useDeleteSSO() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async ({ providerId }: DeleteSSOParams) => {
const response = await fetch(`/api/auth/sso/providers/${providerId}`, {
method: 'DELETE',
})
if (!response.ok) {
const error = await response.json()
throw new Error(error.message || 'Failed to delete SSO provider')
}
return response.json()
},
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({ queryKey: ssoKeys.providers() })
if (variables.orgId) {
queryClient.invalidateQueries({
queryKey: organizationKeys.detail(variables.orgId),
})
}
},
})
}

View File

@@ -5,6 +5,7 @@ import {
hydrateUserFilesWithBase64,
} from '@/lib/uploads/utils/user-file-base64.server'
import { sanitizeInputFormat, sanitizeTools } from '@/lib/workflows/comparison/normalize'
import { validateBlockType } from '@/ee/access-control/utils/permission-check'
import {
BlockType,
buildResumeApiUrl,
@@ -31,7 +32,6 @@ import { streamingResponseFormatProcessor } from '@/executor/utils'
import { buildBlockExecutionError, normalizeError } from '@/executor/utils/errors'
import { isJSONString } from '@/executor/utils/json'
import { filterOutputForLog } from '@/executor/utils/output-filter'
import { validateBlockType } from '@/executor/utils/permission-check'
import type { VariableResolver } from '@/executor/variables/resolver'
import type { SerializedBlock } from '@/serializer/types'
import type { SubflowType } from '@/stores/workflows/workflow/types'

View File

@@ -6,6 +6,12 @@ import { createMcpToolId } from '@/lib/mcp/utils'
import { refreshTokenIfNeeded } from '@/app/api/auth/oauth/utils'
import { getAllBlocks } from '@/blocks'
import type { BlockOutput } from '@/blocks/types'
import {
validateBlockType,
validateCustomToolsAllowed,
validateMcpToolsAllowed,
validateModelProvider,
} from '@/ee/access-control/utils/permission-check'
import { AGENT, BlockType, DEFAULTS, REFERENCE, stripCustomToolPrefix } from '@/executor/constants'
import { memoryService } from '@/executor/handlers/agent/memory'
import type {
@@ -18,12 +24,6 @@ import type { BlockHandler, ExecutionContext, StreamingExecution } from '@/execu
import { collectBlockData } from '@/executor/utils/block-data'
import { buildAPIUrl, buildAuthHeaders } from '@/executor/utils/http'
import { stringifyJSON } from '@/executor/utils/json'
import {
validateBlockType,
validateCustomToolsAllowed,
validateMcpToolsAllowed,
validateModelProvider,
} from '@/executor/utils/permission-check'
import { executeProviderRequest } from '@/providers'
import { getProviderFromModel, transformBlockTool } from '@/providers/utils'
import type { SerializedBlock } from '@/serializer/types'

View File

@@ -4,11 +4,11 @@ import { createLogger } from '@sim/logger'
import { eq } from 'drizzle-orm'
import { refreshTokenIfNeeded } from '@/app/api/auth/oauth/utils'
import type { BlockOutput } from '@/blocks/types'
import { validateModelProvider } from '@/ee/access-control/utils/permission-check'
import { BlockType, DEFAULTS, EVALUATOR } from '@/executor/constants'
import type { BlockHandler, ExecutionContext } from '@/executor/types'
import { buildAPIUrl, buildAuthHeaders, extractAPIErrorMessage } from '@/executor/utils/http'
import { isJSONString, parseJSON, stringifyJSON } from '@/executor/utils/json'
import { validateModelProvider } from '@/executor/utils/permission-check'
import { calculateCost, getProviderFromModel } from '@/providers/utils'
import type { SerializedBlock } from '@/serializer/types'

View File

@@ -6,6 +6,7 @@ import { getBaseUrl } from '@/lib/core/utils/urls'
import { refreshTokenIfNeeded } from '@/app/api/auth/oauth/utils'
import { generateRouterPrompt, generateRouterV2Prompt } from '@/blocks/blocks/router'
import type { BlockOutput } from '@/blocks/types'
import { validateModelProvider } from '@/ee/access-control/utils/permission-check'
import {
BlockType,
DEFAULTS,
@@ -15,7 +16,6 @@ import {
} from '@/executor/constants'
import type { BlockHandler, ExecutionContext } from '@/executor/types'
import { buildAuthHeaders } from '@/executor/utils/http'
import { validateModelProvider } from '@/executor/utils/permission-check'
import { calculateCost, getProviderFromModel } from '@/providers/utils'
import type { SerializedBlock } from '@/serializer/types'

View File

@@ -1,3 +1,5 @@
'use client'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { fetchJson } from '@/hooks/selectors/helpers'

View File

@@ -1,3 +1,5 @@
'use client'
import { useMemo } from 'react'
import { getEnv, isTruthy } from '@/lib/core/config/env'
import { isAccessControlEnabled, isHosted } from '@/lib/core/config/feature-flags'
@@ -5,8 +7,8 @@ import {
DEFAULT_PERMISSION_GROUP_CONFIG,
type PermissionGroupConfig,
} from '@/lib/permission-groups/types'
import { useUserPermissionConfig } from '@/ee/access-control/hooks/permission-groups'
import { useOrganizations } from '@/hooks/queries/organization'
import { useUserPermissionConfig } from '@/hooks/queries/permission-groups'
export interface PermissionConfigResult {
config: PermissionGroupConfig

View File

@@ -59,8 +59,8 @@ import { sendEmail } from '@/lib/messaging/email/mailer'
import { getFromEmailAddress, getPersonalEmailFrom } from '@/lib/messaging/email/utils'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
import { syncAllWebhooksForCredentialSet } from '@/lib/webhooks/utils.server'
import { SSO_TRUSTED_PROVIDERS } from '@/ee/sso/constants'
import { createAnonymousSession, ensureAnonymousUserExists } from './anonymous'
import { SSO_TRUSTED_PROVIDERS } from './sso/constants'
const logger = createLogger('Auth')

View File

@@ -5,8 +5,8 @@ import { and, eq, isNull } from 'drizzle-orm'
import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils'
import { sanitizeForCopilot } from '@/lib/workflows/sanitization/json-sanitizer'
import { isHiddenFromDisplay } from '@/blocks/types'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
import { escapeRegExp } from '@/executor/constants'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import type { ChatContext } from '@/stores/panel/copilot/types'
export type AgentContextType =

View File

@@ -7,7 +7,7 @@ import {
} from '@/lib/copilot/tools/shared/schemas'
import { registry as blockRegistry, getLatestBlock } from '@/blocks/registry'
import { isHiddenFromDisplay, type SubBlockConfig } from '@/blocks/types'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
import { PROVIDER_DEFINITIONS } from '@/providers/models'
import { tools as toolsRegistry } from '@/tools/registry'
import { getTrigger, isTriggerValid } from '@/triggers'

View File

@@ -6,7 +6,7 @@ import {
type GetBlockOptionsResultType,
} from '@/lib/copilot/tools/shared/schemas'
import { registry as blockRegistry, getLatestBlock } from '@/blocks/registry'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
import { tools as toolsRegistry } from '@/tools/registry'
export const getBlockOptionsServerTool: BaseServerTool<

View File

@@ -6,7 +6,7 @@ import {
} from '@/lib/copilot/tools/shared/schemas'
import { registry as blockRegistry } from '@/blocks/registry'
import type { BlockConfig } from '@/blocks/types'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
export const getBlocksAndToolsServerTool: BaseServerTool<
ReturnType<typeof GetBlocksAndToolsInput.parse>,

View File

@@ -8,7 +8,7 @@ import {
} from '@/lib/copilot/tools/shared/schemas'
import { registry as blockRegistry } from '@/blocks/registry'
import { AuthMode, type BlockConfig, isHiddenFromDisplay } from '@/blocks/types'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
import { PROVIDER_DEFINITIONS } from '@/providers/models'
import { tools as toolsRegistry } from '@/tools/registry'
import { getTrigger, isTriggerValid } from '@/triggers'

View File

@@ -3,7 +3,7 @@ import { z } from 'zod'
import type { BaseServerTool } from '@/lib/copilot/tools/server/base-tool'
import { registry as blockRegistry } from '@/blocks/registry'
import type { BlockConfig } from '@/blocks/types'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
export const GetTriggerBlocksInput = z.object({})
export const GetTriggerBlocksResult = z.object({

View File

@@ -15,8 +15,8 @@ import { buildCanonicalIndex, isCanonicalPair } from '@/lib/workflows/subblocks/
import { TriggerUtils } from '@/lib/workflows/triggers/triggers'
import { getAllBlocks, getBlock } from '@/blocks/registry'
import type { BlockConfig, SubBlockConfig } from '@/blocks/types'
import { getUserPermissionConfig } from '@/ee/access-control/utils/permission-check'
import { EDGE, normalizeName, RESERVED_BLOCK_NAMES } from '@/executor/constants'
import { getUserPermissionConfig } from '@/executor/utils/permission-check'
import { generateLoopBlocks, generateParallelBlocks } from '@/stores/workflows/workflow/utils'
import { TRIGGER_RUNTIME_SUBBLOCK_IDS } from '@/triggers/constants'