From ef31a2fe7be79070e58a3ca3f5da863125ef0fa1 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Sun, 18 May 2025 01:39:47 -0700 Subject: [PATCH] fix(ci): fixed container registry name in ci, modified some routes to be dynamic to avoid nextjs telemetry --- .github/workflows/build.yml | 2 +- apps/sim/app/api/function/execute/route.ts | 5 ++- .../app/api/webhooks/trigger/[path]/route.ts | 6 ++-- .../workspaces/invitations/accept/route.ts | 32 +++++++------------ .../workspaces/invitations/details/route.ts | 4 +-- .../app/api/workspaces/invitations/route.ts | 29 +++++++++++++---- .../app/api/workspaces/members/[id]/route.ts | 4 +-- apps/sim/app/api/workspaces/members/route.ts | 4 +-- apps/sim/app/api/workspaces/route.ts | 2 +- 9 files changed, 46 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c41880971..0626d3e93 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -34,7 +34,7 @@ jobs: if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: - registry: simstudioai + registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index 82533cc2d..553bb641b 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -4,9 +4,8 @@ import { createContext, Script } from 'vm' import { env } from '@/lib/env' import { createLogger } from '@/lib/logs/console-logger' -// Explicitly export allowed methods -export const dynamic = 'force-dynamic' // Disable static optimization -export const runtime = 'nodejs' // Use Node.js runtime +export const dynamic = 'force-dynamic' +export const runtime = 'nodejs' const logger = createLogger('FunctionExecuteAPI') diff --git a/apps/sim/app/api/webhooks/trigger/[path]/route.ts b/apps/sim/app/api/webhooks/trigger/[path]/route.ts index c1ddc249d..ac1a3b125 100644 --- a/apps/sim/app/api/webhooks/trigger/[path]/route.ts +++ b/apps/sim/app/api/webhooks/trigger/[path]/route.ts @@ -17,11 +17,9 @@ import { webhook, workflow } from '@/db/schema' const logger = createLogger('WebhookTriggerAPI') -// Define Next.js config for webhook processing -export const dynamic = 'force-dynamic' // Ensure dynamic rendering -export const maxDuration = 300 // 5 minutes max execution time +export const dynamic = 'force-dynamic' +export const maxDuration = 300 -// Storage for active processing tasks to prevent garbage collection const activeProcessingTasks = new Map>() /** diff --git a/apps/sim/app/api/workspaces/invitations/accept/route.ts b/apps/sim/app/api/workspaces/invitations/accept/route.ts index 3f683e15b..f41c48cbf 100644 --- a/apps/sim/app/api/workspaces/invitations/accept/route.ts +++ b/apps/sim/app/api/workspaces/invitations/accept/route.ts @@ -2,10 +2,11 @@ import { NextRequest, NextResponse } from 'next/server' import { randomUUID } from 'crypto' import { and, eq } from 'drizzle-orm' import { getSession } from '@/lib/auth' +import { env } from '@/lib/env' import { db } from '@/db' import { user, workspace, workspaceInvitation, workspaceMember } from '@/db/schema' -// GET /api/workspaces/invitations/accept - Accept an invitation via token +// Accept an invitation via token export async function GET(req: NextRequest) { const token = req.nextUrl.searchParams.get('token') @@ -14,7 +15,7 @@ export async function GET(req: NextRequest) { return NextResponse.redirect( new URL( '/invite/invite-error?reason=missing-token', - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' ) ) } @@ -25,10 +26,7 @@ export async function GET(req: NextRequest) { // No need to encode API URL as callback, just redirect to invite page // The middleware will handle proper login flow and return to invite page return NextResponse.redirect( - new URL( - `/invite/${token}?token=${token}`, - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' - ) + new URL(`/invite/${token}?token=${token}`, env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai') ) } @@ -44,7 +42,7 @@ export async function GET(req: NextRequest) { return NextResponse.redirect( new URL( '/invite/invite-error?reason=invalid-token', - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' ) ) } @@ -54,7 +52,7 @@ export async function GET(req: NextRequest) { return NextResponse.redirect( new URL( '/invite/invite-error?reason=expired', - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' ) ) } @@ -64,7 +62,7 @@ export async function GET(req: NextRequest) { return NextResponse.redirect( new URL( '/invite/invite-error?reason=already-processed', - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' ) ) } @@ -107,7 +105,7 @@ export async function GET(req: NextRequest) { return NextResponse.redirect( new URL( `/invite/invite-error?reason=email-mismatch&details=${encodeURIComponent(`Invitation was sent to ${invitation.email}, but you're logged in as ${userData?.email || session.user.email}`)}`, - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' ) ) } @@ -123,7 +121,7 @@ export async function GET(req: NextRequest) { return NextResponse.redirect( new URL( '/invite/invite-error?reason=workspace-not-found', - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' ) ) } @@ -151,10 +149,7 @@ export async function GET(req: NextRequest) { .where(eq(workspaceInvitation.id, invitation.id)) return NextResponse.redirect( - new URL( - `/w/${invitation.workspaceId}`, - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' - ) + new URL(`/w/${invitation.workspaceId}`, env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai') ) } @@ -179,17 +174,14 @@ export async function GET(req: NextRequest) { // Redirect to the workspace return NextResponse.redirect( - new URL( - `/w/${invitation.workspaceId}`, - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' - ) + new URL(`/w/${invitation.workspaceId}`, env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai') ) } catch (error) { console.error('Error accepting invitation:', error) return NextResponse.redirect( new URL( '/invite/invite-error?reason=server-error', - process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' ) ) } diff --git a/apps/sim/app/api/workspaces/invitations/details/route.ts b/apps/sim/app/api/workspaces/invitations/details/route.ts index 5d66e4c6d..a2c915f18 100644 --- a/apps/sim/app/api/workspaces/invitations/details/route.ts +++ b/apps/sim/app/api/workspaces/invitations/details/route.ts @@ -1,10 +1,10 @@ import { NextRequest, NextResponse } from 'next/server' -import { and, eq } from 'drizzle-orm' +import { eq } from 'drizzle-orm' import { getSession } from '@/lib/auth' import { db } from '@/db' import { workspace, workspaceInvitation } from '@/db/schema' -// GET /api/workspaces/invitations/details - Get invitation details by token +// Get invitation details by token export async function GET(req: NextRequest) { const token = req.nextUrl.searchParams.get('token') diff --git a/apps/sim/app/api/workspaces/invitations/route.ts b/apps/sim/app/api/workspaces/invitations/route.ts index 800a8fccf..7e2a2041f 100644 --- a/apps/sim/app/api/workspaces/invitations/route.ts +++ b/apps/sim/app/api/workspaces/invitations/route.ts @@ -1,17 +1,21 @@ import { NextRequest, NextResponse } from 'next/server' import { render } from '@react-email/render' import { randomUUID } from 'crypto' -import { and, eq, inArray, sql } from 'drizzle-orm' +import { and, eq, inArray } from 'drizzle-orm' import { Resend } from 'resend' import { WorkspaceInvitationEmail } from '@/components/emails/workspace-invitation' import { getSession } from '@/lib/auth' +import { env } from '@/lib/env' +import { createLogger } from '@/lib/logs/console-logger' import { db } from '@/db' import { user, workspace, workspaceInvitation, workspaceMember } from '@/db/schema' -// Initialize Resend for email sending -const resend = new Resend(process.env.RESEND_API_KEY) +export const dynamic = 'force-dynamic' -// GET /api/workspaces/invitations - Get all invitations for the user's workspaces +const logger = createLogger('WorkspaceInvitationsAPI') +const resend = env.RESEND_API_KEY ? new Resend(env.RESEND_API_KEY) : null + +// Get all invitations for the user's workspaces export async function GET(req: NextRequest) { const session = await getSession() @@ -53,7 +57,7 @@ export async function GET(req: NextRequest) { } } -// POST /api/workspaces/invitations - Create a new invitation +// Create a new invitation export async function POST(req: NextRequest) { const session = await getSession() @@ -204,7 +208,7 @@ async function sendInvitationEmail({ token: string }) { try { - const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' + const baseUrl = env.NEXT_PUBLIC_APP_URL || 'https://simstudio.ai' // Always use the client-side invite route with token parameter const invitationLink = `${baseUrl}/invite/${token}?token=${token}` @@ -216,8 +220,19 @@ async function sendInvitationEmail({ }) ) + if (!resend) { + logger.error(`RESEND_API_KEY not configured`) + return NextResponse.json( + { + error: + 'Email service not configured. Please set RESEND_API_KEY in environment variables.', + }, + { status: 500 } + ) + } + await resend.emails.send({ - from: process.env.RESEND_FROM_EMAIL || 'noreply@simstudio.ai', + from: 'noreply@simstudio.ai', to, subject: `You've been invited to join "${workspaceName}" on Sim Studio`, html: emailHtml, diff --git a/apps/sim/app/api/workspaces/members/[id]/route.ts b/apps/sim/app/api/workspaces/members/[id]/route.ts index 6859fb747..e6dba3846 100644 --- a/apps/sim/app/api/workspaces/members/[id]/route.ts +++ b/apps/sim/app/api/workspaces/members/[id]/route.ts @@ -2,9 +2,9 @@ import { NextRequest, NextResponse } from 'next/server' import { and, eq } from 'drizzle-orm' import { getSession } from '@/lib/auth' import { db } from '@/db' -import { workspace, workspaceMember } from '@/db/schema' +import { workspaceMember } from '@/db/schema' -// PATCH /api/workspaces/members/[id] - Update a member's role +// Update a member's role export async function PATCH(req: NextRequest, { params }: { params: Promise<{ id: string }> }) { const { id } = await params const session = await getSession() diff --git a/apps/sim/app/api/workspaces/members/route.ts b/apps/sim/app/api/workspaces/members/route.ts index ac1851270..0b4cb68d6 100644 --- a/apps/sim/app/api/workspaces/members/route.ts +++ b/apps/sim/app/api/workspaces/members/route.ts @@ -2,9 +2,9 @@ import { NextResponse } from 'next/server' import { and, eq } from 'drizzle-orm' import { getSession } from '@/lib/auth' import { db } from '@/db' -import { user, workspace, workspaceMember } from '@/db/schema' +import { user, workspaceMember } from '@/db/schema' -// POST /api/workspaces/members - Add a member to a workspace +// Add a member to a workspace export async function POST(req: Request) { const session = await getSession() diff --git a/apps/sim/app/api/workspaces/route.ts b/apps/sim/app/api/workspaces/route.ts index 36ea14f57..e4a3ec9cd 100644 --- a/apps/sim/app/api/workspaces/route.ts +++ b/apps/sim/app/api/workspaces/route.ts @@ -4,7 +4,7 @@ import { getSession } from '@/lib/auth' import { db } from '@/db' import { workflow, workspace, workspaceMember } from '@/db/schema' -// GET /api/workspaces - Get all workspaces for the current user +// Get all workspaces for the current user export async function GET() { const session = await getSession()