27 lines
1.2 KiB
TypeScript
27 lines
1.2 KiB
TypeScript
import type { NextRequest } from 'next/server';
|
|
import { authorizeLearningRuntime, runtimeUnauthorized } from '@/lib/makelore-runtime/auth';
|
|
import {
|
|
readFrozenLearningPackageRecord,
|
|
readUniqueMakeloreCoursePackage,
|
|
} from '@/lib/makelore-course/package';
|
|
|
|
export async function GET(request: NextRequest, context: { params: Promise<{ courseId: string }> }) {
|
|
if (!authorizeLearningRuntime(request)) return runtimeUnauthorized();
|
|
const { courseId } = await context.params;
|
|
const contentHash = request.headers.get('x-content-hash')?.trim() || '';
|
|
const record = await readFrozenLearningPackageRecord(courseId).catch(() => null);
|
|
if (!record || record.contentHash !== contentHash) {
|
|
return Response.json({ error: 'course_not_found' }, { status: 404 });
|
|
}
|
|
const bytes = await readUniqueMakeloreCoursePackage(courseId);
|
|
if (!bytes) return Response.json({ error: 'package_not_found' }, { status: 404 });
|
|
return new Response(bytes as unknown as BodyInit, {
|
|
headers: {
|
|
'Content-Type': 'application/zip',
|
|
'Content-Length': String(bytes.byteLength),
|
|
'X-Archive-SHA256': record.archiveSha256,
|
|
'Cache-Control': 'private, no-store',
|
|
},
|
|
});
|
|
}
|