Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 0 additions & 119 deletions apps/sim/lib/analytics/profound.ts

This file was deleted.

2 changes: 0 additions & 2 deletions apps/sim/lib/core/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,6 @@ export const env = createEnv({
TELEMETRY_ENDPOINT: z.string().url().optional(), // Custom telemetry/analytics endpoint
COST_MULTIPLIER: z.number().optional(), // Multiplier for cost calculations
LOG_LEVEL: z.enum(['DEBUG', 'INFO', 'WARN', 'ERROR']).optional(), // Minimum log level to display (defaults to ERROR in production, DEBUG in development)
PROFOUND_API_KEY: z.string().min(1).optional(), // Profound analytics API key
PROFOUND_ENDPOINT: z.string().url().optional(), // Profound analytics endpoint
GRAFANA_OTLP_ENDPOINT: z.string().url().optional(), // Grafana Cloud OTLP HTTP gateway base URL (e.g., https://otlp-gateway-prod-us-east-0.grafana.net/otlp). Trigger.dev exporters append /v1/traces, /v1/logs, /v1/metrics.
GRAFANA_OTLP_HEADERS: z.string().min(1).optional(), // Comma-separated key=value headers for OTLP requests (e.g., "Authorization=Basic <base64(instanceId:token)>"). Same format as the OTEL_EXPORTER_OTLP_HEADERS spec.
GRAFANA_DEPLOYMENT_ENVIRONMENT: z.string().min(1).optional(), // Deployment tier label (e.g., "production", "staging", "development"). Emitted as the stable `deployment.environment.name` resource attribute on Trigger.dev telemetry to match the rest of the Sim OTEL stack.
Expand Down
28 changes: 10 additions & 18 deletions apps/sim/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createLogger } from '@sim/logger'
import { getSessionCookie } from 'better-auth/cookies'
import { type NextRequest, NextResponse } from 'next/server'
import { sendToProfound } from './lib/analytics/profound'
import { getEnv } from './lib/core/config/env'
import { isAuthDisabled, isDev, isHosted } from './lib/core/config/env-flags'
import { generateRuntimeCSP } from './lib/core/security/csp'
Expand Down Expand Up @@ -316,40 +315,40 @@ export async function proxy(request: NextRequest) {
const hasActiveSession = isAuthDisabled || !!sessionCookie

const redirect = handleRootPathRedirects(request, hasActiveSession)
if (redirect) return track(request, redirect)
if (redirect) return applyIndexingPolicy(request, redirect)

if (url.pathname === '/login' || url.pathname === '/signup') {
if (hasActiveSession) {
return track(request, NextResponse.redirect(new URL('/workspace', request.url)))
return applyIndexingPolicy(request, NextResponse.redirect(new URL('/workspace', request.url)))
}
const response = NextResponse.next()
response.headers.set('Content-Security-Policy', generateRuntimeCSP())
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('X-Frame-Options', 'SAMEORIGIN')
return track(request, response)
return applyIndexingPolicy(request, response)
}

// Chat pages are publicly accessible embeds — CSP is set in next.config.ts headers
if (url.pathname.startsWith('/chat/')) {
return track(request, NextResponse.next())
return applyIndexingPolicy(request, NextResponse.next())
}

if (url.pathname.startsWith('/workspace')) {
if (!hasActiveSession) {
return track(request, NextResponse.redirect(new URL('/login', request.url)))
return applyIndexingPolicy(request, NextResponse.redirect(new URL('/login', request.url)))
}
const response = NextResponse.next()
response.headers.set('Content-Security-Policy', generateRuntimeCSP())
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('X-Frame-Options', 'SAMEORIGIN')
return track(request, response)
return applyIndexingPolicy(request, response)
}

const invitationRedirect = handleInvitationRedirects(request, hasActiveSession)
if (invitationRedirect) return track(request, invitationRedirect)
if (invitationRedirect) return applyIndexingPolicy(request, invitationRedirect)

const securityBlock = handleSecurityFiltering(request)
if (securityBlock) return track(request, securityBlock)
if (securityBlock) return applyIndexingPolicy(request, securityBlock)

const response = NextResponse.next()
response.headers.set('Vary', 'User-Agent')
Expand All @@ -358,7 +357,7 @@ export async function proxy(request: NextRequest) {
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('X-Frame-Options', 'SAMEORIGIN')

return track(request, response)
return applyIndexingPolicy(request, response)
}

/**
Expand All @@ -370,7 +369,7 @@ export async function proxy(request: NextRequest) {
* the index. robots.txt is excluded from this proxy's matcher so it keeps
* serving the crawlable rules this header depends on.
*/
function applyIndexingPolicy(request: NextRequest, response: NextResponse): void {
function applyIndexingPolicy(request: NextRequest, response: NextResponse): NextResponse {
const host =
request.headers.get('x-forwarded-host')?.split(',')[0]?.trim() ||
request.headers.get('host') ||
Expand All @@ -379,14 +378,7 @@ function applyIndexingPolicy(request: NextRequest, response: NextResponse): void
if (isNonCanonicalSimHost(host)) {
response.headers.set('X-Robots-Tag', 'noindex, nofollow')
}
}

/**
* Sends request data to Profound analytics (fire-and-forget) and returns the response.
*/
function track(request: NextRequest, response: NextResponse): NextResponse {
applyIndexingPolicy(request, response)
sendToProfound(request, response.status)
return response
}

Expand Down
Loading