This repository has been archived by the owner on Jan 25, 2024. It is now read-only.
forked from muzix/ghost-s3
-
Notifications
You must be signed in to change notification settings - Fork 18
/
index.js
137 lines (117 loc) · 3.8 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
'use strict';
// # S3 storage module for Ghost blog http://ghost.org/
var fs = require('fs');
var path = require('path');
var Bluebird = require('bluebird');
var AWS = require('aws-sdk-promise');
var readFileAsync = Bluebird.promisify(fs.readFile);
var options = {};
var util = require('util');
var BaseStore;
try {
BaseStore = require('ghost/core/server/storage/base');
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') throw e;
BaseStore = require(path.join(process.cwd(), 'core/server/storage/base'));
}
function S3Store(config) {
BaseStore.call(this);
options = config;
}
util.inherits(S3Store, BaseStore);
/**
* Return the URL where image assets can be read.
* @param {String} bucket [AWS S3 bucket name]
* @return {String} [path-style URL of the S3 bucket]
*/
function getAwsPath(bucket) {
var awsRegion = (options.region == 'us-east-1') ? 's3' : 's3-' + options.region;
var awsPath = options.assetHost ? options.assetHost : 'https://' + awsRegion + '.amazonaws.com/' + options.bucket + '/';
return awsPath;
}
function logError(error) {
console.log('error in ghost-s3', error);
}
function logInfo(info) {
console.log('info in ghost-s3', info);
}
function getTargetName(image, targetDir) {
var ext = path.extname(image.name);
var name = path.basename(image.name, ext).replace(/\W/g, '_');
return targetDir + name + '-' + Date.now() + ext;
}
function validOptions(opts) {
return (opts.accessKeyId &&
opts.secretAccessKey &&
opts.bucket &&
opts.region);
}
S3Store.prototype.save = function save(image) {
if (!validOptions(options)) {
return Bluebird.reject('ghost-s3 is not configured');
}
var targetDir = this.getTargetDir();
var targetFilename = getTargetName(image, targetDir);
var s3 = new AWS.S3({
accessKeyId: options.accessKeyId,
secretAccessKey: options.secretAccessKey,
bucket: options.bucket,
region: options.region
});
return readFileAsync(image.path)
.then(function(buffer) {
var params = {
ACL: 'public-read',
Bucket: options.bucket,
Key: targetFilename,
Body: buffer,
ContentType: image.type,
CacheControl: 'max-age=' + (1000 * 365 * 24 * 60 * 60) // 365 days
};
return s3.putObject(params).promise();
})
.tap(function() {
logInfo('ghost-s3', 'Temp uploaded file path: ' + image.path);
})
.then(function(results) {
var awsPath = getAwsPath(options.bucket);
return Bluebird.resolve(awsPath + targetFilename);
})
.catch(function(err) {
logError(err);
throw err;
});
};
// middleware for serving the files
S3Store.prototype.serve = function serve() {
var s3 = new AWS.S3({
accessKeyId: options.accessKeyId,
secretAccessKey: options.secretAccessKey,
bucket: options.bucket,
region: options.region
});
return function (req, res, next) {
var params = {
Bucket: options.bucket,
Key: req.path.replace(/^\//, '')
};
s3.getObject(params)
.on('httpHeaders', function(statusCode, headers, response) {
res.set(headers);
})
.createReadStream()
.on('error', function(err) {
logError(err);
res.status(404);
next();
})
.pipe(res);
};
};
// noop because Ghost requires this function to be defined
// TODO: implement
S3Store.prototype.exists = function exists() {};
// noop because Ghost requires this function to be defined
// TODO: implement
S3Store.prototype.delete = function deleteFile() {};
module.exports = S3Store;