import { NextRequest, NextResponse } from 'next/server'; import { localStorage } from '@/lib/local-storage'; import path from 'path'; export async function GET(request: NextRequest, { params }: { params: Promise<{ path: string[] }> }) { try { const { path: pathSegments } = await params; const filePath = normalizeStoragePath(pathSegments.join('/')); if (!filePath) { return NextResponse.json({ error: 'Invalid file path' }, { status: 400 }); } if (!localStorage.fileExists(filePath)) { return NextResponse.json({ error: 'File not found' }, { status: 404 }); } const fileBuffer = localStorage.readFile(filePath); const contentType = getContentType(filePath); return new NextResponse(new Uint8Array(fileBuffer), { headers: { 'Content-Type': contentType, 'Content-Disposition': `inline; filename="${path.basename(filePath)}"`, }, }); } catch (error) { console.error('[Local Storage API] Error:', error); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } } function normalizeStoragePath(value: string): string | null { try { const decoded = decodeURIComponent(value); const normalized = path.posix.normalize(decoded).replace(/^\/+/, ''); if (!normalized || normalized.startsWith('..') || normalized.includes('/../') || path.isAbsolute(normalized)) { return null; } return normalized; } catch { return null; } } function getContentType(filePath: string): string { const extension = filePath.split('.').pop()?.toLowerCase(); const contentTypeMap: Record = { 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'webp': 'image/webp', 'gif': 'image/gif', 'mp4': 'video/mp4', 'avi': 'video/x-msvideo', 'mov': 'video/quicktime', 'wmv': 'video/x-ms-wmv', 'pdf': 'application/pdf', 'txt': 'text/plain', 'json': 'application/json', }; return contentTypeMap[extension || ''] || 'application/octet-stream'; }