curaflow/backend/storage.js

86 lines
2.9 KiB
JavaScript

const Minio = require('minio');
const multer = require('multer');
// Configure MinIO Client
const minioClient = new Minio.Client({
endPoint: process.env.MINIO_ENDPOINT || 'localhost',
port: parseInt(process.env.MINIO_PORT) || 9000,
useSSL: process.env.MINIO_USE_SSL === 'true',
accessKey: process.env.MINIO_ACCESS_KEY || 'minioadmin',
secretKey: process.env.MINIO_SECRET_KEY || 'minioadmin'
});
const BUCKET_NAME = process.env.MINIO_BUCKET_NAME || 'curio-media';
// Ensure bucket exists
async function initStorage() {
try {
const exists = await minioClient.bucketExists(BUCKET_NAME);
if (!exists) {
await minioClient.makeBucket(BUCKET_NAME, 'us-east-1');
console.log(`[Storage] Bucket '${BUCKET_NAME}' created successfully.`);
// Set basic public read policy for media
const policy = {
Version: '2012-10-17',
Statement: [
{
Action: ['s3:GetObject'],
Effect: 'Allow',
Principal: '*',
Resource: [`arn:aws:s3:::${BUCKET_NAME}/*`],
},
],
};
await minioClient.setBucketPolicy(BUCKET_NAME, JSON.stringify(policy));
} else {
console.log(`[Storage] Bucket '${BUCKET_NAME}' already exists.`);
}
} catch (err) {
console.error('[Storage] MinIO Init Error:', err.message);
}
}
// Multer in-memory storage for handling multipart form data before streaming to MinIO
const upload = multer({
storage: multer.memoryStorage(),
limits: {
fileSize: 10 * 1024 * 1024, // 10MB max file size
}
});
/**
* Upload a file buffer to MinIO
* @param {string} fileName
* @param {Buffer} fileBuffer
* @param {string} mimeType
* @returns {Promise<string>} Public URL of the uploaded file
*/
async function uploadFile(fileName, fileBuffer, mimeType) {
try {
await minioClient.putObject(BUCKET_NAME, fileName, fileBuffer, fileBuffer.length, {
'Content-Type': mimeType
});
const protocol = process.env.MINIO_USE_SSL === 'true' ? 'https' : 'http';
const port = process.env.MINIO_PORT ? `:${process.env.MINIO_PORT}` : '';
// If MinIO is accessible publicly, return the direct URL.
// For production behind proxy, this might need to be the proxy URL.
const publicUrl = process.env.MINIO_PUBLIC_URL
? `${process.env.MINIO_PUBLIC_URL}/${BUCKET_NAME}/${fileName}`
: `${protocol}://${process.env.MINIO_ENDPOINT || 'localhost'}${port}/${BUCKET_NAME}/${fileName}`;
return publicUrl;
} catch (err) {
console.error('[Storage] Upload Error:', err);
throw err;
}
}
module.exports = {
minioClient,
upload,
initStorage,
uploadFile
};