2017-06-07 23:07:31 +02:00
|
|
|
const AWS = require('aws-sdk');
|
|
|
|
const s3 = new AWS.S3();
|
|
|
|
|
|
|
|
const conf = require('./config.js');
|
|
|
|
const fs = require('fs');
|
|
|
|
const path = require('path');
|
|
|
|
const fetch = require('node-fetch');
|
|
|
|
const crypto = require('crypto');
|
|
|
|
|
2017-06-08 22:45:28 +02:00
|
|
|
|
|
|
|
let notLocalHost =
|
|
|
|
conf.env === 'production' &&
|
|
|
|
conf.s3_bucket !== 'localhost' &&
|
|
|
|
conf.bitly_key !== 'localhost';
|
|
|
|
|
|
|
|
const mozlog = require('./log.js');
|
|
|
|
|
|
|
|
let log = mozlog('portal.storage');
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
const redis = require('redis');
|
2017-06-08 01:46:48 +02:00
|
|
|
const redis_client = redis.createClient({
|
|
|
|
host: conf.redis_host
|
|
|
|
});
|
2017-06-08 01:16:38 +02:00
|
|
|
|
2017-06-08 22:45:28 +02:00
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.on('error', err => {
|
2017-06-08 22:45:28 +02:00
|
|
|
log.info('Redis: ', err);
|
2017-06-08 01:16:38 +02:00
|
|
|
});
|
|
|
|
|
2017-06-07 23:07:31 +02:00
|
|
|
|
2017-06-08 22:45:28 +02:00
|
|
|
|
|
|
|
if (notLocalHost) {
|
2017-06-07 23:07:31 +02:00
|
|
|
module.exports = {
|
2017-06-08 01:16:38 +02:00
|
|
|
filename: filename,
|
|
|
|
length: awsLength,
|
|
|
|
get: awsGet,
|
|
|
|
set: awsSet,
|
|
|
|
delete: awsDelete,
|
2017-06-08 22:45:28 +02:00
|
|
|
forceDelete: awsForceDelete,
|
|
|
|
exists: awsExists
|
2017-06-07 23:07:31 +02:00
|
|
|
};
|
|
|
|
} else {
|
|
|
|
module.exports = {
|
2017-06-08 01:16:38 +02:00
|
|
|
filename: filename,
|
|
|
|
length: localLength,
|
|
|
|
get: localGet,
|
|
|
|
set: localSet,
|
|
|
|
delete: localDelete,
|
2017-06-08 22:45:28 +02:00
|
|
|
forceDelete: localForceDelete,
|
|
|
|
exists: localExists
|
2017-06-07 23:07:31 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function filename(id) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
redis_client.hget(id, 'filename', (err, reply) => {
|
|
|
|
if (!err) {
|
|
|
|
resolve(reply);
|
|
|
|
} else {
|
|
|
|
reject();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 22:45:28 +02:00
|
|
|
function localExists(id) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
redis_client.hget(id, 'filename', (rediserr, reply) => {
|
|
|
|
resolve(fs.existsSync(__dirname + '/../static/' + id) && !rediserr)
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function localLength(id) {
|
2017-06-07 23:07:31 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
try {
|
|
|
|
resolve(fs.statSync(__dirname + '/../static/' + id).size);
|
|
|
|
} catch (err) {
|
|
|
|
reject();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function localGet(id) {
|
2017-06-07 23:07:31 +02:00
|
|
|
return fs.createReadStream(__dirname + '/../static/' + id);
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function localSet(id, file, filename, url) {
|
2017-06-07 23:07:31 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
fstream = fs.createWriteStream(__dirname + '/../static/' + id);
|
|
|
|
file.pipe(fstream);
|
|
|
|
fstream.on('close', () => {
|
|
|
|
let uuid = crypto.randomBytes(10).toString('hex');
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.hmset([id, 'filename', filename, 'delete', uuid]);
|
|
|
|
redis_client.expire(id, 86400000);
|
2017-06-08 22:45:28 +02:00
|
|
|
log.info('localSet:', 'Upload Finished of ' + id);
|
2017-06-07 23:07:31 +02:00
|
|
|
resolve({
|
|
|
|
uuid: uuid,
|
|
|
|
url: url
|
|
|
|
});
|
|
|
|
});
|
2017-06-08 01:16:38 +02:00
|
|
|
|
|
|
|
fstream.on('error', () => reject());
|
2017-06-07 23:07:31 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function localDelete(id, delete_token) {
|
2017-06-07 23:07:31 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.hget(id, 'delete', (err, reply) => {
|
2017-06-07 23:07:31 +02:00
|
|
|
if (!reply || delete_token !== reply) {
|
2017-06-08 01:16:38 +02:00
|
|
|
reject();
|
2017-06-07 23:07:31 +02:00
|
|
|
} else {
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.del(id);
|
|
|
|
resolve(fs.unlinkSync(__dirname + '/../static/' + id));
|
2017-06-07 23:07:31 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function localForceDelete(id) {
|
2017-06-07 23:07:31 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.del(id);
|
2017-06-07 23:07:31 +02:00
|
|
|
resolve(fs.unlinkSync(__dirname + '/../static/' + id));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 22:45:28 +02:00
|
|
|
function awsExists(id) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
s3.getObject(params, function(awserr, data) {
|
|
|
|
redis_client.hget(id, 'filename', (rediserr, reply) => {
|
|
|
|
resolve(!awserr && !rediserr);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function awsLength(id) {
|
2017-06-07 23:07:31 +02:00
|
|
|
let params = {
|
|
|
|
Bucket: conf.s3_bucket,
|
|
|
|
Key: id
|
|
|
|
};
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
s3.headObject(params, function(err, data) {
|
2017-06-08 01:16:38 +02:00
|
|
|
if (!err) {
|
|
|
|
resolve(data.ContentLength);
|
|
|
|
} else {
|
|
|
|
reject();
|
|
|
|
}
|
2017-06-07 23:07:31 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function awsGet(id) {
|
2017-06-07 23:07:31 +02:00
|
|
|
let params = {
|
|
|
|
Bucket: conf.s3_bucket,
|
|
|
|
Key: id
|
|
|
|
};
|
|
|
|
|
|
|
|
return s3.getObject(params).createReadStream();
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function awsSet(id, file, filename, url) {
|
2017-06-07 23:07:31 +02:00
|
|
|
let params = {
|
|
|
|
Bucket: conf.s3_bucket,
|
|
|
|
Key: id,
|
|
|
|
Body: file
|
|
|
|
};
|
|
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
s3.upload(params, function(err, data) {
|
|
|
|
if (err) {
|
2017-06-08 22:45:28 +02:00
|
|
|
log.info('awsUploadError:', err.stack); // an error occurred
|
2017-06-08 01:16:38 +02:00
|
|
|
reject();
|
2017-06-07 23:07:31 +02:00
|
|
|
} else {
|
|
|
|
let uuid = crypto.randomBytes(10).toString('hex');
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.hmset([id, 'filename', filename, 'delete', uuid]);
|
2017-06-07 23:07:31 +02:00
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.expire(id, 86400000);
|
2017-06-08 22:45:28 +02:00
|
|
|
log('awsUploadFinish', 'Upload Finished of ' + filename);
|
2017-06-08 01:16:38 +02:00
|
|
|
if (conf.bitly_key) {
|
|
|
|
fetch(
|
|
|
|
'https://api-ssl.bitly.com/v3/shorten?access_token=' +
|
|
|
|
conf.bitly_key +
|
|
|
|
'&longUrl=' +
|
|
|
|
encodeURIComponent(url) +
|
|
|
|
'&format=txt'
|
|
|
|
)
|
|
|
|
.then(res => {
|
|
|
|
return res.text();
|
|
|
|
})
|
|
|
|
.then(body => {
|
2017-06-07 23:07:31 +02:00
|
|
|
resolve({
|
|
|
|
uuid: uuid,
|
2017-06-08 01:16:38 +02:00
|
|
|
url: body
|
2017-06-07 23:07:31 +02:00
|
|
|
});
|
2017-06-08 01:16:38 +02:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
resolve({
|
|
|
|
uuid: uuid,
|
|
|
|
url: url
|
|
|
|
});
|
|
|
|
}
|
2017-06-07 23:07:31 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function awsDelete(id, delete_token) {
|
2017-06-07 23:07:31 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.hget(id, 'delete', (err, reply) => {
|
2017-06-07 23:07:31 +02:00
|
|
|
if (!reply || delete_token !== reply) {
|
2017-06-08 01:16:38 +02:00
|
|
|
reject();
|
2017-06-07 23:07:31 +02:00
|
|
|
} else {
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.del(id);
|
2017-06-07 23:07:31 +02:00
|
|
|
let params = {
|
|
|
|
Bucket: conf.s3_bucket,
|
|
|
|
Key: id
|
|
|
|
};
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
s3.deleteObject(params, function(err, data) {
|
|
|
|
resolve(err);
|
|
|
|
});
|
2017-06-07 23:07:31 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
function awsForceDelete(id) {
|
2017-06-07 23:07:31 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-06-08 01:16:38 +02:00
|
|
|
redis_client.del(id);
|
2017-06-07 23:07:31 +02:00
|
|
|
let params = {
|
|
|
|
Bucket: conf.s3_bucket,
|
|
|
|
Key: id
|
|
|
|
};
|
|
|
|
|
2017-06-08 01:16:38 +02:00
|
|
|
s3.deleteObject(params, function(err, data) {
|
|
|
|
resolve(err);
|
|
|
|
});
|
2017-06-07 23:07:31 +02:00
|
|
|
});
|
|
|
|
}
|