Last active
April 26, 2020 06:32
-
-
Save vojtad/28eb4c43806513d7fd2196f97e11a9e8 to your computer and use it in GitHub Desktop.
Helper to enable client-side signing for AWS S3 uploading for Uppy with AWS S3 Multipart. Set callbacks for AWS S3 Multipart plugin to methods from this heper (https://uppy.io/docs/aws-s3-multipart/#createMultipartUpload-file).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AWS from 'aws-sdk'; | |
export default class AwsS3MultipartHelper { | |
constructor(options) { | |
this.options = { | |
bucket: options.bucket, | |
acl: options.acl || 'public-read', | |
expires: options.expires || 5 * 60, | |
}; | |
AWS.config.credentials = new AWS.Credentials({ | |
accessKeyId: options.credentials.accessKeyId, | |
secretAccessKey: options.credentials.secretAccessKey, | |
sessionToken: options.credentials.sessionToken, | |
}); | |
this.s3 = new AWS.S3({}); | |
} | |
createMultipartUpload(file) { | |
return new Promise((resolve, reject) => { | |
const metadata = {}; | |
Object.keys(file.meta).map(key => { | |
if (file.meta[key] != null) { | |
metadata[key] = file.meta[key].toString() | |
} | |
}) | |
const key = file.name; | |
this.s3.createMultipartUpload({ | |
Bucket: this.options.bucket, | |
Key: key, | |
ACL: this.options.acl, | |
ContentType: file.type, | |
Metadata: metadata, | |
Expires: this.options.expires, | |
}, (error, data) => { | |
if (error) { | |
reject(error); | |
} else { | |
resolve({ | |
key: data.Key, | |
uploadId: data.UploadId, | |
}); | |
} | |
}); | |
}); | |
} | |
listParts(file, { key, uploadId }) { | |
return new Promise((resolve, reject) => { | |
let parts = []; | |
const listPartsPart = (part) => { | |
this.s3.listParts({ | |
Bucket: this.options.bucket, | |
Key: key, | |
UploadId: uploadId, | |
PartNumberMarker: part, | |
}, (error, data) => { | |
if (error) { | |
reject(error); | |
return; | |
} | |
parts = parts.concat(data.Parts); | |
if (data.IsTruncated) { | |
listPartsPart(data.NextPartNumberMarker); | |
} else { | |
resolve(parts); | |
} | |
}) | |
} | |
listPartsPart(0); | |
}); | |
} | |
prepareUploadPart(file, { key, uploadId, number }) { | |
return new Promise((resolve, reject) => { | |
this.s3.getSignedUrl('uploadPart', { | |
Bucket: this.options.bucket, | |
Key: key, | |
UploadId: uploadId, | |
PartNumber: number, | |
Body: '', | |
Expires: this.options.expires, | |
}, (error, url) => { | |
if (error) { | |
reject(error); | |
} else { | |
resolve({ url }); | |
} | |
}); | |
}); | |
} | |
abortMultipartUpload(file, { key, uploadId }) { | |
return new Promise((resolve, reject) => { | |
this.s3.abortMultipartUpload({ | |
Bucket: this.options.bucket, | |
Key: key, | |
UploadId: uploadId | |
}, (error, data) => { | |
if (error) { | |
reject(error); | |
} else { | |
resolve({}); | |
} | |
}); | |
}); | |
} | |
completeMultipartUpload(file, { key, uploadId, parts }) { | |
return new Promise((resolve, reject) => { | |
this.s3.completeMultipartUpload({ | |
Bucket: this.options.bucket, | |
Key: key, | |
UploadId: uploadId, | |
MultipartUpload: { | |
Parts: parts | |
} | |
}, (error, data) => { | |
if (error) { | |
reject(error); | |
} else { | |
resolve({ location: data.Location }); | |
} | |
}); | |
}); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I setup this helper and Uppy like this:
Now you can use Uppy as usual, it will use the helper to sign AWS requests on client side.