// S3Adapter // // Stores Parse files in AWS S3. import * as AWS from 'aws-sdk'; import { FilesAdapter } from './FilesAdapter'; import requiredParameter from '../../requiredParameter'; const DEFAULT_S3_REGION = "us-east-1"; function parseS3AdapterOptions(...options) { if (options.length === 1 && typeof options[0] == "object") { return options; } const additionalOptions = options[3] || {}; return { accessKey: options[0], secretKey: options[1], bucket: options[2], region: additionalOptions.region } } export class S3Adapter extends FilesAdapter { // Creates an S3 session. // Providing AWS access and secret keys is mandatory // Region and bucket will use sane defaults if omitted constructor( accessKey = requiredParameter('S3Adapter requires an accessKey'), secretKey = requiredParameter('S3Adapter requires a secretKey'), bucket, { region = DEFAULT_S3_REGION, bucketPrefix = '', directAccess = false } = {}) { super(); this._region = region; this._bucket = bucket; this._bucketPrefix = bucketPrefix; this._directAccess = directAccess; let s3Options = { accessKeyId: accessKey, secretAccessKey: secretKey, params: { Bucket: this._bucket } }; AWS.config._region = this._region; this._s3Client = new AWS.S3(s3Options); } // For a given config object, filename, and data, store a file in S3 // Returns a promise containing the S3 object creation response createFile(config, filename, data) { let params = { Key: this._bucketPrefix + filename, Body: data }; if (this._directAccess) { params.ACL = "public-read" } return new Promise((resolve, reject) => { this._s3Client.upload(params, (err, data) => { if (err !== null) { return reject(err); } resolve(data); }); }); } deleteFile(config, filename) { return new Promise((resolve, reject) => { let params = { Key: this._bucketPrefix + filename }; this._s3Client.deleteObject(params, (err, data) =>{ if(err !== null) { return reject(err); } resolve(data); }); }); } // Search for and return a file if found by filename // Returns a promise that succeeds with the buffer result from S3 getFileData(config, filename) { let params = {Key: this._bucketPrefix + filename}; return new Promise((resolve, reject) => { this._s3Client.getObject(params, (err, data) => { if (err !== null) { return reject(err); } resolve(data.Body); }); }); } // Generates and returns the location of a file stored in S3 for the given request and filename // The location is the direct S3 link if the option is set, otherwise we serve the file through parse-server getFileLocation(config, filename) { if (this._directAccess) { return `https://${this._bucket}.s3.amazonaws.com/${this._bucketPrefix + filename}`; } return (config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename)); } } export default S3Adapter;