Address PR review: dedicated download secret, shared constants, strip filePath, streaming zip

- jwt.ts: Use JWT_DOWNLOAD_SECRET instead of JWT_SECRET for download tokens
- audio-formats.ts: Add EBOOK_EXTENSIONS export alongside AUDIO_EXTENSIONS
- request-statuses.ts: New shared COMPLETED_STATUSES constant used across requests API, download route, and RequestCard
- requests/route.ts: Import COMPLETED_STATUSES; strip filePath from audiobook in API response
- download/route.ts: Import format/status constants; add archiver dependency and replace adm-zip with streaming archiver for multi-file zips
- RequestCard.tsx: Use shared COMPLETED_STATUSES constant
This commit is contained in:
razzamatazm
2026-02-26 16:20:37 -08:00
parent 1006a04337
commit e1629ce516
9 changed files with 880 additions and 56 deletions
+7 -5
View File
@@ -10,6 +10,7 @@ import { z } from 'zod';
import { RMABLogger } from '@/lib/utils/logger';
import { createRequestForUser } from '@/lib/services/request-creator.service';
import { generateDownloadToken } from '@/lib/utils/jwt';
import { COMPLETED_STATUSES } from '@/lib/constants/request-statuses';
const logger = RMABLogger.create('API.Requests');
@@ -147,13 +148,14 @@ export async function GET(request: NextRequest) {
take: limit,
});
const COMPLETED_STATUSES = ['available', 'downloaded'];
const enriched = requests.map(r => {
const isCompleted = COMPLETED_STATUSES.includes(r.status);
const isCompleted = COMPLETED_STATUSES.includes(r.status as typeof COMPLETED_STATUSES[number]);
const hasFile = isCompleted && r.audiobook?.filePath;
if (!hasFile) return r;
const token = generateDownloadToken(req.user!.id, r.id);
return { ...r, downloadUrl: `/api/requests/${r.id}/download?token=${token}` };
const token = hasFile ? generateDownloadToken(req.user!.id, r.id) : null;
const downloadUrl = token ? `/api/requests/${r.id}/download?token=${token}` : undefined;
// Strip server-side absolute path from client response
const audiobook = r.audiobook ? { ...r.audiobook, filePath: undefined } : r.audiobook;
return { ...r, audiobook, ...(downloadUrl ? { downloadUrl } : {}) };
});
return NextResponse.json({