json-object-editor
Version:
JOE the Json Object Editor | Platform Edition
107 lines (91 loc) • 3.71 kB
JavaScript
function AWSConnect(){
var self = this;
this.default = function(data,req,res){
// AWS SDK v3 (modular)
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
var settings_config = tryEval(JOE.Cache.settings.AWS_S3CONFIG)||{};
var config = $c.merge(settings_config);
var filename = data.filename || req.params.filename||cuid();
var directory = data.directory|| req.params.directory || 'uploads';
var Key = data.Key || directory+'/'+filename;
// Create S3 client with provided config (region/credentials)
const s3 = new S3Client({
region: config.region,
credentials: (config.accessKeyId && config.secretAccessKey) ? {
accessKeyId: config.accessKeyId,
secretAccessKey: config.secretAccessKey,
sessionToken: config.sessionToken
} : undefined
});
// Default to public-read unless explicitly overridden; allows legacy behavior to keep working
var ACL = (data.hasOwnProperty('ACL') ? data.ACL : 'public-read');
var Bucket = JOE.Cache.settings.AWS_BUCKETNAME;
var file = data.file || 'body';
// Create a bucket using bound parameters and put something in it.
var s3Params = {
Bucket: Bucket,
Key:Key,
Body:file
};
if(data.base64){
//var buf = new Buffer(data.base64.replace(/^data:image\/\w+;base64,/, ""),'base64');
var buf = Buffer.from(data.base64.replace(/^data:[a-zA-Z0-9\_\-]*\/[a-zA-Z0-9\_\-]*;base64,/, ""),'base64');
s3Params.Body = buf;
s3Params.ContentEncoding = 'base64';
// Prefer explicit contentType; fall back to extension or a safe default
s3Params.ContentType = data.contentType || data.extension || 'application/octet-stream';
}
var payload = {
params:s3Params,
config:config,
bucket:Bucket,
Key:Key,
reqdata:data,
body:req.body
}
var response = {
Key:Key,
bucket:Bucket
}
// Early validation
if(!Bucket){
return res.status(400).send({ error:'AWS bucket is not configured (settings.AWS_BUCKETNAME).' });
}
if(!config || !config.region){
return res.status(400).send({ error:'AWS S3 region is missing. Set settings.AWS_S3CONFIG.region.' });
}
// Only include ACL if requested (string and not empty)
if(ACL){
s3Params.ACL = ACL;
}
s3.send(new PutObjectCommand(s3Params))
.then(function(data){
// Construct canonical URL from region + bucket
var region = config.region;
var url = 'https://'+Bucket+'.s3.'+region+'.amazonaws.com/'+Key;
response.data = data;
response.url = url;
res.status(200).send(response);
console.log("Successfully uploaded data to "+Key);
})
.catch(function(err){
var code = (err && (err.Code || err.name)) || 'UploadError';
var message = (err && (err.message || String(err))) || 'Upload failed';
// Clear, actionable error when ACLs are disabled on bucket
if(code === 'AccessControlListNotSupported'){
return res.status(400).send({
error: 'Bucket has ACLs disabled (Object Ownership enforced). Remove ACL or switch to presigned/proxy access.',
code: code
});
}
console.log("Error uploading data: ", err);
res.status(500).send({ error: message, code: code });
});
return {use_callback:true};
},
this.html = function(data,req){
return JSON.stringify(self.default(data,req),'','\t\r\n <br/>');
}
return self;
}
module.exports = new AWSConnect();