Skip to content
Draft
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
4 changes: 2 additions & 2 deletions frontend/src/app/api/[..._path]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { resolveApiUrl } from "@/lib/connections/resolve";
import { getAuthMode, usesNextAuth } from "@/types/auth-mode";
import { generateUserJWT } from "@/lib/auth/jwt";
import { isPrivateUrl } from "@/lib/utils/url-validation";
import { internalErrorResponse } from "@/lib/api/error-response";

function getCorsHeaders(req: NextRequest) {
const origin = req.headers.get("origin");
Expand Down Expand Up @@ -156,8 +157,7 @@ async function handleRequest(req: NextRequest, method: string) {
},
});
} catch (e) {
const error = e as Error;
return NextResponse.json({ error: error.message }, { status: 500 });
return internalErrorResponse(e, "proxy request failed");
}
}

Expand Down
9 changes: 2 additions & 7 deletions frontend/src/app/api/admin/upload/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { auth } from "@/lib/auth";
import { isAdmin } from "@/types/auth-mode";
import type { UserRole } from "@/types/auth-mode";
import { writeFile, mkdir, access, constants } from "fs/promises";
import { internalErrorResponse } from "@/lib/api/error-response";
import path from "path";

const ALLOWED_TYPES = [
Expand Down Expand Up @@ -96,13 +97,7 @@ export async function POST(request: NextRequest) {

return NextResponse.json({ url, filename });
} catch (error) {
console.error("Upload error:", error);
return NextResponse.json(
{
error: `Failed to upload file: ${error instanceof Error ? error.message : "Unknown error"}`,
},
{ status: 500 },
);
return internalErrorResponse(error, "admin file upload failed");
}
}

Expand Down
7 changes: 2 additions & 5 deletions frontend/src/app/api/langsmith/runs/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Client, type Run } from "langsmith";
import { NextRequest, NextResponse } from "next/server";
import { LangSmithRun, buildRunHierarchy } from "@/types/langsmith";
import { usesNextAuth } from "@/types/auth-mode";
import { internalErrorResponse } from "@/lib/api/error-response";

// LangSmith Run 객체를 LangSmithRun 형식으로 변환
function convertRun(run: Run): LangSmithRun {
Expand Down Expand Up @@ -137,10 +138,6 @@ export async function GET(req: NextRequest) {

return NextResponse.json({ runs, hierarchy });
} catch (error) {
console.error("Failed to fetch LangSmith runs:", error);
return NextResponse.json(
{ error: error instanceof Error ? error.message : "Unknown error" },
{ status: 500 },
);
return internalErrorResponse(error, "LangSmith runs fetch failed");
}
}
9 changes: 2 additions & 7 deletions frontend/src/app/api/upload/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { usesNextAuth } from "@/types/auth-mode";
import { getSetting } from "@/lib/services/settings.service";
import { internalErrorResponse } from "@/lib/api/error-response";
import { writeFile, mkdir, access, constants } from "fs/promises";
import path from "path";

Expand Down Expand Up @@ -106,13 +107,7 @@ export async function POST(request: NextRequest) {

return NextResponse.json({ url, filename });
} catch (error) {
console.error("Upload error:", error);
return NextResponse.json(
{
error: `Failed to upload file: ${error instanceof Error ? error.message : "Unknown error"}`,
},
{ status: 500 },
);
return internalErrorResponse(error, "user file upload failed");
}
}

Expand Down
14 changes: 14 additions & 0 deletions frontend/src/lib/api/error-response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { NextResponse } from "next/server";

/**
* Return a generic 500 JSON response while logging the real error server-side.
* Prevents leaking internal hostnames, ports, file-system paths, or API keys
* to clients (OWASP A05:2021 — Security Misconfiguration).
*/
export function internalErrorResponse(error: unknown, context: string) {
console.error(`[api] ${context}`, error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 },
);
}
Loading