/** * Test Minio Upload Script * * Usage: * node scripts/test-minio-upload.js * * This script tests connectivity to Minio by uploading a simple test file * and then trying to retrieve it. It uses the same S3 client configuration * as the main application. */ require('dotenv').config(); const { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand } = require('@aws-sdk/client-s3'); // Configuration for S3/Minio from environment variables const S3_CONFIG = { endpoint: process.env.MINIO_S3_UPLOAD_BUCKET_URL, region: process.env.MINIO_AWS_REGION, bucket: process.env.MINIO_AWS_S3_UPLOAD_BUCKET_NAME, accessKey: process.env.MINIO_ACCESS_KEY || process.env.AWS_ACCESS_KEY_ID, secretKey: process.env.MINIO_SECRET_KEY || process.env.AWS_SECRET_ACCESS_KEY, }; // Initialize S3 client with standard configuration const s3Config = { region: S3_CONFIG.region, endpoint: S3_CONFIG.endpoint, forcePathStyle: true, // Required for MinIO }; // Add credentials if available if (S3_CONFIG.accessKey && S3_CONFIG.secretKey) { Object.assign(s3Config, { credentials: { accessKeyId: S3_CONFIG.accessKey, secretAccessKey: S3_CONFIG.secretKey } }); } // Create S3 client const s3Client = new S3Client(s3Config); /** * Generate a public URL for a file stored in Minio/S3 */ function getPublicUrl(filePath) { if (!filePath) return ''; if (filePath.startsWith('http')) return filePath; // Already a full URL // Remove leading slash if present const cleanPath = filePath.startsWith('/') ? filePath.substring(1) : filePath; // Construct the full URL const endpoint = S3_CONFIG.endpoint?.replace(/\/$/, ''); // Remove trailing slash if present const bucket = S3_CONFIG.bucket; // Return original path if no endpoint is configured if (!endpoint) { console.warn('No S3/Minio endpoint configured, returning original path'); return cleanPath; } // Construct and return the full URL return `${endpoint}/${bucket}/${cleanPath}`; } /** * Test Minio connection by uploading and retrieving a test file */ async function testMinioUpload() { // Generate a unique test file path const testKey = `test/upload-test-${Date.now()}.txt`; const testContent = 'This is a test file created at ' + new Date().toISOString(); console.log('=== Testing Minio Upload ==='); console.log('S3 Configuration:'); console.log(' Endpoint:', S3_CONFIG.endpoint || 'MISSING!'); console.log(' Region:', S3_CONFIG.region || 'MISSING!'); console.log(' Bucket:', S3_CONFIG.bucket || 'MISSING!'); console.log(' Has Access Key:', !!S3_CONFIG.accessKey || 'MISSING!'); console.log(' Has Secret Key:', !!S3_CONFIG.secretKey || 'MISSING!'); try { // 1. Upload test file console.log('\nStep 1: Uploading test file...'); console.log(' File path:', testKey); console.log(' Content:', testContent); const uploadCommand = new PutObjectCommand({ Bucket: S3_CONFIG.bucket, Key: testKey, Body: testContent, ContentType: 'text/plain' }); const uploadResult = await s3Client.send(uploadCommand); console.log(' Upload successful!'); console.log(' ETag:', uploadResult.ETag); // 2. Generate public URL const publicUrl = getPublicUrl(testKey); console.log('\nStep 2: Generated public URL:'); console.log(' URL:', publicUrl); // 3. Download the file to verify it was uploaded correctly console.log('\nStep 3: Downloading test file to verify...'); const downloadCommand = new GetObjectCommand({ Bucket: S3_CONFIG.bucket, Key: testKey }); const downloadResult = await s3Client.send(downloadCommand); const downloadedContent = await downloadResult.Body.transformToString(); console.log(' Download successful!'); console.log(' Content:', downloadedContent); if (downloadedContent === testContent) { console.log(' Content verification: ✓ Matches original'); } else { console.log(' Content verification: ✗ Does not match original'); console.log(' Expected:', testContent); console.log(' Received:', downloadedContent); } // 4. Cleanup - Delete the test file console.log('\nStep 4: Cleaning up - deleting test file...'); const deleteCommand = new DeleteObjectCommand({ Bucket: S3_CONFIG.bucket, Key: testKey }); await s3Client.send(deleteCommand); console.log(' Deletion successful!'); console.log('\n=== Test completed successfully ==='); console.log('Minio is properly configured and accessible.'); console.log('File uploads should be working correctly.'); } catch (error) { console.error('\n=== Test failed ==='); console.error('Error details:', error); console.error('\nPossible issues:'); console.error('1. Minio server is not running or not accessible'); console.error('2. Incorrect endpoint URL'); console.error('3. Invalid credentials'); console.error('4. Bucket does not exist or is not accessible'); console.error('5. Network connectivity issues'); console.error('\nEnvironment variables to check:'); console.error('- MINIO_S3_UPLOAD_BUCKET_URL'); console.error('- MINIO_AWS_S3_UPLOAD_BUCKET_NAME'); console.error('- MINIO_ACCESS_KEY / AWS_ACCESS_KEY_ID'); console.error('- MINIO_SECRET_KEY / AWS_SECRET_ACCESS_KEY'); } } // Run the test testMinioUpload();