import express from 'express' import { getPresignedUploadUrl } from '../config/s3.js' import logger from '../utils/logger.js' const router = express.Router() // Get presigned URL for image upload // Note: authenticateToken middleware is applied at server level router.post('/presigned-url', async (req, res) => { try { const { filename, contentType } = req.body logger.transaction('GENERATE_PRESIGNED_URL', { userId: req.user.id, filename, contentType }) if (!filename || !contentType) { logger.warn('UPLOAD', 'Missing required fields', { hasFilename: !!filename, hasContentType: !!contentType }) return res.status(400).json({ message: 'Filename and content type are required' }) } // Validate content type if (!contentType.startsWith('image/')) { logger.warn('UPLOAD', 'Invalid content type', { contentType }) return res.status(400).json({ message: 'File must be an image' }) } // Check if AWS credentials are configured if (!process.env.AWS_ACCESS_KEY_ID || !process.env.AWS_SECRET_ACCESS_KEY) { logger.error('UPLOAD', 'AWS credentials not configured', null) return res.status(500).json({ message: 'AWS S3 is not configured. Please set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in backend .env file.' }) } // Support both S3_BUCKET_NAME and AWS_BUCKET_NAME (for compatibility with api-v1) const bucketName = process.env.S3_BUCKET_NAME || process.env.AWS_BUCKET_NAME if (!bucketName) { logger.error('UPLOAD', 'S3 bucket name not configured', null) return res.status(500).json({ message: 'S3 bucket name is not configured. Please set S3_BUCKET_NAME or AWS_BUCKET_NAME in backend .env file.' }) } const startTime = Date.now() const { uploadUrl, imageUrl, key } = await getPresignedUploadUrl(filename, contentType) const duration = Date.now() - startTime logger.s3('PRESIGNED_URL_GENERATED', { userId: req.user.id, filename, key, duration: `${duration}ms` }) logger.transaction('GENERATE_PRESIGNED_URL_SUCCESS', { userId: req.user.id, key, duration: `${duration}ms` }) res.json({ uploadUrl, imageUrl, }) } catch (error) { logger.error('UPLOAD', 'Error generating presigned URL', error) // Provide more specific error messages let errorMessage = 'Failed to generate upload URL' if (error.name === 'InvalidAccessKeyId' || error.name === 'SignatureDoesNotMatch') { errorMessage = 'Invalid AWS credentials. Please check your AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.' } else if (error.name === 'NoSuchBucket') { const bucketName = process.env.S3_BUCKET_NAME || process.env.AWS_BUCKET_NAME errorMessage = `S3 bucket '${bucketName}' does not exist. Please create it or update S3_BUCKET_NAME/AWS_BUCKET_NAME.` } else if (error.message) { errorMessage = error.message } res.status(500).json({ message: errorMessage, error: error.name || 'Unknown error' }) } }) export default router