diff --git a/src/app/api/agent-server/[...segments]/route.ts b/src/app/api/agent-server/[...segments]/route.ts index 3db6073..b944f98 100644 --- a/src/app/api/agent-server/[...segments]/route.ts +++ b/src/app/api/agent-server/[...segments]/route.ts @@ -3,6 +3,7 @@ export const dynamic = 'force-dynamic' import type { NextRequest } from 'next/server' import { createUpstreamProxyHandler } from '@lib/apiProxy' +import { getAccountSession } from '@server/account/session' import { getAccountServiceBaseUrl } from '@server/serviceConfig' const AGENT_SERVER_PREFIX = '/api/agent-server' @@ -12,6 +13,23 @@ function createHandler() { return createUpstreamProxyHandler({ upstreamBaseUrl, upstreamPathPrefix: AGENT_SERVER_PREFIX, + getAdditionalHeaders: async (request) => { + // Keep explicit Authorization from caller (e.g. agent token) untouched. + if (request.headers.get('authorization')) { + return undefined + } + + // For dashboard browser calls, forward the current account session token. + const session = await getAccountSession(request) + if (!session.token) { + return undefined + } + + return { + authorization: `Bearer ${session.token}`, + 'x-account-session': session.token, + } + }, }) } diff --git a/src/lib/apiProxy.ts b/src/lib/apiProxy.ts index f821995..19fff40 100644 --- a/src/lib/apiProxy.ts +++ b/src/lib/apiProxy.ts @@ -20,6 +20,7 @@ type ProxyOptions = { upstreamBaseUrl: string upstreamPathPrefix: string allowedHeaders?: readonly string[] + getAdditionalHeaders?: (request: NextRequest) => Promise | undefined> | Record | undefined } function stripTrailingSlash(value: string): string { @@ -35,7 +36,11 @@ function buildTargetUrl(request: NextRequest, { upstreamBaseUrl, upstreamPathPre return `${normalizedBase}${normalizedPrefix}${normalizedSuffix}${search}` } -function buildForwardHeaders(request: NextRequest, allowedHeaders: readonly string[] = DEFAULT_FORWARD_HEADERS) { +function buildForwardHeaders( + request: NextRequest, + allowedHeaders: readonly string[] = DEFAULT_FORWARD_HEADERS, + additionalHeaders?: Record +) { const headers = new Headers() for (const name of allowedHeaders) { const value = request.headers.get(name) @@ -50,6 +55,14 @@ function buildForwardHeaders(request: NextRequest, allowedHeaders: readonly stri headers.set('X-Service-Token', serviceToken.trim()) } + if (additionalHeaders) { + for (const [name, value] of Object.entries(additionalHeaders)) { + if (typeof value === 'string' && value.trim().length > 0) { + headers.set(name, value) + } + } + } + return headers } @@ -70,7 +83,8 @@ function applySetCookieHeaders(source: Headers, target: Headers) { export async function proxyRequestToUpstream(request: NextRequest, options: ProxyOptions): Promise { const targetUrl = buildTargetUrl(request, options) - const forwardHeaders = buildForwardHeaders(request, options.allowedHeaders) + const additionalHeaders = await options.getAdditionalHeaders?.(request) + const forwardHeaders = buildForwardHeaders(request, options.allowedHeaders, additionalHeaders) let body: ArrayBuffer | undefined if (!BODYLESS_METHODS.has(request.method.toUpperCase())) {