chore: move backend to hono + typescript (#558)
* 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 <iniubongobonguko2018@gmail.com>
This commit is contained in:
co-authored by
Iniubong Obonguko
parent
9eb7b01587
commit
82be557a42
@@ -0,0 +1,103 @@
|
||||
import { GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { ZCourseDownloadPresignedUrl, ZCoursePresignUrlUpload } from '$src/types/course';
|
||||
|
||||
import { CLOUDFLARE } from '$src/constants';
|
||||
import type { GetSignedUrlParameters } from '$src/utils/s3';
|
||||
import { Hono } from 'hono';
|
||||
import { authMiddleware } from '$src/middlewares/auth';
|
||||
import { generateFileKey } from '$src/utils/upload';
|
||||
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
||||
import { s3Client } from '$src/utils/s3';
|
||||
|
||||
export const presignRouter = new Hono();
|
||||
|
||||
presignRouter.post('/upload', authMiddleware, async (c) => {
|
||||
const body = await c.req.json();
|
||||
const result = ZCoursePresignUrlUpload.parse(body);
|
||||
|
||||
const { fileName, fileType } = result;
|
||||
const fileKey = generateFileKey(fileName);
|
||||
|
||||
try {
|
||||
const command = new PutObjectCommand({
|
||||
Bucket: CLOUDFLARE.R2.BUCKET,
|
||||
Key: fileKey,
|
||||
ContentType: fileType
|
||||
}) as GetSignedUrlParameters[1];
|
||||
|
||||
const presignedUrl = await getSignedUrl(s3Client as GetSignedUrlParameters[0], command, {
|
||||
expiresIn: CLOUDFLARE.R2.PRESIGN_EXPIRATION_TIME
|
||||
});
|
||||
|
||||
return c.json({
|
||||
success: true,
|
||||
url: presignedUrl,
|
||||
fileKey,
|
||||
message: 'Pre-signed URL generated successfully'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error generating pre-signed URL:', error);
|
||||
|
||||
if (error instanceof Error && error.name === 'SignatureDoesNotMatch') {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
type: 'SIGNATURE_ERROR',
|
||||
message: 'Invalid signature for the request'
|
||||
},
|
||||
403
|
||||
);
|
||||
}
|
||||
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
type: 'INTERNAL_ERROR',
|
||||
message: 'Error generating pre-signed URL'
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
presignRouter.post('/download', authMiddleware, async (c) => {
|
||||
const body = await c.req.json();
|
||||
const result = ZCourseDownloadPresignedUrl.parse(body);
|
||||
|
||||
const { keys } = result;
|
||||
|
||||
try {
|
||||
const signedUrls: Record<string, string> = {};
|
||||
|
||||
await Promise.all(
|
||||
keys.map(async (key) => {
|
||||
const command = new GetObjectCommand({
|
||||
Bucket: CLOUDFLARE.R2.BUCKET,
|
||||
Key: key
|
||||
}) as GetSignedUrlParameters[1];
|
||||
|
||||
const presignedUrl = await getSignedUrl(s3Client as GetSignedUrlParameters[0], command, {
|
||||
expiresIn: CLOUDFLARE.R2.DOWNLOAD_EXPIRATION_TIME
|
||||
});
|
||||
|
||||
signedUrls[key] = presignedUrl;
|
||||
})
|
||||
);
|
||||
|
||||
return c.json({
|
||||
success: true,
|
||||
urls: signedUrls,
|
||||
message: 'Video URLs retrieved successfully'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error Retrieving Video:', error);
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
type: 'INTERNAL_ERROR',
|
||||
message: 'Error Retrieving Video'
|
||||
},
|
||||
500
|
||||
);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user