mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
v0.6.38
28 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
30c5e82ab0 |
feat(ee): add enterprise audit logs settings page (#4111)
* feat(ee): add enterprise audit logs settings page with server-side search Add a new audit logs page under enterprise settings that displays all actions captured via recordAudit. Includes server-side search, resource type filtering, date range selection, and cursor-based pagination. - Add internal API route (app/api/audit-logs) with session auth - Extract shared query logic (buildFilterConditions, buildOrgScopeCondition, queryAuditLogs) into app/api/v1/audit-logs/query.ts - Refactor v1 and admin audit log routes to use shared query module - Add React Query hook with useInfiniteQuery and cursor pagination - Add audit logs UI with debounced search, combobox filters, expandable rows - Gate behind requiresHosted + requiresEnterprise navigation flags - Place all enterprise audit log code in ee/audit-logs/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * lint * fix(ee): fix build error and address PR review comments - Fix import path: @/lib/utils → @/lib/core/utils/cn - Guard against empty orgMemberIds array in buildOrgScopeCondition - Skip debounce effect on mount when search is already synced Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * lint * fix(ee): fix type error with unknown metadata in JSX expression Use ternary instead of && chain to prevent unknown type from being returned as ReactNode. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ee): align skeleton filter width with actual component layout Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * lint * feat(audit): add audit logging for passwords, credentials, and schedules - Add PASSWORD_RESET_REQUESTED audit on forget-password with user lookup - Add CREDENTIAL_CREATED/UPDATED/DELETED audit on credential CRUD routes with metadata (credentialType, providerId, updatedFields, envKey) - Add SCHEDULE_CREATED audit on schedule creation with cron/timezone metadata - Fix SCHEDULE_DELETED (was incorrectly using SCHEDULE_UPDATED for deletes) - Enhance existing schedule update/disable/reactivate audit with structured metadata (operation, updatedFields, sourceType, previousStatus) - Add CREDENTIAL resource type and Credential filter option to audit logs UI - Enhance password reset completed description with user email Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(audit): align metadata with established recordAudit patterns - Add actorName/actorEmail to all new credential and schedule audit calls to match the established pattern (e.g., api-keys, byok-keys, knowledge) - Add resourceId and resourceName to forget-password audit call - Enhance forget-password description with user email Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(testing): sync audit mock with new AuditAction and AuditResourceType entries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(audit-logs): derive resource type filter from AuditResourceType Instead of maintaining a separate hardcoded list, the filter dropdown now derives its options directly from the AuditResourceType const object. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(audit): enrich all recordAudit calls with structured metadata - Move resource type filter options to ee/audit-logs/constants.ts (derived from AuditResourceType, no separate list to maintain) - Remove export from internal cursor helpers in query.ts - Add 5 new AuditAction entries: BYOK_KEY_UPDATED, ENVIRONMENT_DELETED, INVITATION_RESENT, WORKSPACE_UPDATED, ORG_INVITATION_RESENT - Enrich ~80 recordAudit calls across the codebase with structured metadata (knowledge bases, connectors, documents, workspaces, members, invitations, workflows, deployments, templates, MCP servers, credential sets, organizations, permission groups, files, tables, notifications, copilot operations) - Sync audit mock with all new entries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(audit): remove redundant metadata fields duplicating top-level audit fields Remove metadata entries that duplicate resourceName, workspaceId, or other top-level recordAudit fields. Also remove noisy fileNames arrays from bulk document upload audits (kept fileCount). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(audit): split audit types from server-only log module Extract AuditAction, AuditResourceType, and their types into lib/audit/types.ts (client-safe, no @sim/db dependency). The server-only recordAudit stays in log.ts and re-exports the types for backwards compatibility. constants.ts now imports from types.ts directly, breaking the postgres -> tls client bundle chain. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(audit): escape LIKE wildcards in audit log search query Escape %, _, and \ characters in the search parameter before embedding in the LIKE pattern to prevent unintended broad matches. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(audit): use actual deletedCount in bulk API key revoke description The description was using keys.length (requested count) instead of deletedCount (actual count), which could differ if some keys didn't exist. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(audit-logs): fix OAuth label displaying as "Oauth" in filter dropdown ACRONYMS set stored 'OAuth' but lookup used toUpperCase() producing 'OAUTH' which never matched. Now store all acronyms uppercase and use a display override map for special casing like OAuth. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
1189400167 |
feat(enterprise): cloud whitelabeling for enterprise orgs (#4047)
* feat(enterprise): cloud whitelabeling for enterprise orgs * fix(enterprise): scope enterprise plan check to target org in whitelabel PUT * fix(enterprise): use isOrganizationOnEnterprisePlan for org-scoped enterprise check * fix(enterprise): allow clearing whitelabel fields and guard against empty update result * fix(enterprise): remove webp from logo accept attribute to match upload hook validation * improvement(billing): use isBillingEnabled instead of isProd for plan gate bypasses * fix(enterprise): show whitelabeling nav item when billing is enabled on non-hosted environments * fix(enterprise): accept relative paths for logoUrl since upload API returns /api/files/serve/ paths * fix(whitelabeling): prevent logo flash on refresh by hiding logo while branding loads * fix(whitelabeling): wire hover color through CSS token on tertiary buttons * fix(whitelabeling): show sim logo by default, only replace when org logo loads * fix(whitelabeling): cache org logo url in localstorage to eliminate flash on repeat visits * feat(whitelabeling): add wordmark support with drag/drop upload * updated turbo * fix(whitelabeling): defer localstorage read to effect to prevent hydration mismatch * fix(whitelabeling): use layout effect for cache read to eliminate logo flash before paint * fix(whitelabeling): cache theme css to eliminate color flash before org settings resolve * fix(whitelabeling): deduplicate HEX_COLOR_REGEX into lib/branding and remove mutation from useCallback deps * fix(whitelabeling): use cookie-based SSR cache to eliminate brand flash on all page loads * fix(whitelabeling): use !orgSettings condition to fix SSR brand cache injection React Query returns isLoading: false with data: undefined during SSR, so the previous brandingLoading condition was always false on the server — initialCache was never injected into brandConfig. Changing to !orgSettings correctly applies the cookie cache both during SSR and while the client-side query loads, eliminating the logo flash on hard refresh. |
||
|
|
89ae738745 |
feat(folders): soft-delete folders and show in Recently Deleted (#4001)
* feat(folders): soft-delete folders and show in Recently Deleted Folders are now soft-deleted (archived) instead of permanently removed, matching the existing pattern for workflows, tables, and knowledge bases. Users can restore folders from Settings > Recently Deleted. - Add `archivedAt` column to `workflowFolder` schema with index - Change folder deletion to set `archivedAt` instead of hard-delete - Add folder restore endpoint (POST /api/folders/[id]/restore) - Batch-restore all workflows inside restored folders in one transaction - Add scope filter to GET /api/folders (active/archived) - Add Folders tab to Recently Deleted settings page - Update delete modal messaging for restorable items - Change "This action cannot be undone" styling to muted text Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(testing): add FOLDER_RESTORED to audit mock Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(folders): atomic restore transaction and scope to folder-deleted workflows Address two review findings: - Wrap entire folder restore in a single DB transaction to prevent partial state if any step fails - Only restore workflows archived within 5s of the folder's archivedAt, so individually-deleted workflows are not silently un-deleted - Add folder_restored to PostHog event map Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(folders): simplify restore to remove hacky 5s time window The 5-second time window for scoping which workflows to restore was a fragile heuristic (magic number, race-prone, non-deterministic). Restoring a folder now restores all archived workflows in it, matching standard trash/recycle-bin behavior. Users can re-delete any workflow they don't want after restore. The single-transaction wrapping from the prior commit is kept — that was a legitimate atomicity fix. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(db): regenerate folder soft-delete migration with drizzle-kit Replace manually created migration with proper drizzle-kit generated one that includes the snapshot file, fixing CI schema sync check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(db): fix migration metadata formatting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(folders): scope restore to folder-deleted workflows via shared timestamp Use a single timestamp across the entire folder deletion — folders, workflows, schedules, webhooks, etc. all get the exact same archivedAt. On restore, match workflows by exact archivedAt equality with the folder's timestamp, so individually-deleted workflows are not silently un-deleted. - Add optional archivedAt to ArchiveWorkflowOptions (backwards-compatible) - Pass shared timestamp through deleteFolderRecursively → archiveWorkflowsByIdsInWorkspace - Filter restore with eq(workflow.archivedAt, folderArchivedAt) instead of isNotNull Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(workflows): clear folderId on restore when folder is archived or missing When individually restoring a workflow from Recently Deleted, check if its folder still exists and is active. If the folder is archived or missing, clear folderId so the workflow appears at root instead of being orphaned (invisible in sidebar). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(folders): format restoreFolderRecursively call to satisfy biome Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(folders): close remaining restore edge cases Three issues caught by audit: 1. Child folder restore used isNotNull instead of timestamp matching, so individually-deleted child folders would be incorrectly restored. Now uses eq(archivedAt, folderArchivedAt) for both workflows AND child folders — consistent and deterministic. 2. No workspace archived check — could restore a folder into an archived workspace. Now checks getWorkspaceWithOwner, matching the existing restoreWorkflow pattern. 3. Re-restoring an already-restored folder returned an error. Now returns success with zero counts (idempotent). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(folders): add archivedAt to optimistic folder creation objects Ensures optimistic folder objects include archivedAt: null for consistency with the database schema shape. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(folders): handle missing parent folder during restore reparenting If the parent folder row no longer exists (not just archived), the restored folder now correctly gets reparented to root instead of retaining a dangling parentId reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
a680cec78f |
fix(core): consolidate ID generation to prevent HTTP self-hosted crashes (#3977)
* fix(core): consolidate ID generation to prevent HTTP self-hosted crashes crypto.randomUUID() requires a secure context (HTTPS) in browsers, causing white-screen crashes on self-hosted HTTP deployments. This replaces all direct usage of crypto.randomUUID(), nanoid, and the uuid package with a central utility that falls back to crypto.getRandomValues() which works in all contexts. - Add generateId(), generateShortId(), isValidUuid() in @/lib/core/utils/uuid - Replace crypto.randomUUID() imports across ~220 server + client files - Replace nanoid imports with generateShortId() - Replace uuid package validate with isValidUuid() - Remove nanoid dependency from apps/sim and packages/testing - Remove browser polyfill script from layout.tsx - Update test mocks to target @/lib/core/utils/uuid - Update CLAUDE.md, AGENTS.md, cursor rules, claude rules Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * update bunlock * fix(core): remove UUID_REGEX shim, use isValidUuid directly * fix(core): remove deprecated uuid mock helpers that use vi.doMock --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
0abeac77e1 |
improvement(platform): standardize perms, audit logging, lifecycle across admin, copilot, ui actions (#3858)
* improvement(platform): standardize perms, audit logging, lifecycle mgmt across admin, copilot, ui actions * address comments * improve error codes * address bugbot comments * fix test |
||
|
|
d3d58a9615 |
Feat/improved logging (#3833)
* feat(logs): add additional metadata for workflow execution logs
* Revert "Feat(logs) upgrade mothership chat messages to error (#3772)"
This reverts commit
|
||
|
|
8a481b612d |
chore(config): clean up bun, turbo, and next.js config (#3788)
* chore(config): clean up bun, turbo, and next.js config * chore(ci): bump bun to 1.3.11 in dockerfiles and workflows |
||
|
|
a64afac075 |
feat(kb): harden sync engine and add connector audit logging (#3697)
* feat(kb): harden sync engine and add connector audit logging - Fix stuck syncing status: added finally block in executeSync + stale lock recovery in cron scheduler (2hr TTL) - Fix token expiry mid-sync: refresh OAuth token between pagination pages and before deferred content hydration - GitHub deferred content loading: use Git blob SHA for change detection, only fetch content for new/changed docs - Add network error keywords to isRetryableError (fetch failed, econnreset, etc.) - Extract sanitizeStorageTitle helper to fix S3 key length limit issues - Add audit logging for connector CRUD, sync triggers, document exclude/restore, and resource restoration paths * lint * fix(tests): update audit mock and route tests for new audit actions * fix(kb): address PR review - finally block race, contentHash propagation, resourceName - Replace DB-read finally block with local syncExitedCleanly flag to avoid race condition - Propagate fullDoc.contentHash during deferred content hydration - Add resourceName to file restore audit record * fix(audit): include fileId in file restore audit description |
||
|
|
5b9f0d73c2 |
feat(mothership): mothership (#3411)
* Fix lint * improvement(sidebar): loading * fix(sidebar): use client-generated UUIDs for stable optimistic updates (#3439) * fix(sidebar): use client-generated UUIDs for stable optimistic updates * fix(folders): use zod schema validation for folder create API Replace inline UUID regex with zod schema validation for consistency with other API routes. Update test expectations accordingly. * fix(sidebar): add client UUID to single workflow duplicate hook The useDuplicateWorkflow hook was missing newId: crypto.randomUUID(), causing the same temp-ID-swap issue for single workflow duplication from the context menu. * fix(folders): avoid unnecessary Set re-creation in replaceOptimisticEntry Only create new expandedFolders/selectedFolders Sets when tempId differs from data.id. In the common happy path (client-generated UUIDs), this avoids unnecessary Zustand state reference changes and re-renders. * Mothership block logs * Fix mothership block logs * improvement(knowledge): make connector-synced document chunks readonly (#3440) * improvement(knowledge): make connector-synced document chunks readonly * fix(knowledge): enforce connector chunk readonly on server side * fix(knowledge): disable toggle and delete actions for connector-synced chunks * Job exeuction logs * Job logs * fix(connectors): remove unverifiable requiredScopes for Linear connector * fix(connectors): remove legacy requiredScopes from Jira and Confluence connectors Jira and Confluence OAuth tokens don't return legacy scope names like read:jira-work or read:confluence-content.all, causing the 'Update access' banner to always appear. Set requiredScopes to empty array like Linear. * feat(tasks): add rename to task context menu (#3442) * Revert "fix(connectors): remove legacy requiredScopes from Jira and Confluence connectors" This reverts commit |
||
|
|
72bb7e6945 |
fix(executor): skip Response block formatting for internal JWT callers (#3551)
* fix(executor): skip Response block formatting for internal JWT callers
The workflow executor tool received `{error: true}` despite successful child
workflow execution when the child had a Response block. This happened because
`createHttpResponseFromBlock()` hijacked the response with raw user-defined
data, and the executor's `transformResponse` expected the standard
`{success, executionId, output, metadata}` wrapper.
Fix: skip Response block formatting when `authType === INTERNAL_JWT` since
Response blocks are designed for external API consumers, not internal
workflow-to-workflow calls. Also extract `AuthType` constants from magic
strings across all auth type comparisons in the codebase.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test(executor): add route-level tests for Response block auth gating
Verify that internal JWT callers receive standard format while external
callers (API key, session) get Response block formatting. Tests the
server-side condition directly using workflowHasResponseBlock and
createHttpResponseFromBlock with AuthType constants.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(testing): add AuthType to all hybrid auth test mocks
Route code now imports AuthType from @/lib/auth/hybrid, so test mocks
must export it too. Added AuthTypeMock to @sim/testing and included it
in all 15 test files that mock the hybrid auth module.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
||
|
|
fadbad4085 |
feat(confluence): add get user by account ID tool (#3345)
* feat(confluence): add get user by account ID tool * feat(confluence): add missing tools for tasks, blog posts, spaces, descendants, permissions, and properties Add 16 new Confluence operations: list/get/update tasks, update/delete blog posts, create/update/delete spaces, get page descendants, list space permissions, list/create/delete space properties. Includes API routes, tool definitions, block config wiring, OAuth scopes, and generated docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(confluence): add missing OAuth scopes to auth.ts provider config The OAuth authorization flow uses scopes from auth.ts, not oauth.ts. The 9 new scopes were only added to oauth.ts and the block config but not to the actual provider config in auth.ts, causing re-auth to still return tokens without the new scopes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * lint * fix(confluence): fix truncated get_user tool description in docs Remove apostrophe from description that caused MDX generation to truncate at the escape character. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(confluence): address PR review feedback - Move get_user from GET to POST to avoid exposing access token in URL - Add 400 validation for missing params in space-properties create/delete - Add null check for blog post version before update to prevent TypeError Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(confluence): add missing response fields for descendants and tasks - Add type and depth fields to page descendants (from Confluence API) - Add body field (storage format) to task list/get/update responses Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * lint * fix(confluence): use validatePathSegment for Atlassian account IDs validateAlphanumericId rejects valid Atlassian account IDs that contain colons (e.g. 557058:6b9c9931-4693-49c1-8b3a-931f1af98134). Use validatePathSegment with a custom pattern allowing colons instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ran lint * update mock * upgrade turborepo * fix(confluence): reject empty update body for space PUT Return 400 when neither name nor description is provided for space update, instead of sending an empty body to the Confluence API. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(confluence): remove spaceId requirement for create_space and fix list_tasks pagination - Remove create_space from spaceId condition array since creating a space doesn't require a space ID input - Remove list_tasks from generic supportsCursor array so it uses its dedicated handler that correctly passes assignedTo and status filters during pagination Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * ran lint * fixed type errors --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
3c470ab0f8 | fix(workflows): disallow duplicate workflow names at the same folder level (#3260) | ||
|
|
e24c824c9a |
feat(tables): added tables (#2867)
* updates * required * trashy table viewer * updates * updates * filtering ui * updates * updates * updates * one input mode * format * fix lints * improved errors * updates * updates * chages * doc strings * breaking down file * update comments with ai * updates * comments * changes * revert * updates * dedupe * updates * updates * updates * refactoring * renames & refactors * refactoring * updates * undo * update db * wand * updates * fix comments * fixes * simplify comments * u[dates * renames * better comments * validation * updates * updates * updates * fix sorting * fix appearnce * updating prompt to make it user sort * rm * updates * rename * comments * clean comments * simplicifcaiton * updates * updates * refactor * reduced type confusion * undo * rename * undo changes * undo * simplify * updates * updates * revert * updates * db updates * type fix * fix * fix error handling * updates * docs * docs * updates * rename * dedupe * revert * uncook * updates * fix * fix * fix * fix * prepare merge * readd migrations * add back missed code * migrate enrichment logic to general abstraction * address bugbot concerns * adhere to size limits for tables * remove conflicting migration * add back migrations * fix tables auth * fix permissive auth * fix lint * reran migrations * migrate to use tanstack query for all server state * update table-selector * update names * added tables to permission groups, updated subblock types --------- Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai> Co-authored-by: waleed <walif6@gmail.com> |
||
|
|
7c7c0fd955 |
feat(audit-log): add audit events for templates, billing, credentials, env, deployments, passwords (#3246)
* feat(audit-log): add audit events for templates, billing, credentials, env, deployments, passwords * improvement(audit-log): add actorName/actorEmail to all recordAudit calls * fix(audit-log): resolve user for password reset, add CREDENTIAL_SET_INVITATION_RESENT action * fix(audit-log): add workspaceId to deployment activation audit * improvement(audit-log): use better-auth callback for password reset audit, remove cast - Move password reset audit to onPasswordReset callback in auth config instead of coupling to better-auth's verification table internals - Remove ugly double-cast on workflowData.workspaceId in deployment activation * fix(audit-log): add missing actorName/actorEmail to workflow duplicate * improvement(audit-log): add resourceName to credential set invitation accept |
||
|
|
e37b4a926d |
feat(audit-log): add persistent audit log system with comprehensive route instrumentation (#3242)
* feat(audit-log): add persistent audit log system with comprehensive route instrumentation
* fix(audit-log): address PR review — nullable workspaceId, enum usage, remove redundant queries
- Make audit_log.workspace_id nullable with ON DELETE SET NULL (logs survive workspace/user deletion)
- Make audit_log.actor_id nullable with ON DELETE SET NULL
- Replace all 53 routes' string literal action/resourceType with AuditAction.X and AuditResourceType.X enums
- Fix empty workspaceId ('') → null for OAuth, form, and org routes to avoid FK violations
- Remove redundant DB queries in chat manage route (use checkChatAccess return data)
- Fix organization routes to pass workspaceId: null instead of organizationId
* fix(audit-log): replace remaining workspaceId '' fallbacks with null
* fix(audit-log): credential-set org IDs, workspace deletion FK, actorId fallback, string literal action
* reran migrations
* fix(mcp,audit): tighten env var domain bypass, add post-resolution check, form workspaceId
- Only bypass MCP domain check when env var is in hostname/authority, not path/query
- Add post-resolution validateMcpDomain call in test-connection endpoint
- Match client-side isDomainAllowed to same hostname-only bypass logic
- Return workspaceId from checkFormAccess, use in form audit logs
- Add 49 comprehensive domain-check tests covering all edge cases
* fix(mcp): stateful regex lastIndex bug, RFC 3986 authority parsing
- Remove /g flag from module-level ENV_VAR_PATTERN to avoid lastIndex state
- Create fresh regex instances per call in server-side hasEnvVarInHostname
- Fix authority extraction to terminate at /, ?, or # per RFC 3986
- Prevents bypass via https://evil.com?token={{SECRET}} (no path)
- Add test cases for query-only and fragment-only env var URLs (53 total)
* fix(audit-log): try/catch for never-throw contract, accept null actorName/Email, fix misleading action
- Wrap recordAudit body in try/catch so nanoid() or header extraction can't throw
- Accept string | null for actorName and actorEmail (session.user.name can be null)
- Normalize null -> undefined before insert to match DB column types
- Fix org members route: ORG_MEMBER_ADDED -> ORG_INVITATION_CREATED (sends invite, not adds member)
* improvement(audit-log): add resource names and specific invitation actions
* fix(audit-log): use validated chat record, add mock sync tests
|
||
|
|
36ec68d93e | fix(serializer): validate required fields for blocks without tools (#3137) | ||
|
|
8d846c5983 |
feat(async-jobs): async execution with job queue backends (#3134)
* feat(async-jobs): async execution with job queue backends * added migration * remove unused envvar, remove extraneous comments * ack comment * same for db * added dedicated async envvars for timeouts, updated helm * updated comment * ack comment * migrated routes to be more restful * ack comments --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> |
||
|
|
4db6e556b7 |
feat(canvas): added the ability to lock blocks (#3102)
* feat(canvas): added the ability to lock blocks * unlock duplicates of locked blocks * fix(duplicate): place duplicate outside locked container When duplicating a block that's inside a locked loop/parallel, the duplicate is now placed outside the container since nothing should be added to a locked container. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(duplicate): unlock all blocks when duplicating workflow - Server-side workflow duplication now sets locked: false for all blocks - regenerateWorkflowStateIds also unlocks blocks for templates - Client-side regenerateBlockIds already handled this (for paste/import) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix code block disabled state, allow unlock from editor * fix(lock): address code review feedback - Fix toggle enabled using first toggleable block, not first block - Delete button now checks isParentLocked - Lock button now has disabled state - Editor lock icon distinguishes block vs parent lock state Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): prevent unlocking blocks inside locked containers - Editor: can't unlock block if parent container is locked - Action bar: can't unlock block if parent container is locked - Shows "Parent container is locked" tooltip in both cases Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): ensure consistent behavior across all UIs Block Menu, Editor, Action Bar now all have identical behavior: - Enable/Disable: disabled when locked OR parent locked - Flip Handles: disabled when locked OR parent locked - Delete: disabled when locked OR parent locked - Remove from Subflow: disabled when locked OR parent locked - Lock: always available for admins - Unlock: disabled when parent is locked (unlock parent first) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(enable): consistent behavior - can't enable if parent disabled Same pattern as lock: must enable parent container first before enabling children inside it. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs(quick-reference): add lock block action Added documentation for the lock/unlock block feature (admin only). Note: Image placeholder added, pending actual screenshot. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * remove prefix square brackets in error notif * add lock block image * fix(block-menu): paste should not be disabled for locked selection Paste creates new blocks, doesn't modify selected ones. Changed from disableEdit (includes lock state) to !userCanEdit (permission only), matching the Duplicate action behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(workflow): extract block deletion protection into shared utility Extract duplicated block protection logic from workflow.tsx into a reusable filterProtectedBlocks helper in utils/block-protection-utils.ts. This ensures consistent behavior between context menu delete and keyboard delete operations. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(workflow): extend block protection utilities for edge protection Add isEdgeProtected, filterUnprotectedEdges, and hasProtectedBlocks utilities. Refactor workflow.tsx to use these helpers for: - onEdgesChange edge removal filtering - onConnect connection prevention - onNodeDragStart drag prevention - Keyboard edge deletion - Block menu disableEdit calculation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): address review comments for lock feature 1. Store batchToggleEnabled now uses continue to skip locked blocks entirely, matching database operation behavior 2. Copilot add operation now checks if parent container is locked before adding nested nodes (defensive check for consistency) 3. Remove unused filterUnprotectedEdges function Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(copilot): add lock checks for insert and extract operations - insert_into_subflow: Check if existing block being moved is locked - extract_from_subflow: Check if block or parent subflow is locked These operations now match the UI behavior where locked blocks cannot be moved into/out of containers. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): prevent duplicates inside locked containers via regenerateBlockIds 1. regenerateBlockIds now checks if existing parent is locked before keeping the block inside it. If parent is locked, the duplicate is placed outside (parentId cleared) instead of creating an inconsistent state. 2. Remove unnecessary effectivePermissions.canAdmin and potentialParentId from onNodeDragStart dependency array. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): fix toggle locked target state and draggable check 1. BATCH_TOGGLE_LOCKED now uses first block from blocksToToggle set instead of blockIds[0], matching BATCH_TOGGLE_ENABLED pattern. Also added early exit if blocksToToggle is empty. 2. Blocks inside locked containers are now properly non-draggable. Changed draggable check from !block.locked to use isBlockProtected() which checks both block lock and parent container lock. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(copilot): check parent lock in edit and delete operations Both edit and delete operations now check if the block's parent container is locked, not just if the block itself is locked. This ensures consistent behavior with the UI which uses isBlockProtected utility that checks both direct lock and parent lock. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(socket): add server-side lock validation and admin-only permissions 1. BATCH_TOGGLE_LOCKED now requires admin role - non-admin users with write role can no longer bypass UI restriction via direct socket messages 2. BATCH_REMOVE_BLOCKS now validates lock status server-side - filters out protected blocks (locked or inside locked parent) before deletion 3. Remove duplicate/outdated comment in regenerateBlockIds Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test(socket): update permission test for admin-only lock toggle batch-toggle-locked is now admin-only, so write role should be denied. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(undo-redo): use consistent target state for toggle redo The redo logic for BATCH_TOGGLE_ENABLED and BATCH_TOGGLE_LOCKED was incorrectly computing each block's new state as !previousStates[blockId]. However, the store's batchToggleEnabled/batchToggleLocked set ALL blocks to the SAME target state based on the first block's previous state. Now redo computes targetState = !previousStates[firstBlockId] and applies it to all blocks, matching the store's behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(socket): add comprehensive lock validation across operations Based on audit findings, adds lock validation to multiple operations: 1. BATCH_TOGGLE_HANDLES - now skips locked/protected blocks at: - Store layer (batchToggleHandles) - Collaborative hook (collaborativeBatchToggleBlockHandles) - Server socket handler 2. BATCH_ADD_BLOCKS - server now filters blocks being added to locked parent containers 3. BATCH_UPDATE_PARENT - server now: - Skips protected blocks (locked or inside locked container) - Prevents moving blocks into locked containers All validations use consistent isProtected() helper that checks both direct lock and parent container lock. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(workflow): use pre-computed lock state from contextMenuBlocks contextMenuBlocks already has locked and isParentLocked properties computed in use-canvas-context-menu.ts, so there's no need to look up blocks again via hasProtectedBlocks. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): add lock validation to block rename operations Defense-in-depth: although the UI disables rename for locked blocks, the collaborative layer and server now also validate locks. - collaborativeUpdateBlockName: checks if block is locked or inside locked container before attempting rename - UPDATE_NAME server handler: checks lock status and parent lock before performing database update Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * added defense in depth for renaming locked blocks * fix(socket): add server-side lock validation for edges and subblocks Defense-in-depth: adds lock checks to server-side handlers that were previously relying only on client-side validation. Edge operations (ADD, REMOVE, BATCH_ADD, BATCH_REMOVE): - Check if source or target blocks are protected before modifying edges Subblock updates: - Check if parent block is protected before updating subblock values Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): fetch parent blocks for edge protection checks and consistent tooltip - Fixed edge operations to fetch parent blocks before checking lock status - Previously, isBlockProtected checked if parent was locked, but the parent wasn't in blocksById because only source/target blocks were fetched - Now fetches parent blocks for all four edge operations: ADD, REMOVE, BATCH_ADD_EDGES, BATCH_REMOVE_EDGES - Fixed tooltip inconsistency: changed "Run previous blocks first" to "Run upstream blocks first" in action-bar to match workflow.tsx Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * updated tooltip text for run from block * fix(lock): add lock check to duplicate button and clean up drag handler - Added lock check to duplicate button in action bar to prevent duplicating locked blocks (consistent with other edit operations) - Removed ineffective early return in onNodeDragStart since the `draggable` property on nodes already prevents dragging protected blocks - the early return was misleading as it couldn't actually stop a drag operation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(lock): use disableEdit for duplicate in block menu Changed duplicate menu item to use disableEdit (which includes lock check) instead of !userCanEdit for consistency with action bar and other edit operations. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> |
||
|
|
6f0a093869 |
fix(llm): update router and llm_chat tool to call providers routes (#2986)
* fix(llm): update router and llm_chat tool to call providers routes * updated failing tests |
||
|
|
78e4ca9d45 |
improvement(serializer): canonical subblock, serialization cleanups, schedules/webhooks are deployment version friendly (#2848)
* hide form deployment tab from docs * progress * fix resolution * cleanup code * fix positioning * cleanup dead sockets adv mode ops * address greptile comments * fix tests plus more simplification * fix cleanup * bring back advanced mode with specific definition * revert feature flags * improvement(subblock): ui * resolver change to make all var references optional chaining * fix(webhooks/schedules): deployment version friendly * fix tests * fix credential sets with new lifecycle * prep merge * add back migration * fix display check for adv fields * fix trigger vs block scoping --------- Co-authored-by: Emir Karabeg <emirkarabeg@berkeley.edu> |
||
|
|
a35f6eca03 |
improvement(tools): use react query to fetch child workflow schema, avoid refetch and duplicated utils, consolidated utils and testing mocks (#2839)
* improvement(tools): use react query to fetch child workflow schema, avoid refetch and duplicated utils * consolidated utils & testing mocks |
||
|
|
67440432bf |
fix(ops): fix subflow resizing on exit (#2760)
* fix(sockets): broadcast handles and enabled/disabled state * made all ops batched, removed all individual ops * fix subflow resizing on exit * removed unused custom event * fix failing tests, update testing * fix test mock |
||
|
|
05bbf34265 |
improvement(canvas): add multi-block select, add batch handle, enabled, and edge operations (#2738)
* improvement(canvas): add multi-block select, add batch handle, enabled, and edge operations * feat(i18n): update translations (#2732) Co-authored-by: icecrasher321 <icecrasher321@users.noreply.github.com> * don't allow flip handles for subflows * ack PR comments * more * fix missing handler * remove dead subflow-specific ops * remove unused code * fixed subflow ops * keep edges on subflow actions intact * fix subflow resizing * fix remove from subflow bulk * improvement(canvas): add multi-block select, add batch handle, enabled, and edge operations * don't allow flip handles for subflows * ack PR comments * more * fix missing handler * remove dead subflow-specific ops * remove unused code * fixed subflow ops * fix subflow resizing * keep edges on subflow actions intact * fixed copy from inside subflow * types improvement, preview fixes * fetch varible data in deploy modal * moved remove from subflow one position to the right * fix subflow issues * address greptile comment * fix test * improvement(preview): ui/ux * fix(preview): subflows * added batch add edges * removed recovery * use consolidated consts for sockets operations * more --------- Co-authored-by: icecrasher321 <icecrasher321@users.noreply.github.com> Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai> Co-authored-by: Emir Karabeg <emirkarabeg@berkeley.edu> |
||
|
|
79be435918 |
feat(email): welcome email; improvement(emails): ui/ux (#2658)
* feat(email): welcome email; improvement(emails): ui/ux * improvement(emails): links, accounts, preview * refactor(emails): file structure and wrapper components * added envvar for personal emails sent, added isHosted gate * fixed failing tests, added env mock * fix: removed comment --------- Co-authored-by: waleed <walif6@gmail.com> |
||
|
|
bf5d0a5573 |
feat(copy-paste): allow cross workflow selection, paste, move for blocks (#2649)
* feat(copy-paste): allow cross workflow selection, paste, move for blocks * fix drag options * add keyboard and mouse controls into docs * refactor sockets and undo/redo for batch additions and removals * fix tests * cleanup more code * fix perms issue * fix subflow copy/paste * remove log file * fit paste in viewport bounds * fix deselection |
||
|
|
71130c8b0a | improvement(monorepo): added tsconfig package, resolved type errors in testing package (#2613) | ||
|
|
d707d18ee6 |
fix(build): update dockerfile to contain testing package deps (#2591)
* fix(build): update dockerfile to contain testing package deps * added logger package |
||
|
|
b7f6bab282 |
feat(tests): added testing package, overhauled tests (#2586)
* feat(tests): added testing package, overhauled tests * fix build |