Skip to content

Commit 0e94b82

Browse files
committed
use getBaseUrl everywhere
1 parent 8e0553a commit 0e94b82

35 files changed

Lines changed: 90 additions & 155 deletions

File tree

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/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/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

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { db } from '@sim/db'
22
import { webhook } from '@sim/db/schema'
33
import { eq } from 'drizzle-orm'
44
import { type NextRequest, NextResponse } from 'next/server'
5-
import { env } from '@/lib/env'
65
import { createLogger } from '@/lib/logs/console/logger'
6+
import { getBaseUrl } from '@/lib/urls/utils'
77
import { generateRequestId } from '@/lib/utils'
88

99
const logger = createLogger('WebhookTestAPI')
@@ -35,15 +35,7 @@ export async function GET(request: NextRequest) {
3535
const provider = foundWebhook.provider || 'generic'
3636
const providerConfig = (foundWebhook.providerConfig as Record<string, any>) || {}
3737

38-
if (!env.NEXT_PUBLIC_APP_URL) {
39-
logger.error(`[${requestId}] NEXT_PUBLIC_APP_URL not configured, cannot test webhook`)
40-
return NextResponse.json(
41-
{ success: false, error: 'NEXT_PUBLIC_APP_URL must be configured' },
42-
{ status: 500 }
43-
)
44-
}
45-
const baseUrl = env.NEXT_PUBLIC_APP_URL
46-
const webhookUrl = `${baseUrl}/api/webhooks/trigger/${foundWebhook.path}`
38+
const webhookUrl = `${getBaseUrl()}/api/webhooks/trigger/${foundWebhook.path}`
4739

4840
logger.info(`[${requestId}] Testing webhook for provider: ${provider}`, {
4941
webhookId,

apps/sim/app/api/workspaces/invitations/[invitationId]/route.ts

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import { WorkspaceInvitationEmail } from '@/components/emails/workspace-invitati
1414
import { getSession } from '@/lib/auth'
1515
import { sendEmail } from '@/lib/email/mailer'
1616
import { getFromEmailAddress } from '@/lib/email/utils'
17-
import { env } from '@/lib/env'
1817
import { hasWorkspaceAdminAccess } from '@/lib/permissions/utils'
18+
import { getBaseUrl } from '@/lib/urls/utils'
1919

2020
// GET /api/workspaces/invitations/[invitationId] - Get invitation details OR accept via token
2121
export async function GET(
@@ -30,12 +30,7 @@ export async function GET(
3030
if (!session?.user?.id) {
3131
// For token-based acceptance flows, redirect to login
3232
if (isAcceptFlow) {
33-
return NextResponse.redirect(
34-
new URL(
35-
`/invite/${invitationId}?token=${token}`,
36-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
37-
)
38-
)
33+
return NextResponse.redirect(new URL(`/invite/${invitationId}?token=${token}`, getBaseUrl()))
3934
}
4035
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
4136
}
@@ -54,10 +49,7 @@ export async function GET(
5449
if (!invitation) {
5550
if (isAcceptFlow) {
5651
return NextResponse.redirect(
57-
new URL(
58-
`/invite/${invitationId}?error=invalid-token`,
59-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
60-
)
52+
new URL(`/invite/${invitationId}?error=invalid-token`, getBaseUrl())
6153
)
6254
}
6355
return NextResponse.json({ error: 'Invitation not found or has expired' }, { status: 404 })
@@ -66,10 +58,7 @@ export async function GET(
6658
if (new Date() > new Date(invitation.expiresAt)) {
6759
if (isAcceptFlow) {
6860
return NextResponse.redirect(
69-
new URL(
70-
`/invite/${invitation.id}?error=expired`,
71-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
72-
)
61+
new URL(`/invite/${invitation.id}?error=expired`, getBaseUrl())
7362
)
7463
}
7564
return NextResponse.json({ error: 'Invitation has expired' }, { status: 400 })
@@ -84,10 +73,7 @@ export async function GET(
8473
if (!workspaceDetails) {
8574
if (isAcceptFlow) {
8675
return NextResponse.redirect(
87-
new URL(
88-
`/invite/${invitation.id}?error=workspace-not-found`,
89-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
90-
)
76+
new URL(`/invite/${invitation.id}?error=workspace-not-found`, getBaseUrl())
9177
)
9278
}
9379
return NextResponse.json({ error: 'Workspace not found' }, { status: 404 })
@@ -96,10 +82,7 @@ export async function GET(
9682
if (isAcceptFlow) {
9783
if (invitation.status !== ('pending' as WorkspaceInvitationStatus)) {
9884
return NextResponse.redirect(
99-
new URL(
100-
`/invite/${invitation.id}?error=already-processed`,
101-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
102-
)
85+
new URL(`/invite/${invitation.id}?error=already-processed`, getBaseUrl())
10386
)
10487
}
10588

@@ -114,21 +97,15 @@ export async function GET(
11497

11598
if (!userData) {
11699
return NextResponse.redirect(
117-
new URL(
118-
`/invite/${invitation.id}?error=user-not-found`,
119-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
120-
)
100+
new URL(`/invite/${invitation.id}?error=user-not-found`, getBaseUrl())
121101
)
122102
}
123103

124104
const isValidMatch = userEmail === invitationEmail
125105

126106
if (!isValidMatch) {
127107
return NextResponse.redirect(
128-
new URL(
129-
`/invite/${invitation.id}?error=email-mismatch`,
130-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
131-
)
108+
new URL(`/invite/${invitation.id}?error=email-mismatch`, getBaseUrl())
132109
)
133110
}
134111

@@ -154,10 +131,7 @@ export async function GET(
154131
.where(eq(workspaceInvitation.id, invitation.id))
155132

156133
return NextResponse.redirect(
157-
new URL(
158-
`/workspace/${invitation.workspaceId}/w`,
159-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
160-
)
134+
new URL(`/workspace/${invitation.workspaceId}/w`, getBaseUrl())
161135
)
162136
}
163137

@@ -181,12 +155,7 @@ export async function GET(
181155
.where(eq(workspaceInvitation.id, invitation.id))
182156
})
183157

184-
return NextResponse.redirect(
185-
new URL(
186-
`/workspace/${invitation.workspaceId}/w`,
187-
env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
188-
)
189-
)
158+
return NextResponse.redirect(new URL(`/workspace/${invitation.workspaceId}/w`, getBaseUrl()))
190159
}
191160

192161
return NextResponse.json({
@@ -298,7 +267,7 @@ export async function POST(
298267
.set({ token: newToken, expiresAt: newExpiresAt, updatedAt: new Date() })
299268
.where(eq(workspaceInvitation.id, invitationId))
300269

301-
const baseUrl = env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
270+
const baseUrl = getBaseUrl()
302271
const invitationLink = `${baseUrl}/invite/${invitationId}?token=${newToken}`
303272

304273
const emailHtml = await render(

apps/sim/app/api/workspaces/invitations/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import { WorkspaceInvitationEmail } from '@/components/emails/workspace-invitati
1515
import { getSession } from '@/lib/auth'
1616
import { sendEmail } from '@/lib/email/mailer'
1717
import { getFromEmailAddress } from '@/lib/email/utils'
18-
import { env } from '@/lib/env'
1918
import { createLogger } from '@/lib/logs/console/logger'
19+
import { getBaseUrl } from '@/lib/urls/utils'
2020

2121
export const dynamic = 'force-dynamic'
2222

@@ -232,7 +232,7 @@ async function sendInvitationEmail({
232232
token: string
233233
}) {
234234
try {
235-
const baseUrl = env.NEXT_PUBLIC_APP_URL || 'https://sim.ai'
235+
const baseUrl = getBaseUrl()
236236
// Use invitation ID in path, token in query parameter for security
237237
const invitationLink = `${baseUrl}/invite/${invitationId}?token=${token}`
238238

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/trigger-config/components/trigger-modal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from '@/components/ui/select'
2121
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
2222
import { createLogger } from '@/lib/logs/console/logger'
23+
import { getBaseUrl } from '@/lib/urls/utils'
2324
import { cn } from '@/lib/utils'
2425
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
2526
import { getTrigger } from '@/triggers'
@@ -284,8 +285,7 @@ export function TriggerModal({
284285
}
285286

286287
if (finalPath) {
287-
const baseUrl = window.location.origin
288-
setWebhookUrl(`${baseUrl}/api/webhooks/trigger/${finalPath}`)
288+
setWebhookUrl(`${getBaseUrl()}/api/webhooks/trigger/${finalPath}`)
289289
}
290290
}, [
291291
triggerPath,

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/components/sub-block/components/webhook/components/webhook-modal.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
DialogTitle,
1010
} from '@/components/ui/dialog'
1111
import { createLogger } from '@/lib/logs/console/logger'
12+
import { getBaseUrl } from '@/lib/urls/utils'
1213
import {
1314
AirtableConfig,
1415
DeleteConfirmDialog,
@@ -404,12 +405,7 @@ export function WebhookModal({
404405
}, [webhookPath])
405406

406407
// Construct the full webhook URL
407-
const baseUrl =
408-
typeof window !== 'undefined'
409-
? `${window.location.protocol}//${window.location.host}`
410-
: 'https://your-domain.com'
411-
412-
const webhookUrl = `${baseUrl}/api/webhooks/trigger/${formattedPath}`
408+
const webhookUrl = `${getBaseUrl()}/api/webhooks/trigger/${formattedPath}`
413409

414410
const generateTestUrl = async () => {
415411
if (!webhookId) return

0 commit comments

Comments
 (0)