Compare commits

...

3 Commits

Author SHA1 Message Date
Waleed
7f1efcc798 fix(blocks): resolve Ollama models incorrectly requiring API key in Docker (#3976)
* fix(blocks): resolve Ollama models incorrectly requiring API key in Docker

Server-side validation failed for Ollama models like mistral:latest because
the Zustand providers store is empty on the server and getProviderFromModel
misidentified them via regex pattern matching (e.g. mistral:latest matched
Mistral AI's /^mistral/ pattern).

Replace the hardcoded CLOUD_PROVIDER_PREFIXES list with existing data sources:
- Provider store (definitive on client, checks all provider buckets)
- getBaseModelProviders() from PROVIDER_DEFINITIONS (server-side static cloud model lookup)
- Slash convention for dynamic cloud providers (fireworks/, openrouter/, etc.)
- isOllamaConfigured feature flag using existing OLLAMA_URL env var

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: remove getProviderFromModel regex fallback from API key validation

The fallback was the last piece of regex-based matching in the function and
only ran for self-hosted without OLLAMA_URL on the server — a path where
Ollama models cannot appear in the dropdown anyway.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* lint

* fix: handle vLLM models in store provider check

vLLM is a local model server like Ollama and should not require an API key.
Add vllm to the store provider check as a safety net for models that may
not have the vllm/ prefix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 12:14:52 -07:00
Waleed
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>
2026-04-05 11:28:54 -07:00
Waleed
235f0748ca feat(files): expand file editor to support more formats, add docx/xlsx preview (#3971)
* feat(files): expand file editor to support more formats, add docx/xlsx preview

* lint

* fix(files): narrow fileData type for closure in docx/xlsx preview effects

* fix(files): address PR review — fix xlsx type, simplify error helper, tighten iframe sandbox

* add mothership read externsions

* fix(files): update upload test — js is now a supported extension

* fix(files): deduplicate code extensions, handle dotless filenames

* fix(files): lower xlsx preview row cap to 1k and type workbookRef properly

Reduces XLSX_MAX_ROWS from 10,000 to 1,000 to prevent browser sluggishness
on large spreadsheets. Types workbookRef with the proper xlsx.WorkBook
interface instead of unknown, removing the unsafe cast.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(files): extract shared DataTable, isolate client-safe constants

- Move SUPPORTED_CODE_EXTENSIONS to validation-constants.ts so client
  components no longer transitively import Node's `path` module
- Extract shared DataTable component used by both CsvPreview and
  XlsxPreview, eliminating duplicated table markup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(validation): remove Node path import, use plain string extraction

Replace `import path from 'path'` with a simple `extractExtension` helper
that does `fileName.slice(fileName.lastIndexOf('.') + 1)`. This removes
the only Node module dependency from validation.ts, making it safe to
import from client components without pulling in a Node polyfill.

Deletes the unnecessary validation-constants.ts that was introduced as
a workaround — the constants now live back in validation.ts where they
belong.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* lint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-05 09:57:49 -07:00
330 changed files with 1803 additions and 1006 deletions

View File

@@ -9,5 +9,26 @@ Use TSDoc for documentation. No `====` separators. No non-TSDoc comments.
## Styling
Never update global styles. Keep all styling local to components.
## ID Generation
Never use `crypto.randomUUID()`, `nanoid`, or the `uuid` package directly. Use the utilities from `@/lib/core/utils/uuid`:
- `generateId()` — UUID v4, use by default
- `generateShortId(size?)` — short URL-safe ID (default 21 chars), for compact identifiers
Both use `crypto.getRandomValues()` under the hood and work in all contexts including non-secure (HTTP) browsers.
```typescript
// ✗ Bad
import { nanoid } from 'nanoid'
import { v4 as uuidv4 } from 'uuid'
const id = crypto.randomUUID()
// ✓ Good
import { generateId, generateShortId } from '@/lib/core/utils/uuid'
const uuid = generateId()
const shortId = generateShortId()
const tiny = generateShortId(8)
```
## Package Manager
Use `bun` and `bunx`, not `npm` and `npx`.

View File

@@ -16,5 +16,26 @@ Use TSDoc for documentation. No `====` separators. No non-TSDoc comments.
## Styling
Never update global styles. Keep all styling local to components.
## ID Generation
Never use `crypto.randomUUID()`, `nanoid`, or the `uuid` package directly. Use the utilities from `@/lib/core/utils/uuid`:
- `generateId()` — UUID v4, use by default
- `generateShortId(size?)` — short URL-safe ID (default 21 chars), for compact identifiers
Both use `crypto.getRandomValues()` under the hood and work in all contexts including non-secure (HTTP) browsers.
```typescript
// ✗ Bad
import { nanoid } from 'nanoid'
import { v4 as uuidv4 } from 'uuid'
const id = crypto.randomUUID()
// ✓ Good
import { generateId, generateShortId } from '@/lib/core/utils/uuid'
const uuid = generateId()
const shortId = generateShortId()
const tiny = generateShortId(8)
```
## Package Manager
Use `bun` and `bunx`, not `npm` and `npx`.

View File

@@ -7,6 +7,7 @@ You are a professional software engineer. All code must follow best practices: a
- **Logging**: Import `createLogger` from `@sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`
- **Comments**: Use TSDoc for documentation. No `====` separators. No non-TSDoc comments
- **Styling**: Never update global styles. Keep all styling local to components
- **ID Generation**: Never use `crypto.randomUUID()`, `nanoid`, or `uuid` package. Use `generateId()` (UUID v4) or `generateShortId()` (compact) from `@/lib/core/utils/uuid`
- **Package Manager**: Use `bun` and `bunx`, not `npm` and `npx`
## Architecture

View File

@@ -7,6 +7,7 @@ You are a professional software engineer. All code must follow best practices: a
- **Logging**: Import `createLogger` from `@sim/logger`. Use `logger.info`, `logger.warn`, `logger.error` instead of `console.log`
- **Comments**: Use TSDoc for documentation. No `====` separators. No non-TSDoc comments
- **Styling**: Never update global styles. Keep all styling local to components
- **ID Generation**: Never use `crypto.randomUUID()`, `nanoid`, or `uuid` package. Use `generateId()` (UUID v4) or `generateShortId()` (compact) from `@/lib/core/utils/uuid`
- **Package Manager**: Use `bun` and `bunx`, not `npm` and `npx`
## Architecture

View File

@@ -9,11 +9,11 @@ import { a2aAgent, workflow } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq, isNull, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { generateSkillsFromWorkflow } from '@/lib/a2a/agent-card'
import { A2A_DEFAULT_CAPABILITIES } from '@/lib/a2a/constants'
import { sanitizeAgentName } from '@/lib/a2a/utils'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { captureServerEvent } from '@/lib/posthog/server'
import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/persistence/utils'
import { hasValidStartBlockInState } from '@/lib/workflows/triggers/trigger-utils'
@@ -173,7 +173,7 @@ export async function POST(request: NextRequest) {
skillTags
)
const agentId = uuidv4()
const agentId = generateId()
const agentName = name || sanitizeAgentName(wf.name)
const [agent] = await db

View File

@@ -4,7 +4,6 @@ import { a2aAgent, a2aPushNotificationConfig, a2aTask, workflow } from '@sim/db/
import { createLogger } from '@sim/logger'
import { and, eq, isNull } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { A2A_DEFAULT_TIMEOUT, A2A_MAX_HISTORY_LENGTH } from '@/lib/a2a/constants'
import { notifyTaskStateChange } from '@/lib/a2a/push-notifications'
import {
@@ -18,6 +17,7 @@ import { acquireLock, getRedisClient, releaseLock } from '@/lib/core/config/redi
import { validateUrlWithDNS } from '@/lib/core/security/input-validation.server'
import { SSE_HEADERS } from '@/lib/core/utils/sse'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import { markExecutionCancelled } from '@/lib/execution/cancellation'
import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils'
import { getWorkspaceBilledAccountUserId } from '@/lib/workspaces/utils'
@@ -400,11 +400,11 @@ async function handleMessageSend(
const message = params.message
const taskId = message.taskId || generateTaskId()
const contextId = message.contextId || uuidv4()
const contextId = message.contextId || generateId()
// Distributed lock to prevent concurrent task processing
const lockKey = `a2a:task:${taskId}:lock`
const lockValue = uuidv4()
const lockValue = generateId()
const acquired = await acquireLock(lockKey, lockValue, 60)
if (!acquired) {
@@ -628,12 +628,12 @@ async function handleMessageStream(
}
const message = params.message
const contextId = message.contextId || uuidv4()
const contextId = message.contextId || generateId()
const taskId = message.taskId || generateTaskId()
// Distributed lock to prevent concurrent task processing
const lockKey = `a2a:task:${taskId}:lock`
const lockValue = uuidv4()
const lockValue = generateId()
const acquired = await acquireLock(lockKey, lockValue, 300)
if (!acquired) {
@@ -1427,7 +1427,7 @@ async function handlePushNotificationSet(
.where(eq(a2aPushNotificationConfig.id, existingConfig.id))
} else {
await db.insert(a2aPushNotificationConfig).values({
id: uuidv4(),
id: generateId(),
taskId: params.id,
url: config.url,
token: config.token || null,

View File

@@ -1,7 +1,7 @@
import type { Artifact, Message, PushNotificationConfig, Task, TaskState } from '@a2a-js/sdk'
import { v4 as uuidv4 } from 'uuid'
import { generateInternalToken } from '@/lib/auth/internal'
import { getInternalApiBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
/** A2A v0.3 JSON-RPC method names */
export const A2A_METHODS = {
@@ -85,7 +85,7 @@ export function isJSONRPCRequest(obj: unknown): obj is JSONRPCRequest {
}
export function generateTaskId(): string {
return uuidv4()
return generateId()
}
export function createTaskStatus(state: TaskState): { state: TaskState; timestamp: string } {

View File

@@ -2,7 +2,6 @@ import { db } from '@sim/db'
import { academyCertificate, user } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq } from 'drizzle-orm'
import { nanoid } from 'nanoid'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getCourseById } from '@/lib/academy/content'
@@ -10,6 +9,7 @@ import type { CertificateMetadata } from '@/lib/academy/types'
import { getSession } from '@/lib/auth'
import type { TokenBucketConfig } from '@/lib/core/rate-limiter'
import { RateLimiter } from '@/lib/core/rate-limiter'
import { generateShortId } from '@/lib/core/utils/uuid'
const logger = createLogger('AcademyCertificatesAPI')
@@ -106,7 +106,7 @@ export async function POST(req: NextRequest) {
const [certificate] = await db
.insert(academyCertificate)
.values({
id: nanoid(),
id: generateShortId(),
userId: session.user.id,
courseId,
status: 'active',
@@ -211,5 +211,5 @@ export async function GET(req: NextRequest) {
/** Generates a human-readable certificate number, e.g. SIM-2026-A3K9XZ2P */
function generateCertificateNumber(): string {
const year = new Date().getFullYear()
return `SIM-${year}-${nanoid(8).toUpperCase()}`
return `SIM-${year}-${generateShortId(8).toUpperCase()}`
}

View File

@@ -3,6 +3,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { env } from '@/lib/core/config/env'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
const logger = createLogger('ShopifyAuthorize')
@@ -161,7 +162,7 @@ export async function GET(request: NextRequest) {
const baseUrl = getBaseUrl()
const redirectUri = `${baseUrl}/api/auth/oauth2/callback/shopify`
const state = crypto.randomUUID()
const state = generateId()
const oauthUrl =
`https://${cleanShop}/admin/oauth/authorize?` +

View File

@@ -1,4 +1,4 @@
import { randomInt, randomUUID } from 'crypto'
import { randomInt } from 'crypto'
import { db } from '@sim/db'
import { chat, verification } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -10,6 +10,7 @@ import { getRedisClient } from '@/lib/core/config/redis'
import { addCorsHeaders, isEmailAllowed } from '@/lib/core/security/deployment'
import { getStorageMethod } from '@/lib/core/storage'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { sendEmail } from '@/lib/messaging/email/mailer'
import { setChatAuthCookie } from '@/app/api/chat/utils'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'
@@ -61,7 +62,7 @@ async function storeOTP(email: string, chatId: string, otp: string): Promise<voi
await db.transaction(async (tx) => {
await tx.delete(verification).where(eq(verification.identifier, identifier))
await tx.insert(verification).values({
id: randomUUID(),
id: generateId(),
identifier,
value,
expiresAt,

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import { chat, workflow } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -7,6 +6,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { addCorsHeaders, validateAuthToken } from '@/lib/core/security/deployment'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { preprocessExecution } from '@/lib/execution/preprocessing'
import { LoggingSession } from '@/lib/logs/execution/logging-session'
import { ChatFiles } from '@/lib/uploads'
@@ -103,7 +103,7 @@ export async function POST(
)
}
const executionId = randomUUID()
const executionId = generateId()
const loggingSession = new LoggingSession(
deployment.workflowId,
executionId,
@@ -150,7 +150,7 @@ export async function POST(
return addCorsHeaders(createErrorResponse('No input provided', 400), request)
}
const executionId = randomUUID()
const executionId = generateId()
const loggingSession = new LoggingSession(deployment.workflowId, executionId, 'chat', requestId)

View File

@@ -27,6 +27,7 @@ import {
createRequestTracker,
createUnauthorizedResponse,
} from '@/lib/copilot/request-helpers'
import { generateId } from '@/lib/core/utils/uuid'
import { captureServerEvent } from '@/lib/posthog/server'
import {
authorizeWorkflowByWorkspacePermission,
@@ -205,7 +206,7 @@ export async function POST(req: NextRequest) {
}
)
const userMessageIdToUse = userMessageId || crypto.randomUUID()
const userMessageIdToUse = userMessageId || generateId()
const reqLogger = logger.withMetadata({
requestId: tracker.requestId,
messageId: userMessageIdToUse,
@@ -406,8 +407,8 @@ export async function POST(req: NextRequest) {
}
if (stream) {
const executionId = crypto.randomUUID()
const runId = crypto.randomUUID()
const executionId = generateId()
const runId = generateId()
const sseStream = createSSEStream({
requestPayload,
userId: authenticatedUserId,
@@ -437,7 +438,7 @@ export async function POST(req: NextRequest) {
if (!result.success) return
const assistantMessage: Record<string, unknown> = {
id: crypto.randomUUID(),
id: generateId(),
role: 'assistant' as const,
content: result.content,
timestamp: new Date().toISOString(),
@@ -515,8 +516,8 @@ export async function POST(req: NextRequest) {
return new Response(sseStream, { headers: SSE_RESPONSE_HEADERS })
}
const nsExecutionId = crypto.randomUUID()
const nsRunId = crypto.randomUUID()
const nsExecutionId = generateId()
const nsRunId = generateId()
if (actualChatId) {
await createRunSegment({
@@ -576,7 +577,7 @@ export async function POST(req: NextRequest) {
}
const assistantMessage = {
id: crypto.randomUUID(),
id: generateId(),
role: 'assistant',
content: responseData.content,
timestamp: new Date().toISOString(),

View File

@@ -3,10 +3,10 @@ import { member, templateCreators } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq, or } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import type { CreatorProfileDetails } from '@/app/_types/creator-profile'
const logger = createLogger('CreatorProfilesAPI')
@@ -147,7 +147,7 @@ export async function POST(request: NextRequest) {
}
// Create the profile
const profileId = uuidv4()
const profileId = generateId()
const now = new Date()
const details: CreatorProfileDetails = {}

View File

@@ -9,6 +9,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { hasCredentialSetsAccess } from '@/lib/billing'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import { sendEmail } from '@/lib/messaging/email/mailer'
const logger = createLogger('CredentialSetInvite')
@@ -105,12 +106,12 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
const body = await req.json()
const { email } = createInviteSchema.parse(body)
const token = crypto.randomUUID()
const token = generateId()
const expiresAt = new Date()
expiresAt.setDate(expiresAt.getDate() + 7)
const invitation = {
id: crypto.randomUUID(),
id: generateId(),
credentialSetId: id,
email: email || null,
token,

View File

@@ -6,6 +6,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { hasCredentialSetsAccess } from '@/lib/billing'
import { generateId } from '@/lib/core/utils/uuid'
import { syncAllWebhooksForCredentialSet } from '@/lib/webhooks/utils.server'
const logger = createLogger('CredentialSetMembers')
@@ -167,7 +168,7 @@ export async function DELETE(req: NextRequest, { params }: { params: Promise<{ i
return NextResponse.json({ error: 'Member not found' }, { status: 404 })
}
const requestId = crypto.randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
// Use transaction to ensure member deletion + webhook sync are atomic
await db.transaction(async (tx) => {

View File

@@ -10,6 +10,7 @@ import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { syncAllWebhooksForCredentialSet } from '@/lib/webhooks/utils.server'
const logger = createLogger('CredentialSetInviteToken')
@@ -125,11 +126,11 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ tok
}
const now = new Date()
const requestId = crypto.randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
await db.transaction(async (tx) => {
await tx.insert(credentialSetMember).values({
id: crypto.randomUUID(),
id: generateId(),
credentialSetId: invitation.credentialSetId,
userId: session.user.id,
status: 'active',

View File

@@ -5,6 +5,7 @@ import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { syncAllWebhooksForCredentialSet } from '@/lib/webhooks/utils.server'
const logger = createLogger('CredentialSetMemberships')
@@ -60,7 +61,7 @@ export async function DELETE(req: NextRequest) {
}
try {
const requestId = crypto.randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
// Use transaction to ensure revocation + webhook sync are atomic
await db.transaction(async (tx) => {

View File

@@ -7,6 +7,7 @@ import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { hasCredentialSetsAccess } from '@/lib/billing'
import { generateId } from '@/lib/core/utils/uuid'
const logger = createLogger('CredentialSets')
@@ -150,7 +151,7 @@ export async function POST(req: Request) {
const now = new Date()
const newCredentialSet = {
id: crypto.randomUUID(),
id: generateId(),
organizationId,
name,
description: description || null,

View File

@@ -5,6 +5,7 @@ import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('CredentialMembersAPI')
@@ -133,7 +134,7 @@ export async function POST(request: NextRequest, context: RouteContext) {
}
await db.insert(credentialMember).values({
id: crypto.randomUUID(),
id: generateId(),
credentialId,
userId,
role,

View File

@@ -6,6 +6,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { encryptSecret } from '@/lib/core/security/encryption'
import { generateId } from '@/lib/core/utils/uuid'
import { getCredentialActorContext } from '@/lib/credentials/access'
import {
syncPersonalEnvCredentialsForUser,
@@ -273,7 +274,7 @@ export async function DELETE(
await db
.insert(workspaceEnvironment)
.values({
id: workspaceRow?.id || crypto.randomUUID(),
id: workspaceRow?.id || generateId(),
workspaceId: access.credential.workspaceId,
variables: current,
createdAt: workspaceRow?.createdAt || new Date(),

View File

@@ -5,6 +5,7 @@ import { and, eq, lt } from 'drizzle-orm'
import { NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('CredentialDraftAPI')
@@ -75,7 +76,7 @@ export async function POST(request: Request) {
await db
.insert(pendingCredentialDraft)
.values({
id: crypto.randomUUID(),
id: generateId(),
userId,
workspaceId,
providerId,

View File

@@ -7,6 +7,7 @@ import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { encryptSecret } from '@/lib/core/security/encryption'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { getWorkspaceMemberUserIds } from '@/lib/credentials/environment'
import { syncWorkspaceOAuthCredentialsForUser } from '@/lib/credentials/oauth'
import { getServiceConfigByProviderId } from '@/lib/oauth'
@@ -536,7 +537,7 @@ export async function POST(request: NextRequest) {
}
const now = new Date()
const credentialId = crypto.randomUUID()
const credentialId = generateId()
const [workspaceRow] = await db
.select({ ownerId: workspace.ownerId })
.from(workspace)
@@ -565,7 +566,7 @@ export async function POST(request: NextRequest) {
if (workspaceUserIds.length > 0) {
for (const memberUserId of workspaceUserIds) {
await tx.insert(credentialMember).values({
id: crypto.randomUUID(),
id: generateId(),
credentialId,
userId: memberUserId,
role:
@@ -582,7 +583,7 @@ export async function POST(request: NextRequest) {
}
} else {
await tx.insert(credentialMember).values({
id: crypto.randomUUID(),
id: generateId(),
credentialId,
userId: session.user.id,
role: 'admin',

View File

@@ -8,6 +8,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { decryptSecret, encryptSecret } from '@/lib/core/security/encryption'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { syncPersonalEnvCredentialsForUser } from '@/lib/credentials/environment'
import type { EnvironmentVariable } from '@/stores/settings/environment'
@@ -42,7 +43,7 @@ export async function POST(req: NextRequest) {
await db
.insert(environment)
.values({
id: crypto.randomUUID(),
id: generateId(),
userId: session.user.id,
variables: encryptedVariables,
updatedAt: new Date(),

View File

@@ -82,8 +82,12 @@ vi.mock('drizzle-orm', () => ({
sql: vi.fn((strings: unknown, ...values: unknown[]) => ({ type: 'sql', sql: strings, values })),
}))
vi.mock('uuid', () => ({
v4: vi.fn().mockReturnValue('test-uuid'),
vi.mock('@/lib/core/utils/uuid', () => ({
generateId: vi.fn(() => 'test-uuid'),
generateShortId: vi.fn(() => 'mock-short-id'),
isValidUuid: vi.fn((v: string) =>
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v)
),
}))
vi.mock('@/lib/auth', () => ({

View File

@@ -91,8 +91,12 @@ vi.mock('drizzle-orm', () => ({
sql: vi.fn((strings: unknown, ...values: unknown[]) => ({ type: 'sql', sql: strings, values })),
}))
vi.mock('uuid', () => ({
v4: vi.fn().mockReturnValue('test-uuid'),
vi.mock('@/lib/core/utils/uuid', () => ({
generateId: vi.fn(() => 'test-uuid'),
generateShortId: vi.fn(() => 'mock-short-id'),
isValidUuid: vi.fn((v: string) =>
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v)
),
}))
vi.mock('@/lib/auth', () => ({
@@ -458,10 +462,10 @@ describe('File Upload Security Tests', () => {
expect(response.status).toBe(200)
})
it('should reject JavaScript files', async () => {
it('should reject unsupported file types', async () => {
const formData = new FormData()
const maliciousJs = 'alert("XSS")'
const file = new File([maliciousJs], 'malicious.js', { type: 'application/javascript' })
const content = 'binary data'
const file = new File([content], 'archive.exe', { type: 'application/octet-stream' })
formData.append('file', file)
formData.append('context', 'workspace')
formData.append('workspaceId', 'test-workspace-id')
@@ -475,7 +479,7 @@ describe('File Upload Security Tests', () => {
expect(response.status).toBe(400)
const data = await response.json()
expect(data.message).toContain("File type 'js' is not allowed")
expect(data.message).toContain("File type 'exe' is not allowed")
})
it('should reject files without extensions', async () => {

View File

@@ -8,6 +8,7 @@ import { generateWorkspaceFileKey } from '@/lib/uploads/contexts/workspace/works
import { isImageFileType } from '@/lib/uploads/utils/file-utils'
import {
SUPPORTED_AUDIO_EXTENSIONS,
SUPPORTED_CODE_EXTENSIONS,
SUPPORTED_DOCUMENT_EXTENSIONS,
SUPPORTED_VIDEO_EXTENSIONS,
validateFileType,
@@ -23,6 +24,7 @@ const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'] as const
const ALLOWED_EXTENSIONS = new Set<string>([
...SUPPORTED_DOCUMENT_EXTENSIONS,
...SUPPORTED_CODE_EXTENSIONS,
...IMAGE_EXTENSIONS,
...SUPPORTED_AUDIO_EXTENSIONS,
...SUPPORTED_VIDEO_EXTENSIONS,

View File

@@ -7,6 +7,7 @@ import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { duplicateWorkflow } from '@/lib/workflows/persistence/duplicate'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
@@ -67,7 +68,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
const targetWorkspaceId = workspaceId || sourceFolder.workspaceId
const { newFolderId, folderMapping } = await db.transaction(async (tx) => {
const newFolderId = clientNewId || crypto.randomUUID()
const newFolderId = clientNewId || generateId()
const now = new Date()
const targetParentId = parentId ?? sourceFolder.parentId
@@ -227,7 +228,7 @@ async function duplicateFolderStructure(
)
for (const childFolder of childFolders) {
const newChildFolderId = crypto.randomUUID()
const newChildFolderId = generateId()
folderMapping.set(childFolder.id, newChildFolderId)
await tx.insert(workflowFolder).values({

View File

@@ -6,6 +6,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { captureServerEvent } from '@/lib/posthog/server'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'
@@ -92,7 +93,7 @@ export async function POST(request: NextRequest) {
)
}
const id = clientId || crypto.randomUUID()
const id = clientId || generateId()
const newFolder = await db.transaction(async (tx) => {
let sortOrder: number

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import { form, workflow, workflowBlocks } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -7,6 +6,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { addCorsHeaders, validateAuthToken } from '@/lib/core/security/deployment'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { preprocessExecution } from '@/lib/execution/preprocessing'
import { LoggingSession } from '@/lib/logs/execution/logging-session'
import { normalizeInputFormatValue } from '@/lib/workflows/input-format'
@@ -119,7 +119,7 @@ export async function POST(
)
}
const executionId = randomUUID()
const executionId = generateId()
const loggingSession = new LoggingSession(
deployment.workflowId,
executionId,
@@ -165,7 +165,7 @@ export async function POST(
return addCorsHeaders(createErrorResponse('No form data provided', 400), request)
}
const executionId = randomUUID()
const executionId = generateId()
const loggingSession = new LoggingSession(deployment.workflowId, executionId, 'form', requestId)
const preprocessResult = await preprocessExecution({

View File

@@ -3,13 +3,13 @@ import { form } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { isDev } from '@/lib/core/config/feature-flags'
import { encryptSecret } from '@/lib/core/security/encryption'
import { getEmailDomain } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import { deployWorkflow } from '@/lib/workflows/persistence/utils'
import {
checkWorkflowAccessForFormCreation,
@@ -158,7 +158,7 @@ export async function POST(request: NextRequest) {
encryptedPassword = encrypted
}
const id = uuidv4()
const id = generateId()
logger.info('Creating form deployment with values:', {
workflowId,

View File

@@ -9,6 +9,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { hasLiveSyncAccess } from '@/lib/billing/core/subscription'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { dispatchSync } from '@/lib/knowledge/connectors/sync-engine'
import { allocateTagSlots } from '@/lib/knowledge/constants'
import { createTagDefinition } from '@/lib/knowledge/tags/service'
@@ -211,7 +212,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
}
const now = new Date()
const connectorId = crypto.randomUUID()
const connectorId = generateId()
const nextSyncAt =
syncIntervalMinutes > 0 ? new Date(now.getTime() + syncIntervalMinutes * 60 * 1000) : null

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { deleteChunk, updateChunk } from '@/lib/knowledge/chunks/service'
import { checkChunkAccess } from '@/app/api/knowledge/utils'
@@ -17,7 +17,7 @@ export async function GET(
req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId, documentId, chunkId } = await params
try {
@@ -65,7 +65,7 @@ export async function PUT(
req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId, documentId, chunkId } = await params
try {
@@ -147,7 +147,7 @@ export async function DELETE(
req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string; chunkId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId, documentId, chunkId } = await params
try {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { SUPPORTED_FIELD_TYPES } from '@/lib/knowledge/constants'
import {
cleanupUnusedTagDefinitions,
@@ -34,7 +34,7 @@ export async function GET(
req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId, documentId } = await params
try {
@@ -79,7 +79,7 @@ export async function POST(
req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId, documentId } = await params
try {
@@ -160,7 +160,7 @@ export async function DELETE(
req: NextRequest,
{ params }: { params: Promise<{ id: string; documentId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId, documentId } = await params
const { searchParams } = new URL(req.url)
const action = searchParams.get('action') // 'cleanup' or 'all'

View File

@@ -1,10 +1,10 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
bulkDocumentOperation,
bulkDocumentOperationByFilter,
@@ -66,7 +66,7 @@ const BulkUpdateDocumentsSchema = z
})
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
try {
@@ -164,7 +164,7 @@ export async function GET(req: NextRequest, { params }: { params: Promise<{ id:
}
export async function POST(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
try {
@@ -398,7 +398,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
}
export async function PATCH(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
try {

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import { document } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -7,6 +6,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
createDocumentRecords,
deleteDocument,
@@ -35,7 +35,7 @@ const UpsertDocumentSchema = z.object({
})
export async function POST(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
try {

View File

@@ -1,7 +1,7 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { getNextAvailableSlot, getTagDefinitions } from '@/lib/knowledge/tags/service'
import { checkKnowledgeBaseAccess } from '@/app/api/knowledge/utils'
@@ -9,7 +9,7 @@ const logger = createLogger('NextAvailableSlotAPI')
// GET /api/knowledge/[id]/next-available-slot - Get the next available tag slot for a knowledge base and field type
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
const { searchParams } = new URL(req.url)
const fieldType = searchParams.get('fieldType')

View File

@@ -1,7 +1,7 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { deleteTagDefinition } from '@/lib/knowledge/tags/service'
import { checkKnowledgeBaseWriteAccess } from '@/app/api/knowledge/utils'
@@ -14,7 +14,7 @@ export async function DELETE(
req: NextRequest,
{ params }: { params: Promise<{ id: string; tagId: string }> }
) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId, tagId } = await params
try {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { AuthType, checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { SUPPORTED_FIELD_TYPES } from '@/lib/knowledge/constants'
import { createTagDefinition, getTagDefinitions } from '@/lib/knowledge/tags/service'
import { checkKnowledgeBaseWriteAccess } from '@/app/api/knowledge/utils'
@@ -13,7 +13,7 @@ const logger = createLogger('KnowledgeBaseTagDefinitionsAPI')
// GET /api/knowledge/[id]/tag-definitions - Get all tag definitions for a knowledge base
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
try {
@@ -53,7 +53,7 @@ export async function GET(req: NextRequest, { params }: { params: Promise<{ id:
// POST /api/knowledge/[id]/tag-definitions - Create a new tag definition
export async function POST(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
try {

View File

@@ -1,7 +1,7 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { getTagUsage } from '@/lib/knowledge/tags/service'
import { checkKnowledgeBaseAccess } from '@/app/api/knowledge/utils'
@@ -11,7 +11,7 @@ const logger = createLogger('TagUsageAPI')
// GET /api/knowledge/[id]/tag-usage - Get usage statistics for all tag definitions
export async function GET(req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const { id: knowledgeBaseId } = await params
try {

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'node:crypto'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'
import {
@@ -30,6 +29,7 @@ import { DIRECT_TOOL_DEFS, SUBAGENT_TOOL_DEFS } from '@/lib/copilot/tools/mcp/de
import { env } from '@/lib/core/config/env'
import { RateLimiter } from '@/lib/core/rate-limiter'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import {
authorizeWorkflowByWorkspacePermission,
resolveWorkflowIdForUser,
@@ -638,7 +638,7 @@ async function handleDirectToolCall(
)
const toolCall = {
id: randomUUID(),
id: generateId(),
name: toolDef.toolId,
status: 'pending' as const,
params: args as Record<string, any>,
@@ -715,7 +715,7 @@ async function handleBuildToolCall(
}
}
const chatId = randomUUID()
const chatId = generateId()
const requestPayload = {
message: requestText,
@@ -724,12 +724,12 @@ async function handleBuildToolCall(
model: DEFAULT_COPILOT_MODEL,
mode: 'agent',
commands: ['fast'],
messageId: randomUUID(),
messageId: generateId(),
chatId,
}
const executionId = crypto.randomUUID()
const runId = crypto.randomUUID()
const executionId = generateId()
const runId = generateId()
const messageId = requestPayload.messageId as string
await createRunSegment({

View File

@@ -4,6 +4,7 @@ import { createLogger } from '@sim/logger'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { generateId } from '@/lib/core/utils/uuid'
import {
McpDnsResolutionError,
McpDomainNotAllowedError,
@@ -102,7 +103,7 @@ export const POST = withMcpAuth('write')(
throw e
}
const serverId = body.url ? generateMcpServerId(workspaceId, body.url) : crypto.randomUUID()
const serverId = body.url ? generateMcpServerId(workspaceId, body.url) : generateId()
const [existingServer] = await db
.select({ id: mcpServers.id, deletedAt: mcpServers.deletedAt })

View File

@@ -4,6 +4,7 @@ import { createLogger } from '@sim/logger'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { generateId } from '@/lib/core/utils/uuid'
import { getParsedBody, withMcpAuth } from '@/lib/mcp/middleware'
import { mcpPubSub } from '@/lib/mcp/pubsub'
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
@@ -193,7 +194,7 @@ export const POST = withMcpAuth<RouteParams>('write')(
? body.parameterSchema
: await generateParameterSchemaForWorkflow(body.workflowId)
const toolId = crypto.randomUUID()
const toolId = generateId()
const [tool] = await db
.insert(workflowMcpTool)
.values({

View File

@@ -4,6 +4,7 @@ import { createLogger } from '@sim/logger'
import { and, eq, inArray, isNull, sql } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { generateId } from '@/lib/core/utils/uuid'
import { getParsedBody, withMcpAuth } from '@/lib/mcp/middleware'
import { mcpPubSub } from '@/lib/mcp/pubsub'
import { createMcpErrorResponse, createMcpSuccessResponse } from '@/lib/mcp/utils'
@@ -112,7 +113,7 @@ export const POST = withMcpAuth('write')(
)
}
const serverId = crypto.randomUUID()
const serverId = generateId()
const [server] = await db
.insert(workflowMcpServer)
@@ -168,7 +169,7 @@ export const POST = withMcpAuth('write')(
const parameterSchema = await generateParameterSchemaForWorkflow(workflowRecord.id)
const toolId = crypto.randomUUID()
const toolId = generateId()
await db.insert(workflowMcpTool).values({
id: toolId,
serverId,

View File

@@ -5,6 +5,7 @@ import { and, eq, isNull, like } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { checkWorkspaceAccess } from '@/lib/workspaces/permissions/utils'
const logger = createLogger('MemoryAPI')
@@ -163,7 +164,7 @@ export async function POST(request: NextRequest) {
const initialData = Array.isArray(data) ? data : [data]
const now = new Date()
const id = `mem_${crypto.randomUUID().replace(/-/g, '')}`
const id = `mem_${generateId().replace(/-/g, '')}`
const { sql } = await import('drizzle-orm')

View File

@@ -17,6 +17,7 @@ import { processContextsServer, resolveActiveResourceContext } from '@/lib/copil
import { createRequestTracker, createUnauthorizedResponse } from '@/lib/copilot/request-helpers'
import { taskPubSub } from '@/lib/copilot/task-events'
import { generateWorkspaceContext } from '@/lib/copilot/workspace-context'
import { generateId } from '@/lib/core/utils/uuid'
import {
assertActiveWorkspaceAccess,
getUserEntityPermissions,
@@ -109,7 +110,7 @@ export async function POST(req: NextRequest) {
userTimezone,
} = MothershipMessageSchema.parse(body)
const userMessageId = providedMessageId || crypto.randomUUID()
const userMessageId = providedMessageId || generateId()
userMessageIdForLogs = userMessageId
const reqLogger = logger.withMetadata({
requestId: tracker.requestId,
@@ -280,8 +281,8 @@ export async function POST(req: NextRequest) {
}
}
const executionId = crypto.randomUUID()
const runId = crypto.randomUUID()
const executionId = generateId()
const runId = generateId()
const stream = createSSEStream({
requestPayload,
userId: authenticatedUserId,
@@ -310,7 +311,7 @@ export async function POST(req: NextRequest) {
if (!result.success) return
const assistantMessage: Record<string, unknown> = {
id: crypto.randomUUID(),
id: generateId(),
role: 'assistant' as const,
content: result.content,
timestamp: new Date().toISOString(),

View File

@@ -7,6 +7,7 @@ import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { releasePendingChatStream } from '@/lib/copilot/chat-streaming'
import { taskPubSub } from '@/lib/copilot/task-events'
import { generateId } from '@/lib/core/utils/uuid'
const logger = createLogger('MothershipChatStopAPI')
@@ -71,7 +72,7 @@ export async function POST(req: NextRequest) {
if (hasContent || hasBlocks) {
const assistantMessage: Record<string, unknown> = {
id: crypto.randomUUID(),
id: generateId(),
role: 'assistant' as const,
content,
timestamp: new Date().toISOString(),

View File

@@ -6,6 +6,7 @@ import { createRunSegment } from '@/lib/copilot/async-runs/repository'
import { buildIntegrationToolSchemas } from '@/lib/copilot/chat-payload'
import { orchestrateCopilotStream } from '@/lib/copilot/orchestrator'
import { generateWorkspaceContext } from '@/lib/copilot/workspace-context'
import { generateId } from '@/lib/core/utils/uuid'
import {
assertActiveWorkspaceAccess,
getUserEntityPermissions,
@@ -50,8 +51,8 @@ export async function POST(req: NextRequest) {
await assertActiveWorkspaceAccess(workspaceId, userId)
const effectiveChatId = chatId || crypto.randomUUID()
messageId = crypto.randomUUID()
const effectiveChatId = chatId || generateId()
messageId = generateId()
const reqLogger = logger.withMetadata({ messageId })
const [workspaceContext, integrationTools, userPermission] = await Promise.all([
generateWorkspaceContext(workspaceId, userId),
@@ -72,8 +73,8 @@ export async function POST(req: NextRequest) {
...(userPermission ? { userPermission } : {}),
}
const executionId = crypto.randomUUID()
const runId = crypto.randomUUID()
const executionId = generateId()
const runId = generateId()
await createRunSegment({
id: runId,

View File

@@ -1,8 +1,8 @@
import { createLogger } from '@sim/logger'
import { nanoid } from 'nanoid'
import { type NextRequest, NextResponse } from 'next/server'
import { verifyCronAuth } from '@/lib/auth/internal'
import { acquireLock, releaseLock } from '@/lib/core/config/redis'
import { generateShortId } from '@/lib/core/utils/uuid'
import { pollInactivityAlerts } from '@/lib/notifications/inactivity-polling'
const logger = createLogger('InactivityAlertPoll')
@@ -13,7 +13,7 @@ const LOCK_KEY = 'inactivity-alert-polling-lock'
const LOCK_TTL_SECONDS = 120
export async function GET(request: NextRequest) {
const requestId = nanoid()
const requestId = generateShortId()
logger.info(`Inactivity alert polling triggered (${requestId})`)
let lockAcquired = false

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import {
invitation,
@@ -27,6 +26,7 @@ import { isOrgPlan, sqlIsPro } from '@/lib/billing/plan-helpers'
import { requireStripeClient } from '@/lib/billing/stripe-client'
import { ENTITLED_SUBSCRIPTION_STATUSES } from '@/lib/billing/subscriptions/utils'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import { syncWorkspaceEnvCredentials } from '@/lib/credentials/environment'
import { sendEmail } from '@/lib/messaging/email/mailer'
@@ -321,7 +321,7 @@ export async function PUT(
if (status === 'accepted') {
await tx.insert(member).values({
id: randomUUID(),
id: generateId(),
userId: session.user.id,
organizationId,
role: orgInvitation.role,
@@ -423,7 +423,7 @@ export async function PUT(
if (autoAddGroup) {
await tx.insert(permissionGroupMember).values({
id: randomUUID(),
id: generateId(),
permissionGroupId: autoAddGroup.id,
userId: session.user.id,
assignedBy: null,
@@ -497,7 +497,7 @@ export async function PUT(
}
} else {
await tx.insert(permissions).values({
id: randomUUID(),
id: generateId(),
entityType: 'workspace',
entityId: wsInvitation.workspaceId,
userId: session.user.id,

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import {
invitation,
@@ -24,6 +23,7 @@ import {
validateSeatAvailability,
} from '@/lib/billing/validation/seat-management'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import { sendEmail } from '@/lib/messaging/email/mailer'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
import { hasWorkspaceAdminAccess } from '@/lib/workspaces/permissions/utils'
@@ -293,7 +293,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) // 7 days
const invitationsToCreate = emailsToInvite.map((email: string) => ({
id: randomUUID(),
id: generateId(),
email,
inviterId: session.user.id,
organizationId,
@@ -310,8 +310,8 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
for (const email of emailsToInvite) {
const orgInviteForEmail = invitationsToCreate.find((inv) => inv.email === email)
for (const wsInvitation of validWorkspaceInvitations) {
const wsInvitationId = randomUUID()
const token = randomUUID()
const wsInvitationId = generateId()
const token = generateId()
await db.insert(workspaceInvitation).values({
id: wsInvitationId,

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import { invitation, member, organization, user, userStats } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -10,6 +9,7 @@ import { getSession } from '@/lib/auth'
import { getUserUsageData } from '@/lib/billing/core/usage'
import { validateSeatAvailability } from '@/lib/billing/validation/seat-management'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import { sendEmail } from '@/lib/messaging/email/mailer'
import { quickValidateEmail } from '@/lib/messaging/email/validation'
@@ -231,7 +231,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
}
// Create invitation
const invitationId = randomUUID()
const invitationId = generateId()
const expiresAt = new Date()
expiresAt.setDate(expiresAt.getDate() + 7) // 7 days expiry

View File

@@ -6,6 +6,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { hasAccessControlAccess } from '@/lib/billing'
import { generateId } from '@/lib/core/utils/uuid'
const logger = createLogger('PermissionGroupBulkMembers')
@@ -129,7 +130,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
}
const newMembers = usersToAdd.map((userId) => ({
id: crypto.randomUUID(),
id: generateId(),
permissionGroupId: id,
userId,
assignedBy: session.user.id,

View File

@@ -7,6 +7,7 @@ import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { hasAccessControlAccess } from '@/lib/billing'
import { generateId } from '@/lib/core/utils/uuid'
const logger = createLogger('PermissionGroupMembers')
@@ -137,7 +138,7 @@ export async function POST(req: NextRequest, { params }: { params: Promise<{ id:
}
const memberData = {
id: crypto.randomUUID(),
id: generateId(),
permissionGroupId: id,
userId,
assignedBy: session.user.id,

View File

@@ -7,6 +7,7 @@ import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { hasAccessControlAccess } from '@/lib/billing'
import { generateId } from '@/lib/core/utils/uuid'
import {
DEFAULT_PERMISSION_GROUP_CONFIG,
type PermissionGroupConfig,
@@ -181,7 +182,7 @@ export async function POST(req: Request) {
const now = new Date()
const newGroup = {
id: crypto.randomUUID(),
id: generateId(),
organizationId,
name,
description: description || null,

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { AuthType } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { preprocessExecution } from '@/lib/execution/preprocessing'
import { PauseResumeManager } from '@/lib/workflows/executor/human-in-the-loop-manager'
import { getWorkspaceBilledAccountUserId } from '@/lib/workspaces/utils'
@@ -60,7 +60,7 @@ export async function POST(
userId = billedAccountUserId
}
const resumeExecutionId = randomUUID()
const resumeExecutionId = generateId()
const requestId = generateRequestId()
logger.info(`[${requestId}] Preprocessing resume execution`, {

View File

@@ -132,8 +132,12 @@ vi.mock('@sim/db', () => ({
},
}))
vi.mock('uuid', () => ({
v4: vi.fn().mockReturnValue('schedule-execution-1'),
vi.mock('@/lib/core/utils/uuid', () => ({
generateId: vi.fn(() => 'schedule-execution-1'),
generateShortId: vi.fn(() => 'mock-short-id'),
isValidUuid: vi.fn((v: string) =>
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v)
),
}))
import { GET } from './route'

View File

@@ -2,11 +2,11 @@ import { db, workflowDeploymentVersion, workflowSchedule } from '@sim/db'
import { createLogger } from '@sim/logger'
import { and, eq, isNull, lt, lte, ne, not, or, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { verifyCronAuth } from '@/lib/auth/internal'
import { getJobQueue, shouldExecuteInline } from '@/lib/core/async-jobs'
import { createBullMQJobData, isBullMQEnabled } from '@/lib/core/bullmq'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { enqueueWorkspaceDispatch } from '@/lib/core/workspace-dispatch'
import {
executeJobInline,
@@ -89,7 +89,7 @@ export async function GET(request: NextRequest) {
const schedulePromises = dueSchedules.map(async (schedule) => {
const queueTime = schedule.lastQueuedAt ?? queuedAt
const executionId = uuidv4()
const executionId = generateId()
const correlation = {
executionId,
requestId,

View File

@@ -5,6 +5,7 @@ import { and, eq, isNull, or } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { captureServerEvent } from '@/lib/posthog/server'
import { validateCronExpression } from '@/lib/workflows/schedules/utils'
import { authorizeWorkflowByWorkspacePermission } from '@/lib/workflows/utils'
@@ -249,7 +250,7 @@ export async function POST(req: NextRequest) {
}
const now = new Date()
const id = crypto.randomUUID()
const id = generateId()
await db.insert(workflowSchedule).values({
id,

View File

@@ -4,6 +4,7 @@ import { createLogger } from '@sim/logger'
import { and, eq, isNull } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { generateId } from '@/lib/core/utils/uuid'
import { verifyEffectiveSuperUser } from '@/lib/templates/permissions'
import { parseWorkflowJson } from '@/lib/workflows/operations/import-export'
import {
@@ -118,7 +119,7 @@ export async function POST(request: NextRequest) {
}
// Create new workflow record
const newWorkflowId = crypto.randomUUID()
const newWorkflowId = generateId()
const now = new Date()
const dedupedName = await deduplicateWorkflowName(
`[Debug Import] ${sourceWorkflow.name}`,

View File

@@ -2,6 +2,7 @@ import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import {
batchInsertRows,
createTable,
@@ -225,7 +226,7 @@ export async function POST(request: NextRequest) {
let inserted = 0
for (let i = 0; i < coerced.length; i += MAX_BATCH_SIZE) {
const batch = coerced.slice(i, i + MAX_BATCH_SIZE)
const batchRequestId = crypto.randomUUID().slice(0, 8)
const batchRequestId = generateId().slice(0, 8)
const result = await batchInsertRows(
{ tableId: table.id, rows: batch, workspaceId, userId: authResult.userId },
table,

View File

@@ -3,9 +3,9 @@ import { templateStars, templates } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, eq, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
const logger = createLogger('TemplateStarAPI')
@@ -86,7 +86,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
await db.transaction(async (tx) => {
// Add the star record
await tx.insert(templateStars).values({
id: uuidv4(),
id: generateId(),
userId: session.user.id,
templateId: id,
starredAt: new Date(),

View File

@@ -3,10 +3,10 @@ import { templates, workflow, workflowDeploymentVersion } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { eq, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { getInternalApiBaseUrl } from '@/lib/core/utils/urls'
import { generateId } from '@/lib/core/utils/uuid'
import { canAccessTemplate, verifyTemplateOwnership } from '@/lib/templates/permissions'
import {
type RegenerateStateInput,
@@ -93,7 +93,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
const templateData = template[0]
// Create a new workflow ID
const newWorkflowId = uuidv4()
const newWorkflowId = generateId()
const now = new Date()
// Extract variables from the template state and remap to the new workflow
@@ -104,7 +104,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
if (!templateVariables || typeof templateVariables !== 'object') return {}
const mapped: Record<string, any> = {}
for (const [, variable] of Object.entries(templateVariables)) {
const newVarId = uuidv4()
const newVarId = generateId()
mapped[newVarId] = { ...variable, id: newVarId, workflowId: newWorkflowId }
}
return mapped
@@ -178,7 +178,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
// Create a deployment version for the new workflow
if (templateData.state) {
const newDeploymentVersionId = uuidv4()
const newDeploymentVersionId = generateId()
await tx.insert(workflowDeploymentVersion).values({
id: newDeploymentVersionId,
workflowId: newWorkflowId,

View File

@@ -9,11 +9,11 @@ import {
import { createLogger } from '@sim/logger'
import { and, desc, eq, ilike, or, sql } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
import { z } from 'zod'
import { AuditAction, AuditResourceType, recordAudit } from '@/lib/audit/log'
import { getSession } from '@/lib/auth'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
import { canAccessTemplate, verifyEffectiveSuperUser } from '@/lib/templates/permissions'
import {
extractRequiredCredentials,
@@ -267,7 +267,7 @@ export async function POST(request: NextRequest) {
return NextResponse.json({ error: permissionError || 'Access denied' }, { status: 403 })
}
const templateId = uuidv4()
const templateId = generateId()
const now = new Date()
// Get the active deployment version for the workflow to copy its state

View File

@@ -6,6 +6,7 @@ import { createA2AClient, extractTextContent, isTerminalState } from '@/lib/a2a/
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { validateUrlWithDNS } from '@/lib/core/security/input-validation.server'
import { generateRequestId } from '@/lib/core/utils/request'
import { generateId } from '@/lib/core/utils/uuid'
export const dynamic = 'force-dynamic'
@@ -142,7 +143,7 @@ export async function POST(request: NextRequest) {
const message: Message = {
kind: 'message',
messageId: crypto.randomUUID(),
messageId: generateId(),
role: 'user',
parts,
...(validatedData.taskId && { taskId: validatedData.taskId }),

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createRawDynamoDBClient, describeTable, listTables } from '@/app/api/tools/dynamodb/utils'
const logger = createLogger('DynamoDBIntrospectAPI')
@@ -15,7 +15,7 @@ const IntrospectSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMongoDBConnection, sanitizeCollectionName, validateFilter } from '../utils'
const logger = createLogger('MongoDBDeleteAPI')
@@ -38,7 +38,7 @@ const DeleteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let client = null
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMongoDBConnection, sanitizeCollectionName, validatePipeline } from '../utils'
const logger = createLogger('MongoDBExecuteAPI')
@@ -30,7 +30,7 @@ const ExecuteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let client = null
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMongoDBConnection, sanitizeCollectionName } from '../utils'
const logger = createLogger('MongoDBInsertAPI')
@@ -35,7 +35,7 @@ const InsertSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let client = null
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMongoDBConnection, executeIntrospect } from '../utils'
const logger = createLogger('MongoDBIntrospectAPI')
@@ -18,7 +18,7 @@ const IntrospectSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let client = null
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMongoDBConnection, sanitizeCollectionName, validateFilter } from '../utils'
const logger = createLogger('MongoDBQueryAPI')
@@ -47,7 +47,7 @@ const QuerySchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let client = null
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMongoDBConnection, sanitizeCollectionName, validateFilter } from '../utils'
const logger = createLogger('MongoDBUpdateAPI')
@@ -57,7 +57,7 @@ const UpdateSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let client = null
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { buildDeleteQuery, createMySQLConnection, executeQuery } from '@/app/api/tools/mysql/utils'
const logger = createLogger('MySQLDeleteAPI')
@@ -19,7 +19,7 @@ const DeleteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMySQLConnection, executeQuery, validateQuery } from '@/app/api/tools/mysql/utils'
const logger = createLogger('MySQLExecuteAPI')
@@ -18,7 +18,7 @@ const ExecuteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { buildInsertQuery, createMySQLConnection, executeQuery } from '@/app/api/tools/mysql/utils'
const logger = createLogger('MySQLInsertAPI')
@@ -40,7 +40,7 @@ const InsertSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMySQLConnection, executeIntrospect } from '@/app/api/tools/mysql/utils'
const logger = createLogger('MySQLIntrospectAPI')
@@ -17,7 +17,7 @@ const IntrospectSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createMySQLConnection, executeQuery, validateQuery } from '@/app/api/tools/mysql/utils'
const logger = createLogger('MySQLQueryAPI')
@@ -18,7 +18,7 @@ const QuerySchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { buildUpdateQuery, createMySQLConnection, executeQuery } from '@/app/api/tools/mysql/utils'
const logger = createLogger('MySQLUpdateAPI')
@@ -38,7 +38,7 @@ const UpdateSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
convertNeo4jTypesToJSON,
createNeo4jDriver,
@@ -23,7 +23,7 @@ const CreateSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let driver = null
let session = null

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createNeo4jDriver, validateCypherQuery } from '@/app/api/tools/neo4j/utils'
const logger = createLogger('Neo4jDeleteAPI')
@@ -20,7 +20,7 @@ const DeleteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let driver = null
let session = null

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
convertNeo4jTypesToJSON,
createNeo4jDriver,
@@ -23,7 +23,7 @@ const ExecuteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let driver = null
let session = null

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createNeo4jDriver } from '@/app/api/tools/neo4j/utils'
import type { Neo4jNodeSchema, Neo4jRelationshipSchema } from '@/tools/neo4j/types'
@@ -18,7 +18,7 @@ const IntrospectSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let driver = null
let session = null

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
convertNeo4jTypesToJSON,
createNeo4jDriver,
@@ -23,7 +23,7 @@ const MergeSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let driver = null
let session = null

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
convertNeo4jTypesToJSON,
createNeo4jDriver,
@@ -23,7 +23,7 @@ const QuerySchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let driver = null
let session = null

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
convertNeo4jTypesToJSON,
createNeo4jDriver,
@@ -23,7 +23,7 @@ const UpdateSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
let driver = null
let session = null

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import { account } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -6,6 +5,7 @@ import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { validateMicrosoftGraphId } from '@/lib/core/security/input-validation'
import { generateId } from '@/lib/core/utils/uuid'
import { refreshAccessTokenIfNeeded, resolveOAuthAccountId } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'
@@ -18,7 +18,7 @@ import type { MicrosoftGraphDriveItem } from '@/tools/onedrive/types'
* Get files (not folders) from Microsoft OneDrive
*/
export async function GET(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
logger.info(`[${requestId}] OneDrive files request received`)
try {

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import { account } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -6,6 +5,7 @@ import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { validateMicrosoftGraphId } from '@/lib/core/security/input-validation'
import { generateId } from '@/lib/core/utils/uuid'
import { refreshAccessTokenIfNeeded, resolveOAuthAccountId } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'
@@ -13,7 +13,7 @@ export const dynamic = 'force-dynamic'
const logger = createLogger('OneDriveFolderAPI')
export async function GET(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const session = await getSession()

View File

@@ -1,4 +1,3 @@
import { randomUUID } from 'crypto'
import { db } from '@sim/db'
import { account } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
@@ -6,6 +5,7 @@ import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { validateMicrosoftGraphId } from '@/lib/core/security/input-validation'
import { generateId } from '@/lib/core/utils/uuid'
import { refreshAccessTokenIfNeeded, resolveOAuthAccountId } from '@/app/api/auth/oauth/utils'
export const dynamic = 'force-dynamic'
@@ -18,7 +18,7 @@ import type { MicrosoftGraphDriveItem } from '@/tools/onedrive/types'
* Get folders from Microsoft OneDrive
*/
export async function GET(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const session = await getSession()

View File

@@ -1,9 +1,9 @@
import { randomUUID } from 'crypto'
import type { ItemCreateParams } from '@1password/sdk'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
connectRequest,
createOnePasswordClient,
@@ -28,7 +28,7 @@ const CreateItemSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {
@@ -55,7 +55,7 @@ export async function POST(request: NextRequest) {
const parsedFields = params.fields
? (JSON.parse(params.fields) as Array<Record<string, any>>).map((f) => ({
id: f.id || randomUUID().slice(0, 8),
id: f.id || generateId().slice(0, 8),
title: f.label || f.title || '',
fieldType: toSdkFieldType(f.type || 'STRING'),
value: f.value || '',

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { connectRequest, createOnePasswordClient, resolveCredentials } from '../utils'
const logger = createLogger('OnePasswordDeleteItemAPI')
@@ -17,7 +17,7 @@ const DeleteItemSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
connectRequest,
createOnePasswordClient,
@@ -22,7 +22,7 @@ const GetItemSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
connectRequest,
createOnePasswordClient,
@@ -21,7 +21,7 @@ const GetVaultSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
connectRequest,
createOnePasswordClient,
@@ -22,7 +22,7 @@ const ListItemsSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
connectRequest,
createOnePasswordClient,
@@ -21,7 +21,7 @@ const ListVaultsSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {

View File

@@ -1,9 +1,9 @@
import { randomUUID } from 'crypto'
import type { Item } from '@1password/sdk'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
connectRequest,
createOnePasswordClient,
@@ -26,7 +26,7 @@ const ReplaceItemSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {
@@ -57,7 +57,7 @@ export async function POST(request: NextRequest) {
vaultId: params.vaultId,
fields: itemData.fields
? (itemData.fields as Array<Record<string, any>>).map((f) => ({
id: f.id || randomUUID().slice(0, 8),
id: f.id || generateId().slice(0, 8),
title: f.label || f.title || '',
fieldType: toSdkFieldType(f.type || 'STRING'),
value: f.value || '',

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createOnePasswordClient, resolveCredentials } from '../utils'
const logger = createLogger('OnePasswordResolveSecretAPI')
@@ -16,7 +16,7 @@ const ResolveSecretSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
connectRequest,
createOnePasswordClient,
@@ -23,7 +23,7 @@ const UpdateItemSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
const auth = await checkInternalAuth(request)
if (!auth.success || !auth.userId) {

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createPostgresConnection, executeDelete } from '@/app/api/tools/postgresql/utils'
const logger = createLogger('PostgreSQLDeleteAPI')
@@ -19,7 +19,7 @@ const DeleteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import {
createPostgresConnection,
executeQuery,
@@ -22,7 +22,7 @@ const ExecuteSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createPostgresConnection, executeInsert } from '@/app/api/tools/postgresql/utils'
const logger = createLogger('PostgreSQLInsertAPI')
@@ -40,7 +40,7 @@ const InsertSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

View File

@@ -1,8 +1,8 @@
import { randomUUID } from 'crypto'
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { generateId } from '@/lib/core/utils/uuid'
import { createPostgresConnection, executeIntrospect } from '@/app/api/tools/postgresql/utils'
const logger = createLogger('PostgreSQLIntrospectAPI')
@@ -18,7 +18,7 @@ const IntrospectSchema = z.object({
})
export async function POST(request: NextRequest) {
const requestId = randomUUID().slice(0, 8)
const requestId = generateId().slice(0, 8)
try {
const auth = await checkInternalAuth(request)

Some files were not shown because too many files have changed in this diff Show More