86 lines
2.9 KiB
JavaScript
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
|
|
};
|