diff --git a/apps/sim/.env.example b/apps/sim/.env.example index b7808de726..0f3a44bb94 100644 --- a/apps/sim/.env.example +++ b/apps/sim/.env.example @@ -1,8 +1,5 @@ # Database (Required) DATABASE_URL="postgresql://postgres:password@localhost:5432/postgres" -# DATABASE_SSL=disable # Optional: SSL mode (disable, prefer, require, verify-ca, verify-full) -# DATABASE_SSL_CA= # Optional: Base64-encoded CA certificate (required for verify-ca/verify-full) - # To generate: cat your-ca.crt | base64 | tr -d '\n' # PostgreSQL Port (Optional) - defaults to 5432 if not specified # POSTGRES_PORT=5432 diff --git a/apps/sim/drizzle.config.ts b/apps/sim/drizzle.config.ts index a2f0d41c50..3f0cfbd898 100644 --- a/apps/sim/drizzle.config.ts +++ b/apps/sim/drizzle.config.ts @@ -1,44 +1,11 @@ import type { Config } from 'drizzle-kit' import { env } from './lib/env' -const getSSLConfig = () => { - const sslMode = env.DATABASE_SSL?.toLowerCase() - - if (!sslMode || sslMode === 'disable') { - return undefined - } - - if (sslMode === 'prefer') { - return 'prefer' as const - } - - const sslConfig: any = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - console.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } - - return sslConfig -} - -const sslConfig = getSSLConfig() - export default { schema: '../../packages/db/schema.ts', out: '../../packages/db/migrations', dialect: 'postgresql', dbCredentials: { url: env.DATABASE_URL, - ...(sslConfig !== undefined && { ssl: sslConfig }), }, } satisfies Config diff --git a/apps/sim/socket-server/database/operations.ts b/apps/sim/socket-server/database/operations.ts index 35a73cbf9a..388d6610a3 100644 --- a/apps/sim/socket-server/database/operations.ts +++ b/apps/sim/socket-server/database/operations.ts @@ -1,4 +1,3 @@ -import type { ConnectionOptions } from 'node:tls' import * as schema from '@sim/db' import { workflow, workflowBlocks, workflowEdges, workflowSubflows } from '@sim/db' import { and, eq, or, sql } from 'drizzle-orm' @@ -11,34 +10,6 @@ import { loadWorkflowFromNormalizedTables } from '@/lib/workflows/db-helpers' const logger = createLogger('SocketDatabase') const connectionString = env.DATABASE_URL - -const getSSLConfig = () => { - const sslMode = env.DATABASE_SSL - - if (!sslMode) return undefined - if (sslMode === 'disable') return false - if (sslMode === 'prefer') return 'prefer' - - const sslConfig: ConnectionOptions = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - logger.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } - - return sslConfig -} - -const sslConfig = getSSLConfig() const socketDb = drizzle( postgres(connectionString, { prepare: false, @@ -47,7 +18,6 @@ const socketDb = drizzle( max: 25, onnotice: () => {}, debug: false, - ...(sslConfig !== undefined && { ssl: sslConfig }), }), { schema } ) @@ -162,6 +132,7 @@ export async function getWorkflowState(workflowId: string) { const finalState = { // Default values for expected properties deploymentStatuses: {}, + hasActiveWebhook: false, // Data from normalized tables blocks: normalizedData.blocks, edges: normalizedData.edges, @@ -195,7 +166,23 @@ export async function persistWorkflowOperation(workflowId: string, operation: an try { const { operation: op, target, payload, timestamp, userId } = operation + // Log high-frequency operations for monitoring + if (op === 'update-position' && Math.random() < 0.01) { + // Log 1% of position updates + logger.debug('Socket DB operation sample:', { + operation: op, + target, + workflowId: `${workflowId.substring(0, 8)}...`, + }) + } + await db.transaction(async (tx) => { + // Update the workflow's last modified timestamp first + await tx + .update(workflow) + .set({ updatedAt: new Date(timestamp) }) + .where(eq(workflow.id, workflowId)) + // Handle different operation types within the transaction switch (target) { case 'block': @@ -213,13 +200,6 @@ export async function persistWorkflowOperation(workflowId: string, operation: an default: throw new Error(`Unknown operation target: ${target}`) } - - if (op !== 'update-position') { - await tx - .update(workflow) - .set({ updatedAt: new Date(timestamp) }) - .where(eq(workflow.id, workflowId)) - } }) // Log slow operations for monitoring diff --git a/apps/sim/socket-server/rooms/manager.ts b/apps/sim/socket-server/rooms/manager.ts index 3338c6b217..b36ac85a77 100644 --- a/apps/sim/socket-server/rooms/manager.ts +++ b/apps/sim/socket-server/rooms/manager.ts @@ -1,4 +1,3 @@ -import type { ConnectionOptions } from 'node:tls' import * as schema from '@sim/db/schema' import { workflowBlocks, workflowEdges } from '@sim/db/schema' import { and, eq, isNull } from 'drizzle-orm' @@ -9,34 +8,6 @@ import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console/logger' const connectionString = env.DATABASE_URL - -const getSSLConfig = () => { - const sslMode = env.DATABASE_SSL - - if (!sslMode) return undefined - if (sslMode === 'disable') return false - if (sslMode === 'prefer') return 'prefer' - - const sslConfig: ConnectionOptions = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - console.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } - - return sslConfig -} - -const sslConfig = getSSLConfig() const db = drizzle( postgres(connectionString, { prepare: false, @@ -44,7 +15,6 @@ const db = drizzle( connect_timeout: 20, max: 5, onnotice: () => {}, - ...(sslConfig !== undefined && { ssl: sslConfig }), }), { schema } ) diff --git a/packages/db/drizzle.config.ts b/packages/db/drizzle.config.ts index 6cd62f09fd..ab26be6d82 100644 --- a/packages/db/drizzle.config.ts +++ b/packages/db/drizzle.config.ts @@ -1,43 +1,10 @@ import type { Config } from 'drizzle-kit' -const getSSLConfig = () => { - const sslMode = process.env.DATABASE_SSL?.toLowerCase() - - if (!sslMode || sslMode === 'disable') { - return undefined - } - - if (sslMode === 'prefer') { - return 'prefer' as const - } - - const sslConfig: any = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (process.env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(process.env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - console.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } - - return sslConfig -} - -const sslConfig = getSSLConfig() - export default { schema: './schema.ts', out: './migrations', dialect: 'postgresql', dbCredentials: { url: process.env.DATABASE_URL!, - ...(sslConfig !== undefined && { ssl: sslConfig }), }, } satisfies Config diff --git a/packages/db/index.ts b/packages/db/index.ts index ab5a41a79f..d53999e083 100644 --- a/packages/db/index.ts +++ b/packages/db/index.ts @@ -1,4 +1,3 @@ -import type { ConnectionOptions } from 'node:tls' import { drizzle, type PostgresJsDatabase } from 'drizzle-orm/postgres-js' import postgres from 'postgres' import * as schema from './schema' @@ -11,52 +10,12 @@ if (!connectionString) { throw new Error('Missing DATABASE_URL environment variable') } -const getSSLConfig = () => { - const sslMode = process.env.DATABASE_SSL?.toLowerCase() - - if (!sslMode) { - return undefined - } - - if (sslMode === 'disable') { - return false - } - - if (sslMode === 'prefer') { - return 'prefer' - } - - const sslConfig: ConnectionOptions = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (process.env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(process.env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - console.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } else { - throw new Error( - `Invalid DATABASE_SSL mode: ${sslMode}. Must be one of: disable, prefer, require, verify-ca, verify-full` - ) - } - - return sslConfig -} - -const sslConfig = getSSLConfig() const postgresClient = postgres(connectionString, { prepare: false, idle_timeout: 20, connect_timeout: 30, max: 80, onnotice: () => {}, - ...(sslConfig !== undefined && { ssl: sslConfig }), }) const drizzleClient = drizzle(postgresClient, { schema }) diff --git a/packages/db/scripts/deregister-sso-provider.ts b/packages/db/scripts/deregister-sso-provider.ts index 8ba55a1ff3..f22c317e19 100644 --- a/packages/db/scripts/deregister-sso-provider.ts +++ b/packages/db/scripts/deregister-sso-provider.ts @@ -13,7 +13,6 @@ * SSO_PROVIDER_ID=provider-id (optional, if not provided will remove all providers for user) */ -import type { ConnectionOptions } from 'node:tls' import { and, eq } from 'drizzle-orm' import { drizzle } from 'drizzle-orm/postgres-js' import postgres from 'postgres' @@ -45,50 +44,18 @@ const logger = { } // Get database URL from environment -const CONNECTION_STRING = process.env.DATABASE_URL +const CONNECTION_STRING = process.env.POSTGRES_URL ?? process.env.DATABASE_URL if (!CONNECTION_STRING) { - console.error('❌ DATABASE_URL environment variable is required') + console.error('❌ POSTGRES_URL or DATABASE_URL environment variable is required') process.exit(1) } -const getSSLConfig = () => { - const sslMode = process.env.DATABASE_SSL?.toLowerCase() - - if (!sslMode) return undefined - if (sslMode === 'disable') return false - if (sslMode === 'prefer') return 'prefer' - - const sslConfig: ConnectionOptions = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (process.env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(process.env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - console.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } else { - throw new Error( - `Invalid DATABASE_SSL mode: ${sslMode}. Must be one of: disable, prefer, require, verify-ca, verify-full` - ) - } - - return sslConfig -} - -const sslConfig = getSSLConfig() const postgresClient = postgres(CONNECTION_STRING, { prepare: false, idle_timeout: 20, connect_timeout: 30, max: 10, onnotice: () => {}, - ...(sslConfig !== undefined && { ssl: sslConfig }), }) const db = drizzle(postgresClient) diff --git a/packages/db/scripts/migrate-deployment-versions.ts b/packages/db/scripts/migrate-deployment-versions.ts index a9b736e8fe..30677c88b0 100644 --- a/packages/db/scripts/migrate-deployment-versions.ts +++ b/packages/db/scripts/migrate-deployment-versions.ts @@ -3,7 +3,6 @@ // This script is intentionally self-contained for execution in the migrations image. // Do not import from the main app code; duplicate minimal schema and DB setup here. -import type { ConnectionOptions } from 'node:tls' import { sql } from 'drizzle-orm' import { drizzle } from 'drizzle-orm/postgres-js' import postgres from 'postgres' @@ -118,44 +117,12 @@ const workflowDeploymentVersion = pgTable( ) // ---------- DB client ---------- -const getSSLConfig = () => { - const sslMode = process.env.DATABASE_SSL?.toLowerCase() - - if (!sslMode) return undefined - if (sslMode === 'disable') return false - if (sslMode === 'prefer') return 'prefer' - - const sslConfig: ConnectionOptions = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (process.env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(process.env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - console.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } else { - throw new Error( - `Invalid DATABASE_SSL mode: ${sslMode}. Must be one of: disable, prefer, require, verify-ca, verify-full` - ) - } - - return sslConfig -} - -const sslConfig = getSSLConfig() const postgresClient = postgres(CONNECTION_STRING, { prepare: false, idle_timeout: 20, connect_timeout: 30, max: 10, onnotice: () => {}, - ...(sslConfig !== undefined && { ssl: sslConfig }), }) const db = drizzle(postgresClient) diff --git a/packages/db/scripts/register-sso-provider.ts b/packages/db/scripts/register-sso-provider.ts index ca252f4985..a978e024d0 100644 --- a/packages/db/scripts/register-sso-provider.ts +++ b/packages/db/scripts/register-sso-provider.ts @@ -32,7 +32,6 @@ * SSO_SAML_WANT_ASSERTIONS_SIGNED=true (optional, defaults to false) */ -import type { ConnectionOptions } from 'node:tls' import { eq } from 'drizzle-orm' import { drizzle } from 'drizzle-orm/postgres-js' import postgres from 'postgres' @@ -135,50 +134,19 @@ const logger = { } // Get database URL from environment -const CONNECTION_STRING = process.env.DATABASE_URL +const CONNECTION_STRING = process.env.POSTGRES_URL ?? process.env.DATABASE_URL if (!CONNECTION_STRING) { - console.error('❌ DATABASE_URL environment variable is required') + console.error('❌ POSTGRES_URL or DATABASE_URL environment variable is required') process.exit(1) } -const getSSLConfig = () => { - const sslMode = process.env.DATABASE_SSL?.toLowerCase() - - if (!sslMode) return undefined - if (sslMode === 'disable') return false - if (sslMode === 'prefer') return 'prefer' - - const sslConfig: ConnectionOptions = {} - - if (sslMode === 'require') { - sslConfig.rejectUnauthorized = false - } else if (sslMode === 'verify-ca' || sslMode === 'verify-full') { - sslConfig.rejectUnauthorized = true - if (process.env.DATABASE_SSL_CA) { - try { - const ca = Buffer.from(process.env.DATABASE_SSL_CA, 'base64').toString('utf-8') - sslConfig.ca = ca - } catch (error) { - console.error('Failed to parse DATABASE_SSL_CA:', error) - } - } - } else { - throw new Error( - `Invalid DATABASE_SSL mode: ${sslMode}. Must be one of: disable, prefer, require, verify-ca, verify-full` - ) - } - - return sslConfig -} - -const sslConfig = getSSLConfig() +// Initialize database connection (following migration script pattern) const postgresClient = postgres(CONNECTION_STRING, { prepare: false, idle_timeout: 20, connect_timeout: 30, max: 10, onnotice: () => {}, - ...(sslConfig !== undefined && { ssl: sslConfig }), }) const db = drizzle(postgresClient)