import { S3Client, ListObjectsV2Command, PutObjectCommand } from '@aws-sdk/client-s3' import { getSignedUrl } from '@aws-sdk/s3-request-presigner' import dotenv from 'dotenv' dotenv.config() const bucketName = process.env.S3_BUCKET_NAME || process.env.AWS_BUCKET_NAME const region = process.env.AWS_REGION || 'ap-south-1' const accessKeyId = process.env.AWS_ACCESS_KEY_ID const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY console.log('\nšŸ” S3 Access Diagnostic Test\n') console.log('Configuration:') console.log(` Bucket: ${bucketName || 'NOT SET'}`) console.log(` Region: ${region}`) console.log(` Access Key ID: ${accessKeyId ? accessKeyId.substring(0, 8) + '...' : 'NOT SET'}`) console.log(` Secret Key: ${secretAccessKey ? '***SET***' : 'NOT SET'}\n`) if (!bucketName) { console.error('āŒ Bucket name not configured!') console.error(' Set S3_BUCKET_NAME or AWS_BUCKET_NAME in .env') process.exit(1) } if (!accessKeyId || !secretAccessKey) { console.error('āŒ AWS credentials not configured!') console.error(' Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in .env') process.exit(1) } const client = new S3Client({ region: region, credentials: { accessKeyId: accessKeyId, secretAccessKey: secretAccessKey, }, }) console.log('Testing S3 access...\n') // Test 1: ListBucket (s3:ListBucket permission) console.log('1ļøāƒ£ Testing ListBucket (s3:ListBucket permission)...') try { const listCommand = new ListObjectsV2Command({ Bucket: bucketName, MaxKeys: 0 // Just check access, don't list objects }) await client.send(listCommand) console.log(' āœ… SUCCESS - ListBucket works!') } catch (error) { console.error(` āŒ FAILED - ${error.name}`) console.error(` Message: ${error.message}`) if (error.name === 'Forbidden' || error.$metadata?.httpStatusCode === 403) { console.error('\n šŸ’” This means:') console.error(' - Your IAM user does NOT have s3:ListBucket permission') console.error(' - OR credentials don\'t match the IAM user with the policy') console.error(' - OR policy is not attached to the IAM user') } else if (error.name === 'NotFound') { console.error('\n šŸ’” Bucket not found - check bucket name and region') } process.exit(1) } // Test 2: Generate Presigned URL (s3:PutObject permission) console.log('\n2ļøāƒ£ Testing Presigned URL generation (s3:PutObject permission)...') try { const putCommand = new PutObjectCommand({ Bucket: bucketName, Key: 'test/test-file.txt', ContentType: 'text/plain' }) const presignedUrl = await getSignedUrl(client, putCommand, { expiresIn: 60 }) console.log(' āœ… SUCCESS - Presigned URL generated!') console.log(` URL: ${presignedUrl.substring(0, 80)}...`) } catch (error) { console.error(` āŒ FAILED - ${error.name}`) console.error(` Message: ${error.message}`) if (error.name === 'Forbidden' || error.$metadata?.httpStatusCode === 403) { console.error('\n šŸ’” This means:') console.error(' - Your IAM user does NOT have s3:PutObject permission') console.error(' - OR credentials don\'t match the IAM user with the policy') } process.exit(1) } console.log('\nāœ… All tests passed! Your S3 configuration is working correctly.') console.log('\nšŸ’” If the backend still shows "access denied", try:') console.log(' 1. Restart the backend server') console.log(' 2. Wait 1-2 minutes for IAM changes to propagate') console.log(' 3. Verify credentials in .env match the IAM user with your policy\n')