diff --git a/vibn-frontend/app/api/projects/[projectId]/agent/sessions/route.ts b/vibn-frontend/app/api/projects/[projectId]/agent/sessions/route.ts index 7347c6b..b48f963 100644 --- a/vibn-frontend/app/api/projects/[projectId]/agent/sessions/route.ts +++ b/vibn-frontend/app/api/projects/[projectId]/agent/sessions/route.ts @@ -9,8 +9,8 @@ * List all sessions for a project, newest first. */ import { NextResponse } from "next/server"; -import { authSession } from "@/lib/auth/session-server"; -import { query } from "@/lib/db-postgres"; +import { requireWorkspacePrincipal } from "@/lib/auth/workspace-auth"; +import { query, queryOne } from "@/lib/db-postgres"; import { listWorkspaceApiKeys, mintWorkspaceApiKey, revealWorkspaceApiKey } from "@/lib/auth/workspace-auth"; const AGENT_RUNNER_URL = process.env.AGENT_RUNNER_URL ?? "http://localhost:3333"; @@ -33,9 +33,19 @@ export async function POST( ) { try { const { projectId } = await params; - const session = await authSession(); - if (!session?.user?.email) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + + // 1. Authenticate the Workspace API key or Browser Session + const principal = await requireWorkspacePrincipal(req); + if (principal instanceof NextResponse) return principal; + + // 2. Fetch user details from principal.userId + const userRow = await queryOne<{ id: string; data: any }>( + `SELECT id, data FROM fs_users WHERE id = $1 LIMIT 1`, + [principal.userId] + ); + const email = userRow?.data?.email; + if (!email) { + return NextResponse.json({ error: "User email not found" }, { status: 404 }); } const body = await req.json(); @@ -56,7 +66,7 @@ export async function POST( `SELECT p.id, p.data FROM fs_projects p JOIN fs_users u ON u.id = p.user_id WHERE p.id::text = $1 AND u.data->>'email' = $2 LIMIT 1`, - [projectId, session.user.email] + [projectId, email] ); if (owns.length === 0) { return NextResponse.json({ error: "Project not found" }, { status: 404 }); @@ -93,17 +103,17 @@ export async function POST( const keys = await listWorkspaceApiKeys(workspaceId); let defaultKey = keys.find((k: any) => k.name === 'default' && !k.revoked_at); if (!defaultKey) { - const minted = await mintWorkspaceApiKey({ workspaceId, name: 'default', createdBy: session.user.id, scopes: ['workspace:*'] }); + const minted = await mintWorkspaceApiKey({ workspaceId, name: 'default', createdBy: principal.userId, scopes: ['workspace:*'] }); mcpToken = minted.token; } else { const revealed = await revealWorkspaceApiKey(workspaceId, defaultKey.id); if (revealed) mcpToken = revealed.token; else { - const minted = await mintWorkspaceApiKey({ workspaceId, name: 'default', createdBy: session.user.id, scopes: ['workspace:*'] }); + const minted = await mintWorkspaceApiKey({ workspaceId, name: 'default', createdBy: principal.userId, scopes: ['workspace:*'] }); mcpToken = minted.token; } } - + // Add VIBN_API_URL so the runner knows where to send MCP requests const vibnApiUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000"; @@ -162,9 +172,19 @@ export async function GET( ) { try { const { projectId } = await params; - const session = await authSession(); - if (!session?.user?.email) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + + // 1. Authenticate the Workspace API key or Browser Session + const principal = await requireWorkspacePrincipal(req); + if (principal instanceof NextResponse) return principal; + + // 2. Fetch user details from principal.userId + const userRow = await queryOne<{ id: string; data: any }>( + `SELECT id, data FROM fs_users WHERE id = $1 LIMIT 1`, + [principal.userId] + ); + const email = userRow?.data?.email; + if (!email) { + return NextResponse.json({ error: "User email not found" }, { status: 404 }); } await ensureTable(); @@ -190,7 +210,7 @@ export async function GET( WHERE s.project_id::text = $1 AND u.data->>'email' = $2 ORDER BY s.created_at DESC LIMIT 50`, - [projectId, session.user.email] + [projectId, email] ); return NextResponse.json({ sessions });