* feat: setup secure presigned uploads and downloads * clean up * update lock * Get presigned url finally working * 557: Migrate backend to hono + ts * chore: update Dockerfile and package.json for backend configuration * add dev command * remove unused packages * Enhance backend API and frontend components for course management - Updated CORS configuration in the backend to allow specific methods and headers. - Refactored lesson download endpoint to use a new route for PDF downloads. - Removed unused certificate download functionality from the lesson router. - Updated frontend components to reflect changes in API endpoints and improve video upload functionality. - Introduced new video upload component and adjusted video handling in lesson materials. - Cleaned up unnecessary imports and optimized component structure for better performance. * PR cleanups * Enhance email configuration by adding SMTP_SENDER environment variable - Updated docker-compose.yaml to include SMTP_SENDER. - Modified Dockerfile to accept SMTP_SENDER as an argument. - Updated environment schema in env.ts to define SMTP_SENDER as optional. - Adjusted mail service to use SMTP_SENDER for the email 'from' field. - Updated documentation to reflect the new SMTP_SENDER variable. * Remove debug log statement from sendEmail function --------- Co-authored-by: Iniubong Obonguko <[email protected]>
92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
import { Context, Hono } from 'hono';
|
|
import { ZCertificateDownload, ZCourseDownloadContent } from '$src/types/course';
|
|
|
|
import { generateCertificate } from '$src/utils/certificate';
|
|
import { generateCoursePdf } from '$src/utils/course';
|
|
import { katexRouter } from '$src/routes/course/katex';
|
|
import { lessonRouter } from '$src/routes/course/lesson';
|
|
import { presignRouter } from '$src/routes/course/presign';
|
|
import { z } from 'zod';
|
|
|
|
export const courseRouter = new Hono();
|
|
|
|
courseRouter.route('/katex', katexRouter);
|
|
courseRouter.route('/lesson', lessonRouter);
|
|
courseRouter.route('/presign', presignRouter);
|
|
|
|
courseRouter.post('/download/certificate', async (c: Context) => {
|
|
try {
|
|
const data = await c.req.json();
|
|
|
|
const validatedData = ZCertificateDownload.parse(data);
|
|
|
|
const result = await generateCertificate(validatedData);
|
|
|
|
c.header('Content-Type', 'application/pdf');
|
|
c.header(
|
|
'Content-Disposition',
|
|
`attachment; filename="certificate-${validatedData.courseName}.pdf"`
|
|
);
|
|
|
|
return c.body(
|
|
new ReadableStream({
|
|
start(controller) {
|
|
controller.enqueue(result);
|
|
controller.close();
|
|
}
|
|
})
|
|
);
|
|
} catch (error) {
|
|
if (error instanceof z.ZodError) {
|
|
return c.json(
|
|
{
|
|
success: false,
|
|
error: 'Validation error',
|
|
details: error.errors
|
|
},
|
|
400
|
|
);
|
|
}
|
|
|
|
console.error('Error generating certificate:', error);
|
|
return c.json(
|
|
{
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
details: error
|
|
},
|
|
500
|
|
);
|
|
}
|
|
});
|
|
|
|
courseRouter.post('/download/content', async (c: Context) => {
|
|
try {
|
|
const data = await c.req.json();
|
|
const validatedData = ZCourseDownloadContent.parse(data);
|
|
|
|
const pdfBuffer = await generateCoursePdf(validatedData);
|
|
|
|
c.header('Content-Type', 'application/pdf');
|
|
|
|
return c.body(
|
|
new ReadableStream({
|
|
start(controller) {
|
|
controller.enqueue(pdfBuffer);
|
|
controller.close();
|
|
}
|
|
})
|
|
);
|
|
} catch (error) {
|
|
console.error('Error generating course PDF:', error);
|
|
return c.json(
|
|
{
|
|
success: false,
|
|
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
details: error
|
|
},
|
|
400
|
|
);
|
|
}
|
|
});
|