Initial miaojingAI project with image resolution guard

This commit is contained in:
FengLee
2026-05-09 11:32:34 +08:00
commit d499020d4e
264 changed files with 54160 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
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<string, string> = {
'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';
}