From 5437d691b5ffb101563dda85262fcf52652b077f Mon Sep 17 00:00:00 2001 From: oyi77 Date: Tue, 31 Mar 2026 04:03:54 +0700 Subject: [PATCH] fix(cache): address code review issues - Add authentication to /api/cache/entries (GET and DELETE) - Add authentication to /api/cache (GET and DELETE) - Validate trendHours: clamp to 1-720 range - Fix estimatedCostSaved bug: use calculated value instead of hardcoded 0 --- src/app/api/cache/entries/route.ts | 9 +++++++++ src/app/api/cache/route.ts | 12 +++++++++++- src/lib/db/settings.ts | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/app/api/cache/entries/route.ts b/src/app/api/cache/entries/route.ts index 26f30b02a9..97ff51ca9a 100644 --- a/src/app/api/cache/entries/route.ts +++ b/src/app/api/cache/entries/route.ts @@ -1,5 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { getDbInstance } from "@/lib/db/core"; +import { isAuthenticated } from "@/shared/utils/apiAuth"; interface CacheEntry { id: string; @@ -12,6 +13,10 @@ interface CacheEntry { } export async function GET(req: NextRequest) { + if (!(await isAuthenticated(req))) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + try { const { searchParams } = new URL(req.url); const page = Math.max(1, parseInt(searchParams.get("page") || "1", 10)); @@ -71,6 +76,10 @@ export async function GET(req: NextRequest) { } export async function DELETE(req: NextRequest) { + if (!(await isAuthenticated(req))) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + try { const { searchParams } = new URL(req.url); const signature = searchParams.get("signature"); diff --git a/src/app/api/cache/route.ts b/src/app/api/cache/route.ts index d1bca53891..dd7364f929 100644 --- a/src/app/api/cache/route.ts +++ b/src/app/api/cache/route.ts @@ -9,15 +9,21 @@ import { } from "@/lib/semanticCache"; import { getIdempotencyStats } from "@/lib/idempotencyLayer"; import { getCacheMetrics, getCacheTrend } from "@/lib/db/settings"; +import { isAuthenticated } from "@/shared/utils/apiAuth"; function errorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error); } export async function GET(req: NextRequest) { + if (!(await isAuthenticated(req))) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + try { const { searchParams } = new URL(req.url); - const trendHours = parseInt(searchParams.get("trendHours") || "24", 10); + const rawHours = parseInt(searchParams.get("trendHours") || "24", 10); + const trendHours = Math.min(720, Math.max(1, Number.isNaN(rawHours) ? 24 : rawHours)); const cacheStats = getCacheStats(); const idempotencyStats = getIdempotencyStats(); @@ -36,6 +42,10 @@ export async function GET(req: NextRequest) { } export async function DELETE(req: NextRequest) { + if (!(await isAuthenticated(req))) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + try { const { searchParams } = new URL(req.url); const model = searchParams.get("model"); diff --git a/src/lib/db/settings.ts b/src/lib/db/settings.ts index 333d71379f..5173e81e14 100644 --- a/src/lib/db/settings.ts +++ b/src/lib/db/settings.ts @@ -630,7 +630,7 @@ export async function getCacheMetrics() { totalCachedTokens: totalsRow?.totalCachedTokens || 0, totalCacheCreationTokens: totalsRow?.totalCacheCreationTokens || 0, tokensSaved, - estimatedCostSaved: 0, // Would need pricing data to calculate + estimatedCostSaved, byProvider, byStrategy, lastUpdated: new Date().toISOString(),