feat(auth): enable requireWorkspacePrincipal on agent/sessions routes to support desktop API keys

This commit is contained in:
2026-05-29 19:08:23 -07:00
parent 7681bd1211
commit c2f71769bb

View File

@@ -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,13 +103,13 @@ 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;
}
}
@@ -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 });