mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
commit
94fca08500
5 changed files with 112 additions and 54 deletions
|
@ -19,9 +19,12 @@ var _ = require('lodash'),
|
|||
slugs = require('./slugs'),
|
||||
authentication = require('./authentication'),
|
||||
uploads = require('./upload'),
|
||||
dataExport = require('../data/export'),
|
||||
errors = require('../errors'),
|
||||
|
||||
http,
|
||||
formatHttpErrors,
|
||||
addHeaders,
|
||||
cacheInvalidationHeader,
|
||||
locationHeader,
|
||||
contentDispositionHeader,
|
||||
|
@ -135,9 +138,9 @@ locationHeader = function (req, result) {
|
|||
* @return {string}
|
||||
*/
|
||||
contentDispositionHeader = function () {
|
||||
// replace ':' with '_' for OS that don't support it
|
||||
var now = (new Date()).toJSON().replace(/:/g, '_');
|
||||
return 'Attachment; filename="ghost-' + now + '.json"';
|
||||
return dataExport.fileName().then(function (filename) {
|
||||
return 'Attachment; filename="' + filename + '"';
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
@ -172,6 +175,51 @@ formatHttpErrors = function (error) {
|
|||
return {errors: errors, statusCode: statusCode};
|
||||
};
|
||||
|
||||
|
||||
addHeaders = function (apiMethod, req, res, result) {
|
||||
var ops = [],
|
||||
cacheInvalidation,
|
||||
location,
|
||||
contentDisposition;
|
||||
|
||||
cacheInvalidation = cacheInvalidationHeader(req, result)
|
||||
.then(function addCacheHeader(header) {
|
||||
if (header) {
|
||||
res.set({'X-Cache-Invalidate': header});
|
||||
}
|
||||
});
|
||||
|
||||
ops.push(cacheInvalidation);
|
||||
|
||||
if (req.method === 'POST') {
|
||||
location = locationHeader(req, result)
|
||||
.then(function addLocationHeader(header) {
|
||||
if (header) {
|
||||
res.set({'Location': header});
|
||||
// The location header indicates that a new object was created.
|
||||
// In this case the status code should be 201 Created
|
||||
res.status(201);
|
||||
}
|
||||
});
|
||||
ops.push(location);
|
||||
}
|
||||
|
||||
if (apiMethod === db.exportContent) {
|
||||
contentDisposition = contentDispositionHeader()
|
||||
.then(function addContentDispositionHeader(header) {
|
||||
// Add Content-Disposition Header
|
||||
if (apiMethod === db.exportContent) {
|
||||
res.set({
|
||||
'Content-Disposition': header
|
||||
});
|
||||
}
|
||||
});
|
||||
ops.push(contentDisposition);
|
||||
}
|
||||
|
||||
return when.all(ops);
|
||||
};
|
||||
|
||||
/**
|
||||
* ### HTTP
|
||||
*
|
||||
|
@ -186,6 +234,7 @@ http = function (apiMethod) {
|
|||
return function (req, res) {
|
||||
// We define 2 properties for using as arguments in API calls:
|
||||
var object = req.body,
|
||||
response,
|
||||
options = _.extend({}, req.files, req.query, req.params, {
|
||||
context: {
|
||||
user: (req.user && req.user.id) ? req.user.id : null
|
||||
|
@ -202,35 +251,16 @@ http = function (apiMethod) {
|
|||
return apiMethod(object, options)
|
||||
// Handle adding headers
|
||||
.then(function onSuccess(result) {
|
||||
response = result;
|
||||
// Add X-Cache-Invalidate header
|
||||
return cacheInvalidationHeader(req, result)
|
||||
.then(function addCacheHeader(header) {
|
||||
if (header) {
|
||||
res.set({'X-Cache-Invalidate': header});
|
||||
}
|
||||
|
||||
// Add Location header
|
||||
return locationHeader(req, result);
|
||||
}).then(function addLocationHeader(header) {
|
||||
if (header) {
|
||||
res.set({'Location': header});
|
||||
// The location header indicates that a new object was created.
|
||||
// In this case the status code should be 201 Created
|
||||
res.status(201);
|
||||
}
|
||||
|
||||
// Add Content-Disposition Header
|
||||
if (apiMethod === db.exportContent) {
|
||||
res.set({
|
||||
'Content-Disposition': contentDispositionHeader()
|
||||
});
|
||||
}
|
||||
|
||||
// #### Success
|
||||
// Send a properly formatting HTTP response containing the data with correct headers
|
||||
res.json(result || {});
|
||||
});
|
||||
return addHeaders(apiMethod, req, res, result);
|
||||
}).then(function () {
|
||||
// #### Success
|
||||
// Send a properly formatting HTTP response containing the data with correct headers
|
||||
console.log(response);
|
||||
res.json(response || {});
|
||||
}).catch(function onError(error) {
|
||||
errors.logError(error);
|
||||
// #### Error
|
||||
var httpErrors = formatHttpErrors(error);
|
||||
// Send a properly formatted HTTP response containing the errors
|
||||
|
|
|
@ -1,11 +1,31 @@
|
|||
var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
versioning = require('../versioning'),
|
||||
config = require('../../config'),
|
||||
utils = require('../utils'),
|
||||
var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
|
||||
excludedTables = [],
|
||||
exporter;
|
||||
versioning = require('../versioning'),
|
||||
config = require('../../config'),
|
||||
utils = require('../utils'),
|
||||
serverUtils = require('../../utils'),
|
||||
errors = require('../../errors'),
|
||||
settings = require('../../api/settings'),
|
||||
|
||||
excludedTables = ['accesstokens', 'refreshtokens', 'clients'],
|
||||
exporter,
|
||||
exportFileName;
|
||||
|
||||
exportFileName = function () {
|
||||
var datetime = (new Date()).toJSON().substring(0, 10),
|
||||
title = '';
|
||||
|
||||
return settings.read({key: 'title', context: {internal: true}}).then(function (result) {
|
||||
if (result) {
|
||||
title = serverUtils.safeString(result.settings[0].value) + '.';
|
||||
}
|
||||
return title + 'ghost.' + datetime + '.json';
|
||||
}).catch(function (err) {
|
||||
errors.logError(err);
|
||||
return 'ghost.' + datetime + '.json';
|
||||
});
|
||||
};
|
||||
|
||||
exporter = function () {
|
||||
return when.join(versioning.getDatabaseVersion(), utils.getTables()).then(function (results) {
|
||||
|
@ -34,9 +54,10 @@ exporter = function () {
|
|||
|
||||
return when.resolve(exportData);
|
||||
}).catch(function (err) {
|
||||
console.log('Error exporting data: ' + err);
|
||||
errors.logAndThrowError(err, 'Error exporting data', '');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = exporter;
|
||||
module.exports.fileName = exportFileName;
|
||||
|
|
|
@ -44,7 +44,7 @@ backupDatabase = function backupDatabase() {
|
|||
logInfo('Creating database backup');
|
||||
return dataExport().then(function (exportedData) {
|
||||
// Save the exported data to the file system for download
|
||||
var fileName = path.resolve(config().paths.contentPath + '/data/exported-' + (new Date().getTime()) + '.json');
|
||||
var fileName = path.resolve(config().paths.contentPath + '/data/' + dataExport.fileName());
|
||||
|
||||
return nodefn.call(fs.writeFile, fileName, JSON.stringify(exportedData)).then(function () {
|
||||
logInfo('Database backup written to: ' + fileName);
|
||||
|
|
|
@ -11,7 +11,7 @@ var bookshelf = require('bookshelf'),
|
|||
_ = require('lodash'),
|
||||
uuid = require('node-uuid'),
|
||||
config = require('../config'),
|
||||
unidecode = require('unidecode'),
|
||||
utils = require('../utils'),
|
||||
sanitize = require('validator').sanitize,
|
||||
schema = require('../data/schema'),
|
||||
validation = require('../data/validation'),
|
||||
|
@ -343,19 +343,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
|||
});
|
||||
};
|
||||
|
||||
slug = base.trim();
|
||||
|
||||
// Remove non ascii characters
|
||||
slug = unidecode(slug);
|
||||
|
||||
// Remove URL reserved chars: `:/?#[]@!$&'()*+,;=` as well as `\%<>|^~£"`
|
||||
slug = slug.replace(/[:\/\?#\[\]@!$&'()*+,;=\\%<>\|\^~£"]/g, '')
|
||||
// Replace dots and spaces with a dash
|
||||
.replace(/(\s|\.)/g, '-')
|
||||
// Convert 2 or more dashes into a single dash
|
||||
.replace(/-+/g, '-')
|
||||
// Make the whole thing lowercase
|
||||
.toLowerCase();
|
||||
slug = utils.safeString(base);
|
||||
|
||||
// Remove trailing hyphen
|
||||
slug = slug.charAt(slug.length - 1) === '-' ? slug.substr(0, slug.length - 1) : slug;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
var utils,
|
||||
var unidecode = require('unidecode'),
|
||||
|
||||
utils,
|
||||
getRandomInt;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +37,23 @@ utils = {
|
|||
}
|
||||
|
||||
return buf.join('');
|
||||
},
|
||||
safeString: function (string) {
|
||||
string = string.trim();
|
||||
|
||||
// Remove non ascii characters
|
||||
string = unidecode(string);
|
||||
|
||||
// Remove URL reserved chars: `:/?#[]@!$&'()*+,;=` as well as `\%<>|^~£"`
|
||||
string = string.replace(/[:\/\?#\[\]@!$&'()*+,;=\\%<>\|\^~£"]/g, '')
|
||||
// Replace dots and spaces with a dash
|
||||
.replace(/(\s|\.)/g, '-')
|
||||
// Convert 2 or more dashes into a single dash
|
||||
.replace(/-+/g, '-')
|
||||
// Make the whole thing lowercase
|
||||
.toLowerCase();
|
||||
|
||||
return string;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue