ghost-storage-adapter-s3-bartt
Advanced tools
Comparing version 0.1.1-development to 0.1.2-development
109
index.js
@@ -19,6 +19,2 @@ 'use strict'; | ||
var _mmmagic = require('mmmagic'); | ||
var _mmmagic2 = _interopRequireDefault(_mmmagic); | ||
var _fs = require('fs'); | ||
@@ -28,3 +24,2 @@ | ||
var magic = new _mmmagic2.default.Magic(_mmmagic2.default.MAGIC_MIME_TYPE); | ||
var readFileAsync = function readFileAsync(fp) { | ||
@@ -51,17 +46,17 @@ return new Promise(function (resolve, reject) { | ||
var accessKeyId = config.accessKeyId, | ||
acl = config.acl, | ||
assetHost = config.assetHost, | ||
bucket = config.bucket, | ||
endpoint = config.endpoint, | ||
forcePathStyle = config.forcePathStyle, | ||
pathPrefix = config.pathPrefix, | ||
region = config.region, | ||
secretAccessKey = config.secretAccessKey, | ||
endpoint = config.endpoint, | ||
serverSideEncryption = config.serverSideEncryption, | ||
signatureVersion = config.signatureVersion; | ||
forcePathStyle = config.forcePathStyle, | ||
signatureVersion = config.signatureVersion, | ||
acl = config.acl; | ||
// Compatible with the aws-sdk's default environment variables | ||
this.accessKeyId = process.env.AWS_ACCESS_KEY_ID || accessKeyId; | ||
this.secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY || secretAccessKey; | ||
this.accessKeyId = accessKeyId; | ||
this.secretAccessKey = secretAccessKey; | ||
this.region = process.env.AWS_DEFAULT_REGION || region; | ||
@@ -81,6 +76,6 @@ | ||
delete(fileName) { | ||
delete(fileName, targetDir) { | ||
var _this = this; | ||
var targetDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getTargetDir(this.pathPrefix); | ||
var directory = targetDir || this.getTargetDir(this.pathPrefix); | ||
@@ -90,3 +85,3 @@ return new Promise(function (resolve, reject) { | ||
Bucket: _this.bucket, | ||
Key: stripLeadingSlash((0, _path.join)(targetDir, fileName)) | ||
Key: stripLeadingSlash((0, _path.join)(directory, fileName)) | ||
}, function (err) { | ||
@@ -98,7 +93,5 @@ return err ? resolve(false) : resolve(true); | ||
exists(fileName) { | ||
exists(fileName, targetDir) { | ||
var _this2 = this; | ||
var targetDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.pathPrefix; | ||
return new Promise(function (resolve, reject) { | ||
@@ -114,2 +107,17 @@ _this2.s3().getObject({ | ||
/** | ||
* | ||
* @param {String} url full url under which the stored content is served, result of save method | ||
* @returns {String} path under which the content is stored | ||
*/ | ||
urlToPath(url) { | ||
if (url.startsWith(this.host)) { | ||
return url.replace(this.host, ''); | ||
} else { | ||
throw new Error({ | ||
message: `The URL "{url}" is not a valid URL for this site.` | ||
}); | ||
} | ||
} | ||
s3() { | ||
@@ -133,9 +141,9 @@ var options = { | ||
save(image) { | ||
save(image, targetDir) { | ||
var _this3 = this; | ||
var targetDir = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getTargetDir(this.pathPrefix); | ||
var directory = targetDir || this.getTargetDir(this.pathPrefix); | ||
return new Promise(function (resolve, reject) { | ||
Promise.all([_this3.getUniqueFileName(image, targetDir), readFileAsync(image.path)]).then(function (_ref) { | ||
Promise.all([_this3.getUniqueFileName(image, directory), readFileAsync(image.path)]).then(function (_ref) { | ||
var _ref2 = _slicedToArray(_ref, 2), | ||
@@ -145,39 +153,18 @@ fileName = _ref2[0], | ||
resolve(_this3.saveRaw(file, fileName)); | ||
}).catch(function (err) { | ||
return reject(err); | ||
}); | ||
}); | ||
} | ||
/** | ||
* Write the image to storage, ensuring that the path to the image stats with the | ||
* prefix and that the target directory exists. The existence of `saveRaw` enables | ||
* Ghost's automatic responsive images. | ||
*/ | ||
saveRaw(buffer, fileName) { | ||
var _this4 = this; | ||
if (!fileName.startsWith(this.pathPrefix)) { | ||
fileName = (0, _path.join)(this.pathPrefix, fileName); | ||
} | ||
return new Promise(function (resolve, reject) { | ||
magic.detect(buffer, function (err, mimeType) { | ||
if (err) { | ||
return reject(err); | ||
} | ||
var config = { | ||
ACL: _this4.acl, | ||
Body: buffer, | ||
Bucket: _this4.bucket, | ||
ACL: _this3.acl, | ||
Body: file, | ||
Bucket: _this3.bucket, | ||
CacheControl: `max-age=${30 * 24 * 60 * 60}`, | ||
ContentType: mimeType, | ||
ContentType: image.type, | ||
Key: stripLeadingSlash(fileName) | ||
}; | ||
if (_this4.serverSideEncryption !== '') { | ||
config.ServerSideEncryption = _this4.serverSideEncryption; | ||
if (_this3.serverSideEncryption !== '') { | ||
config.ServerSideEncryption = _this3.serverSideEncryption; | ||
} | ||
_this4.s3().putObject(config, function (err, data) { | ||
return err ? reject(err) : resolve(`${_this4.host}/${fileName}`); | ||
_this3.s3().putObject(config, function (err, data) { | ||
return err ? reject(err) : resolve(`${_this3.host}/${fileName}`); | ||
}); | ||
}).catch(function (err) { | ||
return reject(err); | ||
}); | ||
@@ -188,8 +175,8 @@ }); | ||
serve() { | ||
var _this5 = this; | ||
var _this4 = this; | ||
return function (req, res, next) { | ||
return _this5.s3().getObject({ | ||
Bucket: _this5.bucket, | ||
Key: stripLeadingSlash(stripEndingSlash(_this5.pathPrefix) + req.path) | ||
return _this4.s3().getObject({ | ||
Bucket: _this4.bucket, | ||
Key: stripLeadingSlash(stripEndingSlash(_this4.pathPrefix) + req.path) | ||
}).on('httpHeaders', function (statusCode, headers, response) { | ||
@@ -205,3 +192,3 @@ return res.set(headers); | ||
read(options) { | ||
var _this6 = this; | ||
var _this5 = this; | ||
@@ -215,9 +202,9 @@ options = options || {}; | ||
// check if path is stored in s3 handled by us | ||
if (path.startsWith(_this6.host)) { | ||
path = path.substring(_this6.host.length); | ||
if (!path.startsWith(_this5.host)) { | ||
reject(new Error(`${path} is not stored in s3`)); | ||
} | ||
path = (0, _path.join)(_this6.pathPrefix, path); | ||
path = path.substring(_this5.host.length); | ||
_this6.s3().getObject({ | ||
Bucket: _this6.bucket, | ||
_this5.s3().getObject({ | ||
Bucket: _this5.bucket, | ||
Key: stripLeadingSlash(path) | ||
@@ -224,0 +211,0 @@ }, function (err, data) { |
{ | ||
"author": "Bart Teeuwisse <bart@thecodemill.biz> (https://thecodemill.biz)", | ||
"author": { | ||
"name": "Bart Teeuwisse", | ||
"email": "bart.teeuwisse@thecodemill.biz", | ||
"url": "https://thecodemill.biz" | ||
}, | ||
"babel": { | ||
@@ -32,4 +36,3 @@ "plugins": [ | ||
"aws-sdk": "^2.331.0", | ||
"ghost-storage-base": "0.0.1", | ||
"mmmagic": "^0.5.3" | ||
"ghost-storage-base": "0.0.1" | ||
}, | ||
@@ -62,3 +65,3 @@ "description": "An AWS S3 storage adapter for Ghost 0.10+", | ||
"type": "git", | ||
"url": "https://github.com/bart/ghost-storage-adapter-s3.git" | ||
"url": "https://github.com/bartt/ghost-storage-adapter-s3.git" | ||
}, | ||
@@ -75,3 +78,3 @@ "scripts": { | ||
}, | ||
"version": "0.1.1-development" | ||
"version": "0.1.2-development" | ||
} |
import AWS from 'aws-sdk' | ||
import BaseStore from 'ghost-storage-base' | ||
import { join } from 'path' | ||
import mmm from 'mmmagic' | ||
import { readFile } from 'fs' | ||
const magic = new mmm.Magic(mmm.MAGIC_MIME_TYPE) | ||
const readFileAsync = fp => new Promise((resolve, reject) => readFile(fp, (err, data) => err ? reject(err) : resolve(data))) | ||
@@ -18,17 +16,17 @@ const stripLeadingSlash = s => s.indexOf('/') === 0 ? s.substring(1) : s | ||
accessKeyId, | ||
acl, | ||
assetHost, | ||
bucket, | ||
endpoint, | ||
forcePathStyle, | ||
pathPrefix, | ||
region, | ||
secretAccessKey, | ||
endpoint, | ||
serverSideEncryption, | ||
signatureVersion | ||
forcePathStyle, | ||
signatureVersion, | ||
acl | ||
} = config | ||
// Compatible with the aws-sdk's default environment variables | ||
this.accessKeyId = process.env.AWS_ACCESS_KEY_ID || accessKeyId | ||
this.secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY || secretAccessKey | ||
this.accessKeyId = accessKeyId | ||
this.secretAccessKey = secretAccessKey | ||
this.region = process.env.AWS_DEFAULT_REGION || region | ||
@@ -48,3 +46,5 @@ | ||
delete (fileName, targetDir = this.getTargetDir(this.pathPrefix)) { | ||
delete (fileName, targetDir) { | ||
const directory = targetDir || this.getTargetDir(this.pathPrefix) | ||
return new Promise((resolve, reject) => { | ||
@@ -54,3 +54,3 @@ this.s3() | ||
Bucket: this.bucket, | ||
Key: stripLeadingSlash(join(targetDir, fileName)) | ||
Key: stripLeadingSlash(join(directory, fileName)) | ||
}, (err) => err ? resolve(false) : resolve(true)) | ||
@@ -60,3 +60,3 @@ }) | ||
exists (fileName, targetDir = this.pathPrefix) { | ||
exists (fileName, targetDir) { | ||
return new Promise((resolve, reject) => { | ||
@@ -71,2 +71,17 @@ this.s3() | ||
/** | ||
* | ||
* @param {String} url full url under which the stored content is served, result of save method | ||
* @returns {String} path under which the content is stored | ||
*/ | ||
urlToPath (url) { | ||
if (url.startsWith(this.host)) { | ||
return url.replace(this.host, '') | ||
} else { | ||
throw new Error({ | ||
message: `The URL "{url}" is not a valid URL for this site.` | ||
}) | ||
} | ||
} | ||
s3 () { | ||
@@ -91,33 +106,16 @@ const options = { | ||
save (image, targetDir = this.getTargetDir(this.pathPrefix)) { | ||
save (image, targetDir) { | ||
const directory = targetDir || this.getTargetDir(this.pathPrefix) | ||
return new Promise((resolve, reject) => { | ||
Promise.all([ | ||
this.getUniqueFileName(image, targetDir), | ||
this.getUniqueFileName(image, directory), | ||
readFileAsync(image.path) | ||
]).then(([ fileName, file ]) => { | ||
resolve(this.saveRaw(file, fileName)) | ||
}).catch(err => reject(err)) | ||
}) | ||
} | ||
/** | ||
* Write the image to storage, ensuring that the path to the image stats with the | ||
* prefix and that the target directory exists. The existence of `saveRaw` enables | ||
* Ghost's automatic responsive images. | ||
*/ | ||
saveRaw (buffer, fileName) { | ||
if (!fileName.startsWith(this.pathPrefix)) { | ||
fileName = join(this.pathPrefix, fileName) | ||
} | ||
return new Promise((resolve, reject) => { | ||
magic.detect(buffer, (err, mimeType) => { | ||
if (err) { | ||
return reject(err) | ||
} | ||
let config = { | ||
ACL: this.acl, | ||
Body: buffer, | ||
Body: file, | ||
Bucket: this.bucket, | ||
CacheControl: `max-age=${30 * 24 * 60 * 60}`, | ||
ContentType: mimeType, | ||
ContentType: image.type, | ||
Key: stripLeadingSlash(fileName) | ||
@@ -128,4 +126,6 @@ } | ||
} | ||
this.s3().putObject(config, (err, data) => err ? reject(err) : resolve(`${this.host}/${fileName}`)) | ||
this.s3() | ||
.putObject(config, (err, data) => err ? reject(err) : resolve(`${this.host}/${fileName}`)) | ||
}) | ||
.catch(err => reject(err)) | ||
}) | ||
@@ -158,6 +158,6 @@ } | ||
// check if path is stored in s3 handled by us | ||
if (path.startsWith(this.host)) { | ||
path = path.substring(this.host.length) | ||
if (!path.startsWith(this.host)) { | ||
reject(new Error(`${path} is not stored in s3`)) | ||
} | ||
path = join(this.pathPrefix, path) | ||
path = path.substring(this.host.length) | ||
@@ -164,0 +164,0 @@ this.s3() |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
2
20
27554
8
315
1
- Removedmmmagic@^0.5.3
- Removedmmmagic@0.5.3(transitive)
- Removednan@2.22.0(transitive)