Skip to content

Commit eb4821f

Browse files
fix(chat-subs): always use getBaseUrl helper to fetch base url (#1643)
* fix(chat-subs): always use next public app url env * use getBaseUrl everywhere * move remaining uses * fix test * change auth.ts and make getBaseUrl() call not top level for emails * change remaining uses * revert csp * cleanup * fix
1 parent 4cceb22 commit eb4821f

File tree

46 files changed

+180
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+180
-306
lines changed

apps/sim/app/(auth)/login/login-form.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { client } from '@/lib/auth-client'
1818
import { quickValidateEmail } from '@/lib/email/validation'
1919
import { env, isFalsy, isTruthy } from '@/lib/env'
2020
import { createLogger } from '@/lib/logs/console/logger'
21+
import { getBaseUrl } from '@/lib/urls/utils'
2122
import { cn } from '@/lib/utils'
2223
import { SocialLoginButtons } from '@/app/(auth)/components/social-login-buttons'
2324
import { SSOLoginButton } from '@/app/(auth)/components/sso-login-button'
@@ -322,7 +323,7 @@ export default function LoginPage({
322323
},
323324
body: JSON.stringify({
324325
email: forgotPasswordEmail,
325-
redirectTo: `${window.location.origin}/reset-password`,
326+
redirectTo: `${getBaseUrl()}/reset-password`,
326327
}),
327328
})
328329

apps/sim/app/api/billing/portal/route.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { and, eq } from 'drizzle-orm'
44
import { type NextRequest, NextResponse } from 'next/server'
55
import { getSession } from '@/lib/auth'
66
import { requireStripeClient } from '@/lib/billing/stripe-client'
7-
import { env } from '@/lib/env'
87
import { createLogger } from '@/lib/logs/console/logger'
8+
import { getBaseUrl } from '@/lib/urls/utils'
99

1010
const logger = createLogger('BillingPortal')
1111

@@ -21,8 +21,7 @@ export async function POST(request: NextRequest) {
2121
const context: 'user' | 'organization' =
2222
body?.context === 'organization' ? 'organization' : 'user'
2323
const organizationId: string | undefined = body?.organizationId || undefined
24-
const returnUrl: string =
25-
body?.returnUrl || `${env.NEXT_PUBLIC_APP_URL}/workspace?billing=updated`
24+
const returnUrl: string = body?.returnUrl || `${getBaseUrl()}/workspace?billing=updated`
2625

2726
const stripe = requireStripeClient()
2827

apps/sim/app/api/chat/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import type { NextRequest } from 'next/server'
55
import { v4 as uuidv4 } from 'uuid'
66
import { z } from 'zod'
77
import { getSession } from '@/lib/auth'
8-
import { env } from '@/lib/env'
98
import { isDev } from '@/lib/environment'
109
import { createLogger } from '@/lib/logs/console/logger'
10+
import { getBaseUrl } from '@/lib/urls/utils'
1111
import { encryptSecret } from '@/lib/utils'
1212
import { checkWorkflowAccessForChatCreation } from '@/app/api/chat/utils'
1313
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'
@@ -171,7 +171,7 @@ export async function POST(request: NextRequest) {
171171

172172
// Return successful response with chat URL
173173
// Generate chat URL using path-based routing instead of subdomains
174-
const baseUrl = env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
174+
const baseUrl = getBaseUrl()
175175

176176
let chatUrl: string
177177
try {

apps/sim/app/api/files/download/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { type NextRequest, NextResponse } from 'next/server'
22
import { createLogger } from '@/lib/logs/console/logger'
33
import { getPresignedUrl, getPresignedUrlWithConfig, isUsingCloudStorage } from '@/lib/uploads'
44
import { BLOB_EXECUTION_FILES_CONFIG, S3_EXECUTION_FILES_CONFIG } from '@/lib/uploads/setup'
5+
import { getBaseUrl } from '@/lib/urls/utils'
56
import { createErrorResponse } from '@/app/api/files/utils'
67

78
const logger = createLogger('FileDownload')
@@ -81,7 +82,7 @@ export async function POST(request: NextRequest) {
8182
}
8283
} else {
8384
// For local storage, return the direct path
84-
const downloadUrl = `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/api/files/serve/${key}`
85+
const downloadUrl = `${getBaseUrl()}/api/files/serve/${key}`
8586

8687
return NextResponse.json({
8788
downloadUrl,

apps/sim/app/api/function/execute/route.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { createContext, Script } from 'vm'
22
import { type NextRequest, NextResponse } from 'next/server'
33
import { env, isTruthy } from '@/lib/env'
4-
import { MAX_EXECUTION_DURATION } from '@/lib/execution/constants'
54
import { executeInE2B } from '@/lib/execution/e2b'
65
import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages'
76
import { createLogger } from '@/lib/logs/console/logger'
87
import { validateProxyUrl } from '@/lib/security/input-validation'
98
import { generateRequestId } from '@/lib/utils'
109
export const dynamic = 'force-dynamic'
1110
export const runtime = 'nodejs'
12-
export const maxDuration = MAX_EXECUTION_DURATION
11+
// Segment config exports must be statically analyzable.
12+
// Mirror MAX_EXECUTION_DURATION (210s) from '@/lib/execution/constants'.
13+
export const maxDuration = 210
1314

1415
const logger = createLogger('FunctionExecuteAPI')
1516

apps/sim/app/api/organizations/[id]/invitations/route.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ import {
2323
} from '@/lib/billing/validation/seat-management'
2424
import { sendEmail } from '@/lib/email/mailer'
2525
import { quickValidateEmail } from '@/lib/email/validation'
26-
import { env } from '@/lib/env'
2726
import { createLogger } from '@/lib/logs/console/logger'
2827
import { hasWorkspaceAdminAccess } from '@/lib/permissions/utils'
28+
import { getBaseUrl } from '@/lib/urls/utils'
2929

3030
const logger = createLogger('OrganizationInvitations')
3131

@@ -339,7 +339,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
339339
organizationEntry[0]?.name || 'organization',
340340
role,
341341
workspaceInvitationsWithNames,
342-
`${env.NEXT_PUBLIC_APP_URL}/invite/${orgInvitation.id}`
342+
`${getBaseUrl()}/invite/${orgInvitation.id}`
343343
)
344344

345345
emailResult = await sendEmail({
@@ -352,7 +352,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
352352
const emailHtml = await renderInvitationEmail(
353353
inviter[0]?.name || 'Someone',
354354
organizationEntry[0]?.name || 'organization',
355-
`${env.NEXT_PUBLIC_APP_URL}/invite/${orgInvitation.id}`,
355+
`${getBaseUrl()}/invite/${orgInvitation.id}`,
356356
email
357357
)
358358

apps/sim/app/api/organizations/[id]/members/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { getUserUsageData } from '@/lib/billing/core/usage'
99
import { validateSeatAvailability } from '@/lib/billing/validation/seat-management'
1010
import { sendEmail } from '@/lib/email/mailer'
1111
import { quickValidateEmail } from '@/lib/email/validation'
12-
import { env } from '@/lib/env'
1312
import { createLogger } from '@/lib/logs/console/logger'
13+
import { getBaseUrl } from '@/lib/urls/utils'
1414

1515
const logger = createLogger('OrganizationMembersAPI')
1616

@@ -260,7 +260,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
260260
const emailHtml = await renderInvitationEmail(
261261
inviter[0]?.name || 'Someone',
262262
organizationEntry[0]?.name || 'organization',
263-
`${env.NEXT_PUBLIC_APP_URL}/invite/organization?id=${invitationId}`,
263+
`${getBaseUrl()}/invite/organization?id=${invitationId}`,
264264
normalizedEmail
265265
)
266266

apps/sim/app/api/webhooks/[id]/route.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { webhook, workflow } from '@sim/db/schema'
33
import { eq } from 'drizzle-orm'
44
import { type NextRequest, NextResponse } from 'next/server'
55
import { getSession } from '@/lib/auth'
6-
import { env } from '@/lib/env'
76
import { createLogger } from '@/lib/logs/console/logger'
87
import { getUserEntityPermissions } from '@/lib/permissions/utils'
8+
import { getBaseUrl } from '@/lib/urls/utils'
99
import { generateRequestId } from '@/lib/utils'
1010
import { getOAuthToken } from '@/app/api/auth/oauth/utils'
1111

@@ -282,13 +282,7 @@ export async function DELETE(
282282

283283
if (!resolvedExternalId) {
284284
try {
285-
if (!env.NEXT_PUBLIC_APP_URL) {
286-
logger.error(
287-
`[${requestId}] NEXT_PUBLIC_APP_URL not configured, cannot match Airtable webhook`
288-
)
289-
throw new Error('NEXT_PUBLIC_APP_URL must be configured')
290-
}
291-
const expectedNotificationUrl = `${env.NEXT_PUBLIC_APP_URL}/api/webhooks/trigger/${foundWebhook.path}`
285+
const expectedNotificationUrl = `${getBaseUrl()}/api/webhooks/trigger/${foundWebhook.path}`
292286

293287
const listUrl = `https://api.airtable.com/v0/bases/${baseId}/webhooks`
294288
const listResp = await fetch(listUrl, {

apps/sim/app/api/webhooks/[id]/test-url/route.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { db, webhook, workflow } from '@sim/db'
22
import { eq } from 'drizzle-orm'
33
import { type NextRequest, NextResponse } from 'next/server'
44
import { getSession } from '@/lib/auth'
5-
import { env } from '@/lib/env'
65
import { createLogger } from '@/lib/logs/console/logger'
76
import { getUserEntityPermissions } from '@/lib/permissions/utils'
7+
import { getBaseUrl } from '@/lib/urls/utils'
88
import { generateRequestId } from '@/lib/utils'
99
import { signTestWebhookToken } from '@/lib/webhooks/test-tokens'
1010

@@ -64,13 +64,8 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
6464
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
6565
}
6666

67-
if (!env.NEXT_PUBLIC_APP_URL) {
68-
logger.error(`[${requestId}] NEXT_PUBLIC_APP_URL not configured`)
69-
return NextResponse.json({ error: 'Server configuration error' }, { status: 500 })
70-
}
71-
7267
const token = await signTestWebhookToken(id, ttlSeconds)
73-
const url = `${env.NEXT_PUBLIC_APP_URL}/api/webhooks/test/${id}?token=${encodeURIComponent(token)}`
68+
const url = `${getBaseUrl()}/api/webhooks/test/${id}?token=${encodeURIComponent(token)}`
7469

7570
logger.info(`[${requestId}] Minted test URL for webhook ${id}`)
7671
return NextResponse.json({

apps/sim/app/api/webhooks/route.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { and, desc, eq } from 'drizzle-orm'
44
import { nanoid } from 'nanoid'
55
import { type NextRequest, NextResponse } from 'next/server'
66
import { getSession } from '@/lib/auth'
7-
import { env } from '@/lib/env'
87
import { createLogger } from '@/lib/logs/console/logger'
98
import { getUserEntityPermissions } from '@/lib/permissions/utils'
9+
import { getBaseUrl } from '@/lib/urls/utils'
1010
import { generateRequestId } from '@/lib/utils'
1111
import { getOAuthToken } from '@/app/api/auth/oauth/utils'
1212

@@ -467,14 +467,7 @@ async function createAirtableWebhookSubscription(
467467
)
468468
}
469469

470-
if (!env.NEXT_PUBLIC_APP_URL) {
471-
logger.error(
472-
`[${requestId}] NEXT_PUBLIC_APP_URL not configured, cannot register Airtable webhook`
473-
)
474-
throw new Error('NEXT_PUBLIC_APP_URL must be configured for Airtable webhook registration')
475-
}
476-
477-
const notificationUrl = `${env.NEXT_PUBLIC_APP_URL}/api/webhooks/trigger/${path}`
470+
const notificationUrl = `${getBaseUrl()}/api/webhooks/trigger/${path}`
478471

479472
const airtableApiUrl = `https://api.airtable.com/v0/bases/${baseId}/webhooks`
480473

0 commit comments

Comments
 (0)