This has been doing my head in for 3ish days now, I’m hoping someone can help.
I’m trying to migrate a project to using EvaporateJS - because of the issues described here: Slingshot file upload to S3 : “error : failed to upload file to cloud storage [-0]”
I considered:
1 - Using https://github.com/VeliovGroup/Meteor-Files - but that does not seem to support direct to S3 uploads, which is important to me
2 - Forking the Slingshot project - I don’t have the technical know how to manipulate it, from the bits and pieces of the code I have looked at. At least, on the surface, migrating to EvaporateJS seems like it will require less time-resources and provide more functionality along with better community support.
However, I’m only at the early stage, trying a simple upload without anything else, but I keep running into this error: net::ERR_NAME_NOT_RESOLVED
.
initiate error: <my-bucket-name>/<my-object-key-name> status:0
The url logged by the initiate error above seems to be spot on - i.e. If the upload actually succeeded, that is where it would be located - and the files in the bucket already are successfully getting downloaded when pointing to identically constructed URL’s.
From Googling around and reading as much as I can, this seems to be an authorisation error, which leads me to believe my custom Auth function is not working as it should - specifically, I believe my function generating the V4 signature might be off.
What I have tried so far:
- To instantiate Evaporate JS (within React):
// ...React stuff
componentWillMount() {
// Instantiate an EvaporateJS instance
const config = {
customAuthMethod: (_signParams, _signHeaders, stringToSign, dateString) => {
return new Promise((resolve, reject) => {
// Meteor method call that returns a promise that resolves a V4 AWS sig
genAwsSig.call({_signParams, _signHeaders, stringToSign, dateString}, (err, res) => {
if (err) reject(err);
console.log('res:', res); // This successfully logs what seems to be a legit key
resolve(res);
});
})
},
aws_key: 'AKIAIXJ2DK7OCYO4FBGA',
awsRegion: 'ap-southeast-2',
aws_url: 'https://ap-southeast-2.amazonaws.com',
bucket: 'bucketName',
computeContentMd5: true,
cryptoMd5Method(data) {
return crypto
.createHash('md5')
.update(data)
.digest('base64');
},
cryptoHexEncodedHash256: data => AWS.util.crypto.md5(data, 'base64'),
};
this.evaporate = Evaporate.create(config);
}
- Function code within the method that generates and resolves into a V4 sig. What I have tried so far:
- Loosely based on the example from …example/evaporate_example.html
export function generateAWSsignature(_signParams, _signHeaders, stringToSign, dateString) {
return new Promise((resolve, reject) => {
try {
const date = hmac(['AWS4', awsSecret].join(''), dateString.substr(0, 8));
const region = hmac(date, 'ap-southeast-2');
const service = hmac(region, 's3');
const signing = hmac(service, 'aws4_request');
const signingKey = AWS.util.crypto.hmac(signing, decodeURIComponent(stringToSign), 'hex');
console.log('signing: ', signing);
console.log('signingKey: ', signingKey);
resolve(signingKey);
} catch (err) {
reject(err);
}
});
}
- Using this package - https://github.com/department-stockholm/aws-signature-v4
export function generateAWSsignature(_signParams, _signHeaders, stringToSign, dateString) {
return new Promise((resolve, reject) => {
try {
resolve(createSignature(secretKey, Date.now(), 'ap-southeast-2', 's3', stringToSign));
} catch (err) {
reject(err);
}
});
}
- Using the way Meteor Slingshot works (current package I am using on the app) - https://github.com/CulturalMe/meteor-slingshot/
export function generateAWSsignature(_signParams, _signHeaders, stringToSign, dateString) {
return new Promise((resolve, reject) => {
try {
const dateKey = hmac256("AWS4" + secretKey, dateString);
const dateRegionKey = hmac256(dateKey, 'ap-southeast-2');
const dateRegionServiceKey = hmac256(dateRegionKey, 's3');
const signingKey = hmac256(dateRegionServiceKey, "aws4_request");
resolve(hmac256(signingKey, policy, "hex")); // No idea what the 'policy' here is meant to be - so obv this did not work
} catch (err) {
reject(err);
}
});
}
So my questions:
1 - Is there something obvious I am missing in my code snippets above?
2 - What exactly does the ERR_NAME_NOT_RESOLVED message mean? Am I right in thinking it is something to do with generating the V4 signature?
Thanks in advance for any pointers/guidance anyone can provide!