mirror of
https://github.com/TryGhost/Ghost.git
synced 2023-12-13 21:00:40 +01:00
parent
f7e92d20e2
commit
07ad400ee0
80 changed files with 924 additions and 981 deletions
100
core/bootstrap.js
vendored
100
core/bootstrap.js
vendored
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
url = require('url'),
|
url = require('url'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
validator = require('validator'),
|
validator = require('validator'),
|
||||||
errors = require('./server/errors'),
|
errors = require('./server/errors'),
|
||||||
config = require('./server/config'),
|
config = require('./server/config'),
|
||||||
|
@ -20,43 +20,42 @@ function readConfigFile(envVal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeConfigFile() {
|
function writeConfigFile() {
|
||||||
var written = when.defer();
|
|
||||||
|
|
||||||
/* Check for config file and copy from config.example.js
|
/* Check for config file and copy from config.example.js
|
||||||
if one doesn't exist. After that, start the server. */
|
if one doesn't exist. After that, start the server. */
|
||||||
fs.exists(configExample, function checkTemplate(templateExists) {
|
return new Promise(function (resolve, reject) {
|
||||||
var read,
|
fs.exists(configExample, function checkTemplate(templateExists) {
|
||||||
write,
|
var read,
|
||||||
error;
|
write,
|
||||||
|
error;
|
||||||
|
|
||||||
if (!templateExists) {
|
if (!templateExists) {
|
||||||
error = new Error('Could not locate a configuration file.');
|
error = new Error('Could not locate a configuration file.');
|
||||||
error.context = appRoot;
|
error.context = appRoot;
|
||||||
error.help = 'Please check your deployment for config.js or config.example.js.';
|
error.help = 'Please check your deployment for config.js or config.example.js.';
|
||||||
|
|
||||||
return written.reject(error);
|
return reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy config.example.js => config.js
|
// Copy config.example.js => config.js
|
||||||
read = fs.createReadStream(configExample);
|
read = fs.createReadStream(configExample);
|
||||||
read.on('error', function (err) {
|
read.on('error', function (err) {
|
||||||
errors.logError(new Error('Could not open config.example.js for read.'), appRoot, 'Please check your deployment for config.js or config.example.js.');
|
errors.logError(new Error('Could not open config.example.js for read.'), appRoot, 'Please check your deployment for config.js or config.example.js.');
|
||||||
|
|
||||||
return written.reject(err);
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
write = fs.createWriteStream(configFile);
|
||||||
|
write.on('error', function (err) {
|
||||||
|
errors.logError(new Error('Could not open config.js for write.'), appRoot, 'Please check your deployment for config.js or config.example.js.');
|
||||||
|
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
write.on('finish', resolve);
|
||||||
|
|
||||||
|
read.pipe(write);
|
||||||
});
|
});
|
||||||
|
|
||||||
write = fs.createWriteStream(configFile);
|
|
||||||
write.on('error', function (err) {
|
|
||||||
errors.logError(new Error('Could not open config.js for write.'), appRoot, 'Please check your deployment for config.js or config.example.js.');
|
|
||||||
|
|
||||||
return written.reject(err);
|
|
||||||
});
|
|
||||||
write.on('finish', written.resolve);
|
|
||||||
|
|
||||||
read.pipe(write);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return written.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateConfigEnvironment() {
|
function validateConfigEnvironment() {
|
||||||
|
@ -70,7 +69,7 @@ function validateConfigEnvironment() {
|
||||||
config = readConfigFile(envVal);
|
config = readConfigFile(envVal);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
return when.reject(e);
|
return Promise.reject(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we don't even have a config
|
// Check if we don't even have a config
|
||||||
|
@ -78,14 +77,14 @@ function validateConfigEnvironment() {
|
||||||
errors.logError(new Error('Cannot find the configuration for the current NODE_ENV'), 'NODE_ENV=' + envVal,
|
errors.logError(new Error('Cannot find the configuration for the current NODE_ENV'), 'NODE_ENV=' + envVal,
|
||||||
'Ensure your config.js has a section for the current NODE_ENV value and is formatted properly.');
|
'Ensure your config.js has a section for the current NODE_ENV value and is formatted properly.');
|
||||||
|
|
||||||
return when.reject(new Error('Unable to load config for NODE_ENV=' + envVal));
|
return Promise.reject(new Error('Unable to load config for NODE_ENV=' + envVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that our url is valid
|
// Check that our url is valid
|
||||||
if (!validator.isURL(config.url, { protocols: ['http', 'https'], require_protocol: true })) {
|
if (!validator.isURL(config.url, { protocols: ['http', 'https'], require_protocol: true })) {
|
||||||
errors.logError(new Error('Your site url in config.js is invalid.'), config.url, 'Please make sure this is a valid url before restarting');
|
errors.logError(new Error('Your site url in config.js is invalid.'), config.url, 'Please make sure this is a valid url before restarting');
|
||||||
|
|
||||||
return when.reject(new Error('invalid site url'));
|
return Promise.reject(new Error('invalid site url'));
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedUrl = url.parse(config.url || 'invalid', false, true);
|
parsedUrl = url.parse(config.url || 'invalid', false, true);
|
||||||
|
@ -93,14 +92,14 @@ function validateConfigEnvironment() {
|
||||||
if (/\/ghost(\/|$)/.test(parsedUrl.pathname)) {
|
if (/\/ghost(\/|$)/.test(parsedUrl.pathname)) {
|
||||||
errors.logError(new Error('Your site url in config.js cannot contain a subdirectory called ghost.'), config.url, 'Please rename the subdirectory before restarting');
|
errors.logError(new Error('Your site url in config.js cannot contain a subdirectory called ghost.'), config.url, 'Please rename the subdirectory before restarting');
|
||||||
|
|
||||||
return when.reject(new Error('ghost subdirectory not allowed'));
|
return Promise.reject(new Error('ghost subdirectory not allowed'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that we have database values
|
// Check that we have database values
|
||||||
if (!config.database || !config.database.client) {
|
if (!config.database || !config.database.client) {
|
||||||
errors.logError(new Error('Your database configuration in config.js is invalid.'), JSON.stringify(config.database), 'Please make sure this is a valid Bookshelf database configuration');
|
errors.logError(new Error('Your database configuration in config.js is invalid.'), JSON.stringify(config.database), 'Please make sure this is a valid Bookshelf database configuration');
|
||||||
|
|
||||||
return when.reject(new Error('invalid database configuration'));
|
return Promise.reject(new Error('invalid database configuration'));
|
||||||
}
|
}
|
||||||
|
|
||||||
hasHostAndPort = config.server && !!config.server.host && !!config.server.port;
|
hasHostAndPort = config.server && !!config.server.host && !!config.server.port;
|
||||||
|
@ -110,33 +109,32 @@ function validateConfigEnvironment() {
|
||||||
if (!config.server || !(hasHostAndPort || hasSocket)) {
|
if (!config.server || !(hasHostAndPort || hasSocket)) {
|
||||||
errors.logError(new Error('Your server values (socket, or host and port) in config.js are invalid.'), JSON.stringify(config.server), 'Please provide them before restarting.');
|
errors.logError(new Error('Your server values (socket, or host and port) in config.js are invalid.'), JSON.stringify(config.server), 'Please provide them before restarting.');
|
||||||
|
|
||||||
return when.reject(new Error('invalid server configuration'));
|
return Promise.reject(new Error('invalid server configuration'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.resolve(config);
|
return Promise.resolve(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadConfig(configFilePath) {
|
function loadConfig(configFilePath) {
|
||||||
var loaded = when.defer(),
|
|
||||||
pendingConfig;
|
|
||||||
|
|
||||||
// Allow config file path to be taken from, in order of importance:
|
|
||||||
// environment process, passed in value, default location
|
|
||||||
configFile = process.env.GHOST_CONFIG || configFilePath || config.paths.config;
|
configFile = process.env.GHOST_CONFIG || configFilePath || config.paths.config;
|
||||||
|
|
||||||
/* Check for config file and copy from config.example.js
|
/* Check for config file and copy from config.example.js
|
||||||
if one doesn't exist. After that, start the server. */
|
if one doesn't exist. After that, start the server. */
|
||||||
fs.exists(configFile, function checkConfig(configExists) {
|
return new Promise(function (resolve, reject) {
|
||||||
if (!configExists) {
|
fs.exists(configFile, function (exists) {
|
||||||
pendingConfig = writeConfigFile();
|
var pendingConfig;
|
||||||
}
|
|
||||||
|
|
||||||
when(pendingConfig).then(validateConfigEnvironment).then(function (rawConfig) {
|
if (!exists) {
|
||||||
return config.init(rawConfig).then(loaded.resolve);
|
pendingConfig = writeConfigFile();
|
||||||
}).catch(loaded.reject);
|
}
|
||||||
|
|
||||||
|
Promise.resolve(pendingConfig)
|
||||||
|
.then(validateConfigEnvironment)
|
||||||
|
.then(function (rawConfig) {
|
||||||
|
resolve(config.init(rawConfig));
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return loaded.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = loadConfig;
|
module.exports = loadConfig;
|
||||||
|
|
|
@ -2,33 +2,17 @@
|
||||||
// Orchestrates the loading of Ghost
|
// Orchestrates the loading of Ghost
|
||||||
// When run from command line.
|
// When run from command line.
|
||||||
|
|
||||||
var when = require('when'),
|
var bootstrap = require('./bootstrap'),
|
||||||
bootstrap = require('./bootstrap'),
|
|
||||||
server = require('./server');
|
server = require('./server');
|
||||||
|
|
||||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
function makeGhost(options) {
|
function makeGhost(options) {
|
||||||
var deferred = when.defer();
|
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
bootstrap(options.config).then(function () {
|
return bootstrap(options.config).then(function () {
|
||||||
try {
|
return server(options.app);
|
||||||
return server(options.app)
|
});
|
||||||
.then(deferred.resolve)
|
|
||||||
.catch(function (err) {
|
|
||||||
// We don't return the rejected promise to stop
|
|
||||||
// the propagation of the rejection and just
|
|
||||||
// allow the user to manage what to do.
|
|
||||||
deferred.reject(err);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
deferred.reject(e);
|
|
||||||
}
|
|
||||||
}).catch(deferred.reject);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = makeGhost;
|
module.exports = makeGhost;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
semver = require('semver'),
|
semver = require('semver'),
|
||||||
packageInfo = require('../../package.json'),
|
packageInfo = require('../../package.json'),
|
||||||
|
@ -88,54 +88,59 @@ GhostServer.prototype.logUpgradeWarning = function () {
|
||||||
|
|
||||||
// Starts the ghost server listening on the configured port
|
// Starts the ghost server listening on the configured port
|
||||||
GhostServer.prototype.start = function () {
|
GhostServer.prototype.start = function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// ## Start Ghost App
|
// ## Start Ghost App
|
||||||
var deferred = when.defer();
|
return new Promise(function (resolve) {
|
||||||
if (config.getSocket()) {
|
if (config.getSocket()) {
|
||||||
// Make sure the socket is gone before trying to create another
|
// Make sure the socket is gone before trying to create another
|
||||||
try {
|
try {
|
||||||
fs.unlinkSync(config.getSocket());
|
fs.unlinkSync(config.getSocket());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// We can ignore this.
|
// We can ignore this.
|
||||||
|
}
|
||||||
|
|
||||||
|
self.httpServer = self.app.listen(
|
||||||
|
config.getSocket()
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.chmod(config.getSocket(), '0660');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.httpServer = self.app.listen(
|
||||||
|
config.server.port,
|
||||||
|
config.server.host
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.httpServer = this.app.listen(
|
self.httpServer.on('connection', self.connection.bind(self));
|
||||||
config.getSocket()
|
self.httpServer.on('listening', function () {
|
||||||
);
|
self.logStartMessages();
|
||||||
fs.chmod(config.getSocket(), '0660');
|
clearTimeout(self.upgradeWarning);
|
||||||
|
resolve(self);
|
||||||
} else {
|
});
|
||||||
this.httpServer = this.app.listen(
|
});
|
||||||
config.server.port,
|
|
||||||
config.server.host
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.httpServer.on('connection', this.connection.bind(this));
|
|
||||||
this.httpServer.on('listening', function () {
|
|
||||||
this.logStartMessages();
|
|
||||||
clearTimeout(this.upgradeWarning);
|
|
||||||
deferred.resolve(this);
|
|
||||||
}.bind(this));
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise that will be fulfilled when the server stops.
|
// Returns a promise that will be fulfilled when the server stops.
|
||||||
// If the server has not been started, the promise will be fulfilled
|
// If the server has not been started, the promise will be fulfilled
|
||||||
// immediately
|
// immediately
|
||||||
GhostServer.prototype.stop = function () {
|
GhostServer.prototype.stop = function () {
|
||||||
var deferred = when.defer();
|
var self = this;
|
||||||
|
|
||||||
if (this.httpServer === null) {
|
return new Promise(function (resolve) {
|
||||||
deferred.resolve(this);
|
if (self.httpServer === null) {
|
||||||
} else {
|
resolve(self);
|
||||||
this.httpServer.close(function () {
|
} else {
|
||||||
this.httpServer = null;
|
self.httpServer.close(function () {
|
||||||
this.logShutdownMessages();
|
self.httpServer = null;
|
||||||
deferred.resolve(this);
|
self.logShutdownMessages();
|
||||||
}.bind(this));
|
resolve(self);
|
||||||
this.closeConnections();
|
});
|
||||||
}
|
|
||||||
return deferred.promise;
|
self.closeConnections();
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Restarts the ghost application
|
// Restarts the ghost application
|
||||||
|
@ -146,8 +151,8 @@ GhostServer.prototype.restart = function () {
|
||||||
// To be called after `stop`
|
// To be called after `stop`
|
||||||
GhostServer.prototype.hammertime = function () {
|
GhostServer.prototype.hammertime = function () {
|
||||||
console.log('Can\'t touch this'.green);
|
console.log('Can\'t touch this'.green);
|
||||||
return this;
|
|
||||||
|
return Promise.resolve(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = GhostServer;
|
module.exports = GhostServer;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ var _ = require('lodash'),
|
||||||
globalUtils = require('../utils'),
|
globalUtils = require('../utils'),
|
||||||
utils = require('./utils'),
|
utils = require('./utils'),
|
||||||
users = require('./users'),
|
users = require('./users'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
authentication;
|
authentication;
|
||||||
|
@ -31,7 +31,7 @@ authentication = {
|
||||||
var setup = result.setup[0].status;
|
var setup = result.setup[0].status;
|
||||||
|
|
||||||
if (!setup) {
|
if (!setup) {
|
||||||
return when.reject(new errors.NoPermissionError('Setup must be completed before making this request.'));
|
return Promise.reject(new errors.NoPermissionError('Setup must be completed before making this request.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.checkObject(object, 'passwordreset');
|
return utils.checkObject(object, 'passwordreset');
|
||||||
|
@ -39,13 +39,10 @@ authentication = {
|
||||||
if (checkedPasswordReset.passwordreset[0].email) {
|
if (checkedPasswordReset.passwordreset[0].email) {
|
||||||
email = checkedPasswordReset.passwordreset[0].email;
|
email = checkedPasswordReset.passwordreset[0].email;
|
||||||
} else {
|
} else {
|
||||||
return when.reject(new errors.BadRequestError('No email provided.'));
|
return Promise.reject(new errors.BadRequestError('No email provided.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return users.read({ context: {internal: true}, email: email, status: 'active' }).then(function (foundUser) {
|
return users.read({ context: {internal: true}, email: email, status: 'active' }).then(function () {
|
||||||
if (!foundUser) {
|
|
||||||
when.reject(new errors.NotFound('Invalid email address'));
|
|
||||||
}
|
|
||||||
return settings.read({context: {internal: true}, key: 'dbHash'});
|
return settings.read({context: {internal: true}, key: 'dbHash'});
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
var dbHash = response.settings[0].value;
|
var dbHash = response.settings[0].value;
|
||||||
|
@ -69,9 +66,9 @@ authentication = {
|
||||||
};
|
};
|
||||||
return mail.send(payload, {context: {internal: true}});
|
return mail.send(payload, {context: {internal: true}});
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.resolve({passwordreset: [{message: 'Check your email for further instructions.'}]});
|
return Promise.resolve({passwordreset: [{message: 'Check your email for further instructions.'}]});
|
||||||
}).otherwise(function (error) {
|
}).catch(function (error) {
|
||||||
return when.reject(error);
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -91,7 +88,7 @@ authentication = {
|
||||||
var setup = result.setup[0].status;
|
var setup = result.setup[0].status;
|
||||||
|
|
||||||
if (!setup) {
|
if (!setup) {
|
||||||
return when.reject(new errors.NoPermissionError('Setup must be completed before making this request.'));
|
return Promise.reject(new errors.NoPermissionError('Setup must be completed before making this request.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.checkObject(object, 'passwordreset');
|
return utils.checkObject(object, 'passwordreset');
|
||||||
|
@ -104,9 +101,9 @@ authentication = {
|
||||||
var dbHash = response.settings[0].value;
|
var dbHash = response.settings[0].value;
|
||||||
return dataProvider.User.resetPassword(resetToken, newPassword, ne2Password, dbHash);
|
return dataProvider.User.resetPassword(resetToken, newPassword, ne2Password, dbHash);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.resolve({passwordreset: [{message: 'Password changed successfully.'}]});
|
return Promise.resolve({passwordreset: [{message: 'Password changed successfully.'}]});
|
||||||
}).otherwise(function (error) {
|
}).catch(function (error) {
|
||||||
return when.reject(new errors.UnauthorizedError(error.message));
|
return Promise.reject(new errors.UnauthorizedError(error.message));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -127,7 +124,7 @@ authentication = {
|
||||||
var setup = result.setup[0].status;
|
var setup = result.setup[0].status;
|
||||||
|
|
||||||
if (!setup) {
|
if (!setup) {
|
||||||
return when.reject(new errors.NoPermissionError('Setup must be completed before making this request.'));
|
return Promise.reject(new errors.NoPermissionError('Setup must be completed before making this request.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.checkObject(object, 'invitation');
|
return utils.checkObject(object, 'invitation');
|
||||||
|
@ -144,9 +141,9 @@ authentication = {
|
||||||
}).then(function (user) {
|
}).then(function (user) {
|
||||||
return dataProvider.User.edit({name: name, email: email}, {id: user.id});
|
return dataProvider.User.edit({name: name, email: email}, {id: user.id});
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.resolve({invitation: [{message: 'Invitation accepted.'}]});
|
return Promise.resolve({invitation: [{message: 'Invitation accepted.'}]});
|
||||||
}).otherwise(function (error) {
|
}).catch(function (error) {
|
||||||
return when.reject(new errors.UnauthorizedError(error.message));
|
return Promise.reject(new errors.UnauthorizedError(error.message));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -156,9 +153,9 @@ authentication = {
|
||||||
qb.whereIn('status', ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked']);
|
qb.whereIn('status', ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked']);
|
||||||
}).fetch().then(function (users) {
|
}).fetch().then(function (users) {
|
||||||
if (users) {
|
if (users) {
|
||||||
return when.resolve({ setup: [{status: true}]});
|
return Promise.resolve({ setup: [{status: true}]});
|
||||||
} else {
|
} else {
|
||||||
return when.resolve({ setup: [{status: false}]});
|
return Promise.resolve({ setup: [{status: false}]});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -171,7 +168,7 @@ authentication = {
|
||||||
var setup = result.setup[0].status;
|
var setup = result.setup[0].status;
|
||||||
|
|
||||||
if (setup) {
|
if (setup) {
|
||||||
return when.reject(new errors.NoPermissionError('Setup has already been completed.'));
|
return Promise.reject(new errors.NoPermissionError('Setup has already been completed.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.checkObject(object, 'setup');
|
return utils.checkObject(object, 'setup');
|
||||||
|
@ -226,7 +223,7 @@ authentication = {
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
return mail.send(payload, {context: {internal: true}}).otherwise(function (error) {
|
return mail.send(payload, {context: {internal: true}}).catch(function (error) {
|
||||||
errors.logError(
|
errors.logError(
|
||||||
error.message,
|
error.message,
|
||||||
"Unable to send welcome email, your blog will continue to function.",
|
"Unable to send welcome email, your blog will continue to function.",
|
||||||
|
@ -235,7 +232,7 @@ authentication = {
|
||||||
});
|
});
|
||||||
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.resolve({ users: [setupUser]});
|
return Promise.resolve({ users: [setupUser]});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,8 +4,7 @@ var dataExport = require('../data/export'),
|
||||||
dataImport = require('../data/import'),
|
dataImport = require('../data/import'),
|
||||||
dataProvider = require('../models'),
|
dataProvider = require('../models'),
|
||||||
fs = require('fs-extra'),
|
fs = require('fs-extra'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
errors = require('../../server/errors'),
|
errors = require('../../server/errors'),
|
||||||
|
@ -41,14 +40,14 @@ db = {
|
||||||
|
|
||||||
// Export data, otherwise send error 500
|
// Export data, otherwise send error 500
|
||||||
return canThis(options.context).exportContent.db().then(function () {
|
return canThis(options.context).exportContent.db().then(function () {
|
||||||
return dataExport().then(function (exportedData) {
|
return dataExport().then(function (exportedData) {
|
||||||
return when.resolve({ db: [exportedData] });
|
return { db: [exportedData] };
|
||||||
}).otherwise(function (error) {
|
}).catch(function (error) {
|
||||||
return when.reject(new errors.InternalServerError(error.message || error));
|
return Promise.reject(new errors.InternalServerError(error.message || error));
|
||||||
|
});
|
||||||
|
}, function () {
|
||||||
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to export data. (no rights)'));
|
||||||
});
|
});
|
||||||
}, function () {
|
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to export data. (no rights)'));
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* ### Import Content
|
* ### Import Content
|
||||||
|
@ -67,16 +66,16 @@ db = {
|
||||||
|
|
||||||
return canThis(options.context).importContent.db().then(function () {
|
return canThis(options.context).importContent.db().then(function () {
|
||||||
if (!options.importfile || !options.importfile.type || !options.importfile.path) {
|
if (!options.importfile || !options.importfile.type || !options.importfile.path) {
|
||||||
return when.reject(new errors.NoPermissionError('Please select a file to import.'));
|
return Promise.reject(new errors.NoPermissionError('Please select a file to import.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
type = options.importfile.type;
|
type = options.importfile.type;
|
||||||
ext = path.extname(options.importfile.name).toLowerCase();
|
ext = path.extname(options.importfile.name).toLowerCase();
|
||||||
filepath = options.importfile.path;
|
filepath = options.importfile.path;
|
||||||
|
|
||||||
return when(isValidFile(ext)).then(function (result) {
|
return Promise.resolve(isValidFile(ext)).then(function (result) {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return when.reject(new errors.UnsupportedMediaTypeError('Please select a .json file to import.'));
|
return Promise.reject(new errors.UnsupportedMediaTypeError('Please select a .json file to import.'));
|
||||||
}
|
}
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return api.settings.read(
|
return api.settings.read(
|
||||||
|
@ -84,12 +83,12 @@ db = {
|
||||||
).then(function (response) {
|
).then(function (response) {
|
||||||
var setting = response.settings[0];
|
var setting = response.settings[0];
|
||||||
|
|
||||||
return when(setting.value);
|
return setting.value;
|
||||||
});
|
});
|
||||||
}).then(function (version) {
|
}).then(function (version) {
|
||||||
databaseVersion = version;
|
databaseVersion = version;
|
||||||
// Read the file contents
|
// Read the file contents
|
||||||
return nodefn.call(fs.readFile, filepath);
|
return Promise.promisify(fs.readFile)(filepath);
|
||||||
}).then(function (fileContents) {
|
}).then(function (fileContents) {
|
||||||
var importData;
|
var importData;
|
||||||
|
|
||||||
|
@ -103,11 +102,11 @@ db = {
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errors.logError(e, 'API DB import content', 'check that the import file is valid JSON.');
|
errors.logError(e, 'API DB import content', 'check that the import file is valid JSON.');
|
||||||
return when.reject(new errors.BadRequest('Failed to parse the import JSON file'));
|
return Promise.reject(new errors.BadRequest('Failed to parse the import JSON file'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!importData.meta || !importData.meta.version) {
|
if (!importData.meta || !importData.meta.version) {
|
||||||
return when.reject(
|
return Promise.reject(
|
||||||
new errors.ValidationError('Import data does not specify version', 'meta.version')
|
new errors.ValidationError('Import data does not specify version', 'meta.version')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -115,16 +114,14 @@ db = {
|
||||||
// Import for the current version
|
// Import for the current version
|
||||||
return dataImport(databaseVersion, importData);
|
return dataImport(databaseVersion, importData);
|
||||||
|
|
||||||
}).then(function importSuccess() {
|
}).then(api.settings.updateSettingsCache)
|
||||||
return api.settings.updateSettingsCache();
|
.return({ db: [] })
|
||||||
}).then(function () {
|
.finally(function () {
|
||||||
return when.resolve({ db: [] });
|
|
||||||
}).finally(function () {
|
|
||||||
// Unlink the file after import
|
// Unlink the file after import
|
||||||
return nodefn.call(fs.unlink, filepath);
|
return Promise.promisify(fs.unlink)(filepath);
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to import data. (no rights)'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to import data. (no rights)'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -139,14 +136,13 @@ db = {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return canThis(options.context).deleteAllContent.db().then(function () {
|
return canThis(options.context).deleteAllContent.db().then(function () {
|
||||||
return when(dataProvider.deleteAllContent())
|
return Promise.resolve(dataProvider.deleteAllContent())
|
||||||
.then(function () {
|
.return({ db: [] })
|
||||||
return when.resolve({ db: [] });
|
.catch(function (error) {
|
||||||
}, function (error) {
|
return Promise.reject(new errors.InternalServerError(error.message || error));
|
||||||
return when.reject(new errors.InternalServerError(error.message || error));
|
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to export data. (no rights)'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to export data. (no rights)'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
// from a theme, an app, or from an external app, you'll use the Ghost JSON API to do so.
|
// from a theme, an app, or from an external app, you'll use the Ghost JSON API to do so.
|
||||||
|
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
// Include Endpoints
|
// Include Endpoints
|
||||||
db = require('./db'),
|
db = require('./db'),
|
||||||
|
@ -90,7 +90,7 @@ cacheInvalidationHeader = function (req, result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return when(cacheInvalidate);
|
return Promise.resolve(cacheInvalidate);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,7 +122,7 @@ locationHeader = function (req, result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return when(location);
|
return Promise.resolve(location);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -219,7 +219,7 @@ addHeaders = function (apiMethod, req, res, result) {
|
||||||
ops.push(contentDisposition);
|
ops.push(contentDisposition);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.all(ops);
|
return Promise.all(ops);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// # Mail API
|
// # Mail API
|
||||||
// API for sending Mail
|
// API for sending Mail
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
canThis = require('../permissions').canThis,
|
canThis = require('../permissions').canThis,
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
|
@ -42,12 +42,12 @@ mail = {
|
||||||
};
|
};
|
||||||
return object;
|
return object;
|
||||||
})
|
})
|
||||||
.otherwise(function (error) {
|
.catch(function (error) {
|
||||||
return when.reject(new errors.EmailError(error.message));
|
return Promise.reject(new errors.EmailError(error.message));
|
||||||
});
|
});
|
||||||
|
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to send mail.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to send mail.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ mail = {
|
||||||
return mail.send(payload, options);
|
return mail.send(payload, options);
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NotFoundError('Could not find the current user'));
|
return Promise.reject(new errors.NotFoundError('Could not find the current user'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ mail = {
|
||||||
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
|
||||||
|
|
||||||
//read the proper email body template
|
//read the proper email body template
|
||||||
return when.promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
fs.readFile(templatesDir + '/' + options.template + '.html', {encoding: 'utf8'}, function (err, fileContent) {
|
fs.readFile(templatesDir + '/' + options.template + '.html', {encoding: 'utf8'}, function (err, fileContent) {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// # Notifications API
|
// # Notifications API
|
||||||
// RESTful API for creating notifications
|
// RESTful API for creating notifications
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
canThis = require('../permissions').canThis,
|
canThis = require('../permissions').canThis,
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
|
@ -26,9 +26,9 @@ notifications = {
|
||||||
*/
|
*/
|
||||||
browse: function browse(options) {
|
browse: function browse(options) {
|
||||||
return canThis(options.context).browse.notification().then(function () {
|
return canThis(options.context).browse.notification().then(function () {
|
||||||
return when({ 'notifications': notificationsStore });
|
return { 'notifications': notificationsStore };
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to browse notifications.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to browse notifications.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -69,10 +69,10 @@ notifications = {
|
||||||
addedNotifications.push(notification);
|
addedNotifications.push(notification);
|
||||||
});
|
});
|
||||||
|
|
||||||
return when({ notifications: addedNotifications});
|
return { notifications: addedNotifications };
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to add notifications.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to add notifications.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -90,21 +90,21 @@ notifications = {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (notification && !notification.dismissible) {
|
if (notification && !notification.dismissible) {
|
||||||
return when.reject(
|
return Promise.reject(
|
||||||
new errors.NoPermissionError('You do not have permission to dismiss this notification.')
|
new errors.NoPermissionError('You do not have permission to dismiss this notification.')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!notification) {
|
if (!notification) {
|
||||||
return when.reject(new errors.NotFoundError('Notification does not exist.'));
|
return Promise.reject(new errors.NotFoundError('Notification does not exist.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationsStore = _.reject(notificationsStore, function (element) {
|
notificationsStore = _.reject(notificationsStore, function (element) {
|
||||||
return element.id === parseInt(options.id, 10);
|
return element.id === parseInt(options.id, 10);
|
||||||
});
|
});
|
||||||
return when({notifications: [notification]});
|
return { notifications: [notification] };
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to destroy notifications.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to destroy notifications.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -119,9 +119,10 @@ notifications = {
|
||||||
return canThis(options.context).destroy.notification().then(function () {
|
return canThis(options.context).destroy.notification().then(function () {
|
||||||
notificationsStore = [];
|
notificationsStore = [];
|
||||||
notificationCounter = 0;
|
notificationCounter = 0;
|
||||||
return when(notificationsStore);
|
|
||||||
|
return notificationsStore;
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to destroy notifications.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to destroy notifications.'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// # Posts API
|
// # Posts API
|
||||||
// RESTful API for the Post resource
|
// RESTful API for the Post resource
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
dataProvider = require('../models'),
|
dataProvider = require('../models'),
|
||||||
canThis = require('../permissions').canThis,
|
canThis = require('../permissions').canThis,
|
||||||
|
@ -88,8 +88,7 @@ posts = {
|
||||||
return { posts: [ result.toJSON() ]};
|
return { posts: [ result.toJSON() ]};
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject(new errors.NotFoundError('Post not found.'));
|
return Promise.reject(new errors.NotFoundError('Post not found.'));
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -122,10 +121,10 @@ posts = {
|
||||||
return { posts: [ post ]};
|
return { posts: [ post ]};
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject(new errors.NotFoundError('Post not found.'));
|
return Promise.reject(new errors.NotFoundError('Post not found.'));
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to edit this post.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to edit posts.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -158,7 +157,7 @@ posts = {
|
||||||
return { posts: [ post ]};
|
return { posts: [ post ]};
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to add posts.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to add posts.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -188,7 +187,7 @@ posts = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to remove posts.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to remove posts.'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// # Roles API
|
// # Roles API
|
||||||
// RESTful API for the Role resource
|
// RESTful API for the Role resource
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
canThis = require('../permissions').canThis,
|
canThis = require('../permissions').canThis,
|
||||||
dataProvider = require('../models'),
|
dataProvider = require('../models'),
|
||||||
|
@ -45,12 +45,12 @@ roles = {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return role;
|
return role;
|
||||||
}, function () {
|
}).catch(function () {
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(permissionMap).then(function (resolved) {
|
return Promise.all(permissionMap).then(function (resolved) {
|
||||||
return { roles: _.filter(resolved, function (role) {
|
return { roles: _.filter(resolved, function (role) {
|
||||||
return role !== null;
|
return role !== null;
|
||||||
}) };
|
}) };
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// RESTful API for the Setting resource
|
// RESTful API for the Setting resource
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
dataProvider = require('../models'),
|
dataProvider = require('../models'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
canThis = require('../permissions').canThis,
|
canThis = require('../permissions').canThis,
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
|
@ -44,7 +44,7 @@ updateSettingsCache = function (settings) {
|
||||||
settingsCache[key] = setting;
|
settingsCache[key] = setting;
|
||||||
});
|
});
|
||||||
|
|
||||||
return when(settingsCache);
|
return Promise.resolve(settingsCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataProvider.Settings.findAll()
|
return dataProvider.Settings.findAll()
|
||||||
|
@ -206,14 +206,14 @@ populateDefaultSetting = function (key) {
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Get the result from the cache with permission checks
|
// Get the result from the cache with permission checks
|
||||||
});
|
});
|
||||||
}).otherwise(function (err) {
|
}).catch(function (err) {
|
||||||
// Pass along NotFoundError
|
// Pass along NotFoundError
|
||||||
if (typeof err === errors.NotFoundError) {
|
if (typeof err === errors.NotFoundError) {
|
||||||
return when.reject(err);
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Different kind of error?
|
// TODO: Different kind of error?
|
||||||
return when.reject(new errors.NotFoundError('Problem finding setting: ' + key));
|
return Promise.reject(new errors.NotFoundError('Problem finding setting: ' + key));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,13 +227,13 @@ populateDefaultSetting = function (key) {
|
||||||
canEditAllSettings = function (settingsInfo, options) {
|
canEditAllSettings = function (settingsInfo, options) {
|
||||||
var checkSettingPermissions = function (setting) {
|
var checkSettingPermissions = function (setting) {
|
||||||
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
||||||
return when.reject(
|
return Promise.reject(
|
||||||
new errors.NoPermissionError('Attempted to access core setting from external request')
|
new errors.NoPermissionError('Attempted to access core setting from external request')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return canThis(options.context).edit.setting(setting.key).catch(function () {
|
return canThis(options.context).edit.setting(setting.key).catch(function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to edit settings.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to edit settings.'));
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -251,7 +251,7 @@ canEditAllSettings = function (settingsInfo, options) {
|
||||||
return checkSettingPermissions(setting);
|
return checkSettingPermissions(setting);
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(checks);
|
return Promise.all(checks);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -281,7 +281,7 @@ settings = {
|
||||||
|
|
||||||
// If there is no context, return only blog settings
|
// If there is no context, return only blog settings
|
||||||
if (!options.context) {
|
if (!options.context) {
|
||||||
return when(_.filter(result.settings, function (setting) { return setting.type === 'blog'; }));
|
return Promise.resolve(_.filter(result.settings, function (setting) { return setting.type === 'blog'; }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise return whatever this context is allowed to browse
|
// Otherwise return whatever this context is allowed to browse
|
||||||
|
@ -312,19 +312,19 @@ settings = {
|
||||||
result[options.key] = setting;
|
result[options.key] = setting;
|
||||||
|
|
||||||
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
if (setting.type === 'core' && !(options.context && options.context.internal)) {
|
||||||
return when.reject(
|
return Promise.reject(
|
||||||
new errors.NoPermissionError('Attempted to access core setting from external request')
|
new errors.NoPermissionError('Attempted to access core setting from external request')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setting.type === 'blog') {
|
if (setting.type === 'blog') {
|
||||||
return when(settingsResult(result));
|
return Promise.resolve(settingsResult(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
return canThis(options.context).read.setting(options.key).then(function () {
|
return canThis(options.context).read.setting(options.key).then(function () {
|
||||||
return settingsResult(result);
|
return settingsResult(result);
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to read settings.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to read settings.'));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var canThis = require('../permissions').canThis,
|
var canThis = require('../permissions').canThis,
|
||||||
dataProvider = require('../models'),
|
dataProvider = require('../models'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
slugs,
|
slugs,
|
||||||
allowedTypes;
|
allowedTypes;
|
||||||
|
@ -35,25 +35,25 @@ slugs = {
|
||||||
|
|
||||||
return canThis(options.context).generate.slug().then(function () {
|
return canThis(options.context).generate.slug().then(function () {
|
||||||
if (allowedTypes[options.type] === undefined) {
|
if (allowedTypes[options.type] === undefined) {
|
||||||
return when.reject(new errors.BadRequestError('Unknown slug type \'' + options.type + '\'.'));
|
return Promise.reject(new errors.BadRequestError('Unknown slug type \'' + options.type + '\'.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataProvider.Base.Model.generateSlug(allowedTypes[options.type], options.name, {status: 'all'}).then(function (slug) {
|
return dataProvider.Base.Model.generateSlug(allowedTypes[options.type], options.name, {status: 'all'}).then(function (slug) {
|
||||||
if (!slug) {
|
if (!slug) {
|
||||||
return when.reject(new errors.InternalServerError('Could not generate slug.'));
|
return Promise.reject(new errors.InternalServerError('Could not generate slug.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { slugs: [{ slug: slug }] };
|
return { slugs: [{ slug: slug }] };
|
||||||
});
|
});
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return when.reject(err);
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to generate a slug.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to generate a slug.'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = slugs;
|
module.exports = slugs;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// # Tag API
|
// # Tag API
|
||||||
// RESTful API for the Tag resource
|
// RESTful API for the Tag resource
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
canThis = require('../permissions').canThis,
|
canThis = require('../permissions').canThis,
|
||||||
dataProvider = require('../models'),
|
dataProvider = require('../models'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
|
@ -24,9 +24,9 @@ tags = {
|
||||||
});
|
});
|
||||||
|
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to browse tags.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to browse tags.'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = tags;
|
module.exports = tags;
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
// # Themes API
|
// # Themes API
|
||||||
// RESTful API for Themes
|
// RESTful API for Themes
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
canThis = require('../permissions').canThis,
|
canThis = require('../permissions').canThis,
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
settings = require('./settings'),
|
settings = require('./settings'),
|
||||||
when = require('when'),
|
|
||||||
themes;
|
themes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +24,7 @@ themes = {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return canThis(options.context).browse.theme().then(function () {
|
return canThis(options.context).browse.theme().then(function () {
|
||||||
return when.all([
|
return Promise.all([
|
||||||
settings.read({key: 'activeTheme', context: {internal: true}}),
|
settings.read({key: 'activeTheme', context: {internal: true}}),
|
||||||
config.paths.availableThemes
|
config.paths.availableThemes
|
||||||
]).then(function (result) {
|
]).then(function (result) {
|
||||||
|
@ -57,7 +56,7 @@ themes = {
|
||||||
return { themes: themes };
|
return { themes: themes };
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to browse themes.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to browse themes.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -73,7 +72,7 @@ themes = {
|
||||||
|
|
||||||
// Check whether the request is properly formatted.
|
// Check whether the request is properly formatted.
|
||||||
if (!_.isArray(object.themes)) {
|
if (!_.isArray(object.themes)) {
|
||||||
return when.reject({type: 'BadRequest', message: 'Invalid request.'});
|
return Promise.reject({type: 'BadRequest', message: 'Invalid request.'});
|
||||||
}
|
}
|
||||||
|
|
||||||
themeName = object.themes[0].uuid;
|
themeName = object.themes[0].uuid;
|
||||||
|
@ -88,7 +87,7 @@ themes = {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!theme) {
|
if (!theme) {
|
||||||
return when.reject(new errors.BadRequestError('Theme does not exist.'));
|
return Promise.reject(new errors.BadRequestError('Theme does not exist.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate the theme
|
// Activate the theme
|
||||||
|
@ -100,7 +99,7 @@ themes = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, function () {
|
}, function () {
|
||||||
return when.reject(new errors.NoPermissionError('You do not have permission to edit themes.'));
|
return Promise.reject(new errors.NoPermissionError('You do not have permission to edit themes.'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
fs = require('fs-extra'),
|
fs = require('fs-extra'),
|
||||||
storage = require('../storage'),
|
storage = require('../storage'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
|
|
||||||
upload;
|
upload;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function isImage(type, ext) {
|
function isImage(type, ext) {
|
||||||
if ((type === 'image/jpeg' || type === 'image/png' || type === 'image/gif' || type === 'image/svg+xml')
|
if ((type === 'image/jpeg' || type === 'image/png' || type === 'image/gif' || type === 'image/svg+xml')
|
||||||
&& (ext === '.jpg' || ext === '.jpeg' || ext === '.png' || ext === '.gif' || ext === '.svg' || ext === '.svgz')) {
|
&& (ext === '.jpg' || ext === '.jpeg' || ext === '.png' || ext === '.gif' || ext === '.svg' || ext === '.svgz')) {
|
||||||
|
@ -17,7 +14,6 @@ function isImage(type, ext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ## Upload API Methods
|
* ## Upload API Methods
|
||||||
*
|
*
|
||||||
|
@ -32,33 +28,33 @@ upload = {
|
||||||
* @param {{context}} options
|
* @param {{context}} options
|
||||||
* @returns {Promise} Success
|
* @returns {Promise} Success
|
||||||
*/
|
*/
|
||||||
'add': function (options) {
|
add: function (options) {
|
||||||
var store = storage.get_storage(),
|
var store = storage.get_storage(),
|
||||||
type,
|
type,
|
||||||
ext,
|
ext,
|
||||||
filepath;
|
filepath;
|
||||||
|
|
||||||
if (!options.uploadimage || !options.uploadimage.type || !options.uploadimage.path) {
|
if (!options.uploadimage || !options.uploadimage.type || !options.uploadimage.path) {
|
||||||
return when.reject(new errors.NoPermissionError('Please select an image.'));
|
return Promise.reject(new errors.NoPermissionError('Please select an image.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
type = options.uploadimage.type;
|
type = options.uploadimage.type;
|
||||||
ext = path.extname(options.uploadimage.name).toLowerCase();
|
ext = path.extname(options.uploadimage.name).toLowerCase();
|
||||||
filepath = options.uploadimage.path;
|
filepath = options.uploadimage.path;
|
||||||
|
|
||||||
return when(isImage(type, ext)).then(function (result) {
|
return Promise.resolve(isImage(type, ext)).then(function (result) {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return when.reject(new errors.UnsupportedMediaTypeError('Please select a valid image.'));
|
return Promise.reject(new errors.UnsupportedMediaTypeError('Please select a valid image.'));
|
||||||
}
|
}
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return store.save(options.uploadimage);
|
return store.save(options.uploadimage);
|
||||||
}).then(function (url) {
|
}).then(function (url) {
|
||||||
return when.resolve(url);
|
return url;
|
||||||
}).finally(function () {
|
}).finally(function () {
|
||||||
// Remove uploaded file from tmp location
|
// Remove uploaded file from tmp location
|
||||||
return nodefn.call(fs.unlink, filepath);
|
return Promise.promisify(fs.unlink)(filepath);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = upload;
|
module.exports = upload;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// # Users API
|
// # Users API
|
||||||
// RESTful API for the User resource
|
// RESTful API for the User resource
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
dataProvider = require('../models'),
|
dataProvider = require('../models'),
|
||||||
settings = require('./settings'),
|
settings = require('./settings'),
|
||||||
|
@ -26,7 +26,7 @@ function prepareInclude(include) {
|
||||||
sendInviteEmail = function sendInviteEmail(user) {
|
sendInviteEmail = function sendInviteEmail(user) {
|
||||||
var emailData;
|
var emailData;
|
||||||
|
|
||||||
return when.join(
|
return Promise.join(
|
||||||
users.read({'id': user.created_by}),
|
users.read({'id': user.created_by}),
|
||||||
settings.read({'key': 'title'}),
|
settings.read({'key': 'title'}),
|
||||||
settings.read({context: {internal: true}, key: 'dbHash'})
|
settings.read({context: {internal: true}, key: 'dbHash'})
|
||||||
|
@ -114,7 +114,7 @@ users = {
|
||||||
return { users: [result.toJSON()] };
|
return { users: [result.toJSON()] };
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject(new errors.NotFoundError('User not found.'));
|
return Promise.reject(new errors.NotFoundError('User not found.'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ users = {
|
||||||
return { users: [result.toJSON()]};
|
return { users: [result.toJSON()]};
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject(new errors.NotFoundError('User not found.'));
|
return Promise.reject(new errors.NotFoundError('User not found.'));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ users = {
|
||||||
|
|
||||||
if (roleId !== contextRoleId &&
|
if (roleId !== contextRoleId &&
|
||||||
parseInt(options.id, 10) === parseInt(options.context.user, 10)) {
|
parseInt(options.id, 10) === parseInt(options.context.user, 10)) {
|
||||||
return when.reject(new errors.NoPermissionError('You cannot change your own role.'));
|
return Promise.reject(new errors.NoPermissionError('You cannot change your own role.'));
|
||||||
} else if (roleId !== contextRoleId) {
|
} else if (roleId !== contextRoleId) {
|
||||||
return dataProvider.User.findOne({role: 'Owner'}).then(function (result) {
|
return dataProvider.User.findOne({role: 'Owner'}).then(function (result) {
|
||||||
if (parseInt(result.id, 10) !== parseInt(options.id, 10)) {
|
if (parseInt(result.id, 10) !== parseInt(options.id, 10)) {
|
||||||
|
@ -168,7 +168,7 @@ users = {
|
||||||
return editOperation();
|
return editOperation();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return when.reject(new errors.NoPermissionError('There has to be one owner.'));
|
return Promise.reject(new errors.NoPermissionError('There has to be one owner.'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ users = {
|
||||||
newUser.password = globalUtils.uid(50);
|
newUser.password = globalUtils.uid(50);
|
||||||
newUser.status = 'invited';
|
newUser.status = 'invited';
|
||||||
} else {
|
} else {
|
||||||
return when.reject(new errors.BadRequestError('No email provided.'));
|
return Promise.reject(new errors.BadRequestError('No email provided.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataProvider.User.getByEmail(
|
return dataProvider.User.getByEmail(
|
||||||
|
@ -221,7 +221,7 @@ users = {
|
||||||
if (foundUser.get('status') === 'invited' || foundUser.get('status') === 'invited-pending') {
|
if (foundUser.get('status') === 'invited' || foundUser.get('status') === 'invited-pending') {
|
||||||
return foundUser;
|
return foundUser;
|
||||||
} else {
|
} else {
|
||||||
return when.reject(new errors.BadRequestError('User is already registered.'));
|
return Promise.reject(new errors.BadRequestError('User is already registered.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(function (invitedUser) {
|
}).then(function (invitedUser) {
|
||||||
|
@ -237,7 +237,7 @@ users = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.resolve({users: [user]});
|
return Promise.resolve({users: [user]});
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
if (error && error.type === 'EmailError') {
|
if (error && error.type === 'EmailError') {
|
||||||
error.message = 'Error sending email: ' + error.message + ' Please check your email settings and resend the invitation.';
|
error.message = 'Error sending email: ' + error.message + ' Please check your email settings and resend the invitation.';
|
||||||
|
@ -250,7 +250,7 @@ users = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return when.reject(error);
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -262,7 +262,7 @@ users = {
|
||||||
// Make sure user is allowed to add a user with this role
|
// Make sure user is allowed to add a user with this role
|
||||||
return dataProvider.Role.findOne({id: roleId}).then(function (role) {
|
return dataProvider.Role.findOne({id: roleId}).then(function (role) {
|
||||||
if (role.get('name') === 'Owner') {
|
if (role.get('name') === 'Owner') {
|
||||||
return when.reject(new errors.NoPermissionError('Not allowed to create an owner user.'));
|
return Promise.reject(new errors.NoPermissionError('Not allowed to create an owner user.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return canThis(options.context).assign.role(role);
|
return canThis(options.context).assign.role(role);
|
||||||
|
@ -300,7 +300,7 @@ users = {
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return result;
|
return result;
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
return when.reject(new errors.InternalServerError(error));
|
return Promise.reject(new errors.InternalServerError(error));
|
||||||
});
|
});
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
return errors.handleAPIError(error);
|
return errors.handleAPIError(error);
|
||||||
|
@ -327,9 +327,9 @@ users = {
|
||||||
ne2Password = checkedPasswordReset.password[0].ne2Password;
|
ne2Password = checkedPasswordReset.password[0].ne2Password;
|
||||||
|
|
||||||
return dataProvider.User.changePassword(oldPassword, newPassword, ne2Password, options).then(function () {
|
return dataProvider.User.changePassword(oldPassword, newPassword, ne2Password, options).then(function () {
|
||||||
return when.resolve({password: [{message: 'Password changed successfully.'}]});
|
return Promise.resolve({password: [{message: 'Password changed successfully.'}]});
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
return when.reject(new errors.ValidationError(error.message));
|
return Promise.reject(new errors.ValidationError(error.message));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -343,9 +343,9 @@ users = {
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return utils.checkObject(object, 'owner').then(function (checkedOwnerTransfer) {
|
return utils.checkObject(object, 'owner').then(function (checkedOwnerTransfer) {
|
||||||
return dataProvider.User.transferOwnership(checkedOwnerTransfer.owner[0], options).then(function (updatedUsers) {
|
return dataProvider.User.transferOwnership(checkedOwnerTransfer.owner[0], options).then(function (updatedUsers) {
|
||||||
return when.resolve({ users: updatedUsers });
|
return Promise.resolve({ users: updatedUsers });
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
return when.reject(new errors.ValidationError(error.message));
|
return Promise.reject(new errors.ValidationError(error.message));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// # API Utils
|
// # API Utils
|
||||||
// Shared helpers for working with the API
|
// Shared helpers for working with the API
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
utils;
|
utils;
|
||||||
|
@ -27,8 +27,8 @@ utils = {
|
||||||
delete object.posts[0].author;
|
delete object.posts[0].author;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return when(object);
|
return Promise.resolve(object);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = utils;
|
module.exports = utils;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
spawn = require('child_process').spawn,
|
spawn = require('child_process').spawn,
|
||||||
win32 = process.platform === 'win32';
|
win32 = process.platform === 'win32';
|
||||||
|
|
||||||
|
@ -11,32 +11,33 @@ function AppDependencies(appPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AppDependencies.prototype.install = function installAppDependencies() {
|
AppDependencies.prototype.install = function installAppDependencies() {
|
||||||
var def = when.defer(),
|
var spawnOpts,
|
||||||
spawnOpts;
|
self = this;
|
||||||
|
|
||||||
fs.exists(path.join(this.appPath, 'package.json'), function (exists) {
|
return new Promise(function (resolve, reject) {
|
||||||
if (!exists) {
|
fs.exists(path.join(self.appPath, 'package.json'), function (exists) {
|
||||||
// Nothing to do, resolve right away?
|
if (!exists) {
|
||||||
def.resolve();
|
// Nothing to do, resolve right away?
|
||||||
} else {
|
resolve();
|
||||||
// Run npm install in the app directory
|
}
|
||||||
spawnOpts = {
|
else {
|
||||||
cwd: this.appPath
|
// Run npm install in the app directory
|
||||||
};
|
spawnOpts = {
|
||||||
|
cwd: self.appPath
|
||||||
|
};
|
||||||
|
|
||||||
this.spawnCommand('npm', ['install', '--production'], spawnOpts)
|
self.spawnCommand('npm', ['install', '--production'], spawnOpts)
|
||||||
.on('error', def.reject)
|
.on('error', reject)
|
||||||
.on('exit', function (err) {
|
.on('exit', function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
def.reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
def.resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}.bind(this));
|
});
|
||||||
|
});
|
||||||
return def.promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normalize a command across OS and spawn it; taken from yeoman/generator
|
// Normalize a command across OS and spawn it; taken from yeoman/generator
|
||||||
|
@ -49,4 +50,4 @@ AppDependencies.prototype.spawnCommand = function (command, args, opt) {
|
||||||
return spawn(winCommand, winArgs, _.defaults({ stdio: 'inherit' }, opt));
|
return spawn(winCommand, winArgs, _.defaults({ stdio: 'inherit' }, opt));
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = AppDependencies;
|
module.exports = AppDependencies;
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
|
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
api = require('../api'),
|
api = require('../api'),
|
||||||
loader = require('./loader'),
|
loader = require('./loader'),
|
||||||
// Holds the available apps
|
// Holds the available apps
|
||||||
availableApps = {};
|
availableApps = {};
|
||||||
|
|
||||||
|
|
||||||
function getInstalledApps() {
|
function getInstalledApps() {
|
||||||
return api.settings.read({context: {internal: true}, key: 'installedApps'}).then(function (response) {
|
return api.settings.read({context: {internal: true}, key: 'installedApps'}).then(function (response) {
|
||||||
var installed = response.settings[0];
|
var installed = response.settings[0];
|
||||||
|
@ -17,7 +16,7 @@ function getInstalledApps() {
|
||||||
try {
|
try {
|
||||||
installed = JSON.parse(installed.value);
|
installed = JSON.parse(installed.value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return when.reject(e);
|
return Promise.reject(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return installed;
|
return installed;
|
||||||
|
@ -49,7 +48,8 @@ module.exports = {
|
||||||
'Your apps will not be loaded.',
|
'Your apps will not be loaded.',
|
||||||
'Check your settings table for typos in the activeApps value. It should look like: ["app-1", "app2"] (double quotes required).'
|
'Check your settings table for typos in the activeApps value. It should look like: ["app-1", "app2"] (double quotes required).'
|
||||||
);
|
);
|
||||||
return when.resolve();
|
|
||||||
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab all installed apps, install any not already installed that are in appsToLoad.
|
// Grab all installed apps, install any not already installed that are in appsToLoad.
|
||||||
|
@ -59,7 +59,7 @@ module.exports = {
|
||||||
// After loading the app, add it to our hash of loaded apps
|
// After loading the app, add it to our hash of loaded apps
|
||||||
loadedApps[name] = loadedApp;
|
loadedApps[name] = loadedApp;
|
||||||
|
|
||||||
return when.resolve(loadedApp);
|
return Promise.resolve(loadedApp);
|
||||||
},
|
},
|
||||||
loadPromises = _.map(appsToLoad, function (app) {
|
loadPromises = _.map(appsToLoad, function (app) {
|
||||||
// If already installed, just activate the app
|
// If already installed, just activate the app
|
||||||
|
@ -77,13 +77,13 @@ module.exports = {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(loadPromises).then(function () {
|
return Promise.all(loadPromises).then(function () {
|
||||||
// Save our installed apps to settings
|
// Save our installed apps to settings
|
||||||
return saveInstalledApps(_.keys(loadedApps));
|
return saveInstalledApps(_.keys(loadedApps));
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Extend the loadedApps onto the available apps
|
// Extend the loadedApps onto the available apps
|
||||||
_.extend(availableApps, loadedApps);
|
_.extend(availableApps, loadedApps);
|
||||||
}).otherwise(function (err) {
|
}).catch(function (err) {
|
||||||
errors.logError(
|
errors.logError(
|
||||||
err.message || err,
|
err.message || err,
|
||||||
'The app will not be loaded',
|
'The app will not be loaded',
|
||||||
|
@ -93,4 +93,4 @@ module.exports = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
availableApps: availableApps
|
availableApps: availableApps
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
var path = require('path'),
|
var path = require('path'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
AppProxy = require('./proxy'),
|
AppProxy = require('./proxy'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
AppSandbox = require('./sandbox'),
|
AppSandbox = require('./sandbox'),
|
||||||
|
@ -64,9 +64,9 @@ loader = {
|
||||||
// Load app permissions
|
// Load app permissions
|
||||||
var perms = new AppPermissions(appPath);
|
var perms = new AppPermissions(appPath);
|
||||||
|
|
||||||
return perms.read().otherwise(function (err) {
|
return perms.read().catch(function (err) {
|
||||||
// Provide a helpful error about which app
|
// Provide a helpful error about which app
|
||||||
return when.reject(new Error("Error loading app named " + name + "; problem reading permissions: " + err.message));
|
return Promise.reject(new Error("Error loading app named " + name + "; problem reading permissions: " + err.message));
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(function (appPerms) {
|
.then(function (appPerms) {
|
||||||
|
@ -76,15 +76,13 @@ loader = {
|
||||||
|
|
||||||
// Check for an install() method on the app.
|
// Check for an install() method on the app.
|
||||||
if (!_.isFunction(app.install)) {
|
if (!_.isFunction(app.install)) {
|
||||||
return when.reject(new Error("Error loading app named " + name + "; no install() method defined."));
|
return Promise.reject(new Error("Error loading app named " + name + "; no install() method defined."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the app.install() method
|
// Run the app.install() method
|
||||||
// Wrapping the install() with a when because it's possible
|
// Wrapping the install() with a when because it's possible
|
||||||
// to not return a promise from it.
|
// to not return a promise from it.
|
||||||
return when(app.install(appProxy)).then(function () {
|
return Promise.resolve(app.install(appProxy)).return(app);
|
||||||
return when.resolve(app);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -99,16 +97,14 @@ loader = {
|
||||||
|
|
||||||
// Check for an activate() method on the app.
|
// Check for an activate() method on the app.
|
||||||
if (!_.isFunction(app.activate)) {
|
if (!_.isFunction(app.activate)) {
|
||||||
return when.reject(new Error("Error loading app named " + name + "; no activate() method defined."));
|
return Promise.reject(new Error("Error loading app named " + name + "; no activate() method defined."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapping the activate() with a when because it's possible
|
// Wrapping the activate() with a when because it's possible
|
||||||
// to not return a promise from it.
|
// to not return a promise from it.
|
||||||
return when(app.activate(appProxy)).then(function () {
|
return Promise.resolve(app.activate(appProxy)).return(app);
|
||||||
return when.resolve(app);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = loader;
|
module.exports = loader;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
parsePackageJson = require('../require-tree').parsePackageJson;
|
parsePackageJson = require('../require-tree').parsePackageJson;
|
||||||
|
|
||||||
|
@ -10,44 +10,35 @@ function AppPermissions(appPath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AppPermissions.prototype.read = function () {
|
AppPermissions.prototype.read = function () {
|
||||||
var self = this,
|
var self = this;
|
||||||
def = when.defer();
|
|
||||||
|
|
||||||
this.checkPackageContentsExists()
|
return this.checkPackageContentsExists().then(function (exists) {
|
||||||
.then(function (exists) {
|
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
// If no package.json, return default permissions
|
// If no package.json, return default permissions
|
||||||
return def.resolve(AppPermissions.DefaultPermissions);
|
return Promise.resolve(AppPermissions.DefaultPermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and parse the package.json
|
// Read and parse the package.json
|
||||||
self.getPackageContents()
|
return self.getPackageContents().then(function (parsed) {
|
||||||
.then(function (parsed) {
|
|
||||||
// If no permissions in the package.json then return the default permissions.
|
// If no permissions in the package.json then return the default permissions.
|
||||||
if (!(parsed.ghost && parsed.ghost.permissions)) {
|
if (!(parsed.ghost && parsed.ghost.permissions)) {
|
||||||
return def.resolve(AppPermissions.DefaultPermissions);
|
return Promise.resolve(AppPermissions.DefaultPermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Validation on permissions object?
|
// TODO: Validation on permissions object?
|
||||||
|
|
||||||
def.resolve(parsed.ghost.permissions);
|
return Promise.resolve(parsed.ghost.permissions);
|
||||||
})
|
});
|
||||||
.otherwise(def.reject);
|
});
|
||||||
})
|
|
||||||
.otherwise(def.reject);
|
|
||||||
|
|
||||||
return def.promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AppPermissions.prototype.checkPackageContentsExists = function () {
|
AppPermissions.prototype.checkPackageContentsExists = function () {
|
||||||
// Mostly just broken out for stubbing in unit tests
|
// Mostly just broken out for stubbing in unit tests
|
||||||
var def = when.defer();
|
return new Promise(function (resolve) {
|
||||||
|
fs.exists(this.packagePath, function (exists) {
|
||||||
fs.exists(this.packagePath, function (exists) {
|
resolve(exists);
|
||||||
def.resolve(exists);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return def.promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the contents of the package.json in the appPath root
|
// Get the contents of the package.json in the appPath root
|
||||||
|
@ -60,7 +51,7 @@ AppPermissions.prototype.getPackageContents = function () {
|
||||||
return parsePackageJson(this.packagePath, messages)
|
return parsePackageJson(this.packagePath, messages)
|
||||||
.then(function (parsed) {
|
.then(function (parsed) {
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
return when.reject(new Error(messages.errors[0].message));
|
return Promise.reject(new Error(messages.errors[0].message));
|
||||||
}
|
}
|
||||||
|
|
||||||
return parsed;
|
return parsed;
|
||||||
|
@ -72,4 +63,4 @@ AppPermissions.DefaultPermissions = {
|
||||||
posts: ['browse', 'read']
|
posts: ['browse', 'read']
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = AppPermissions;
|
module.exports = AppPermissions;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// All other files that need to reference config.js should use this file.
|
// All other files that need to reference config.js should use this file.
|
||||||
|
|
||||||
var path = require('path'),
|
var path = require('path'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
url = require('url'),
|
url = require('url'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
knex = require('knex'),
|
knex = require('knex'),
|
||||||
|
@ -101,7 +101,7 @@ function initConfig(rawConfig) {
|
||||||
// just the object appropriate for this NODE_ENV
|
// just the object appropriate for this NODE_ENV
|
||||||
updateConfig(rawConfig);
|
updateConfig(rawConfig);
|
||||||
|
|
||||||
return when.all([requireTree(ghostConfig.paths.themePath), requireTree(ghostConfig.paths.appPath)]).then(function (paths) {
|
return Promise.all([requireTree(ghostConfig.paths.themePath), requireTree(ghostConfig.paths.appPath)]).then(function (paths) {
|
||||||
ghostConfig.paths.availableThemes = paths[0];
|
ghostConfig.paths.availableThemes = paths[0];
|
||||||
ghostConfig.paths.availableApps = paths[1];
|
ghostConfig.paths.availableApps = paths[1];
|
||||||
return ghostConfig;
|
return ghostConfig;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Holds all theme configuration information
|
// Holds all theme configuration information
|
||||||
// that as mostly used by templates and handlebar helpers.
|
// that as mostly used by templates and handlebar helpers.
|
||||||
|
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
themeConfig = {};
|
themeConfig = {};
|
||||||
|
@ -18,7 +18,7 @@ function theme() {
|
||||||
// tries to access the config() object before it is created.
|
// tries to access the config() object before it is created.
|
||||||
function update(settings, configUrl) {
|
function update(settings, configUrl) {
|
||||||
// TODO: Pass the context into this method instead of hard coding internal: true?
|
// TODO: Pass the context into this method instead of hard coding internal: true?
|
||||||
return when.all([
|
return Promise.all([
|
||||||
settings.read('title'),
|
settings.read('title'),
|
||||||
settings.read('description'),
|
settings.read('description'),
|
||||||
settings.read('logo'),
|
settings.read('logo'),
|
||||||
|
@ -30,7 +30,6 @@ function update(settings, configUrl) {
|
||||||
themeConfig.description = globals[1].settings[0].value;
|
themeConfig.description = globals[1].settings[0].value;
|
||||||
themeConfig.logo = globals[2].settings[0] ? globals[2].settings[0].value : '';
|
themeConfig.logo = globals[2].settings[0] ? globals[2].settings[0].value : '';
|
||||||
themeConfig.cover = globals[3].settings[0] ? globals[3].settings[0].value : '';
|
themeConfig.cover = globals[3].settings[0] ? globals[3].settings[0].value : '';
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
|
||||||
api = require('../api'),
|
api = require('../api'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
updateCheck = require('../update-check'),
|
updateCheck = require('../update-check'),
|
||||||
|
@ -9,7 +8,7 @@ adminControllers = {
|
||||||
// Route: index
|
// Route: index
|
||||||
// Path: /ghost/
|
// Path: /ghost/
|
||||||
// Method: GET
|
// Method: GET
|
||||||
'index': function (req, res) {
|
index: function (req, res) {
|
||||||
/*jslint unparam:true*/
|
/*jslint unparam:true*/
|
||||||
|
|
||||||
function renderIndex() {
|
function renderIndex() {
|
||||||
|
@ -20,7 +19,7 @@ adminControllers = {
|
||||||
return updateCheck.showUpdateNotification();
|
return updateCheck.showUpdateNotification();
|
||||||
}).then(function (updateVersion) {
|
}).then(function (updateVersion) {
|
||||||
if (!updateVersion) {
|
if (!updateVersion) {
|
||||||
return when.resolve();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var notification = {
|
var notification = {
|
||||||
|
|
|
@ -8,8 +8,7 @@ var moment = require('moment'),
|
||||||
RSS = require('rss'),
|
RSS = require('rss'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
url = require('url'),
|
url = require('url'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
api = require('../api'),
|
api = require('../api'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
filters = require('../../server/filters'),
|
filters = require('../../server/filters'),
|
||||||
|
@ -84,9 +83,7 @@ function formatResponse(post) {
|
||||||
|
|
||||||
function handleError(next) {
|
function handleError(next) {
|
||||||
return function (err) {
|
return function (err) {
|
||||||
var e = new Error(err.message);
|
return next(err);
|
||||||
e.status = err.code;
|
|
||||||
return next(e);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +149,7 @@ frontendControllers = {
|
||||||
res.render(view, formatPageResponse(posts, page));
|
res.render(view, formatPageResponse(posts, page));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).otherwise(handleError(next));
|
}).catch(handleError(next));
|
||||||
},
|
},
|
||||||
'tag': function (req, res, next) {
|
'tag': function (req, res, next) {
|
||||||
// Parse the page number
|
// Parse the page number
|
||||||
|
@ -206,7 +203,7 @@ frontendControllers = {
|
||||||
res.render(view, result);
|
res.render(view, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).otherwise(handleError(next));
|
}).catch(handleError(next));
|
||||||
},
|
},
|
||||||
'author': function (req, res, next) {
|
'author': function (req, res, next) {
|
||||||
|
|
||||||
|
@ -263,7 +260,7 @@ frontendControllers = {
|
||||||
res.render(view, result);
|
res.render(view, result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).otherwise(handleError(next));
|
}).catch(handleError(next));
|
||||||
},
|
},
|
||||||
|
|
||||||
'single': function (req, res, next) {
|
'single': function (req, res, next) {
|
||||||
|
@ -290,7 +287,7 @@ frontendControllers = {
|
||||||
// If there are still no matches then return.
|
// If there are still no matches then return.
|
||||||
if (staticPostPermalink.match(path) === false) {
|
if (staticPostPermalink.match(path) === false) {
|
||||||
// Reject promise chain with type 'NotFound'
|
// Reject promise chain with type 'NotFound'
|
||||||
return when.reject(new errors.NotFoundError());
|
return Promise.reject(new errors.NotFoundError());
|
||||||
}
|
}
|
||||||
|
|
||||||
permalink = staticPostPermalink;
|
permalink = staticPostPermalink;
|
||||||
|
@ -324,7 +321,7 @@ frontendControllers = {
|
||||||
return res.redirect(config.paths.subdir + '/ghost/editor/' + post.id + '/');
|
return res.redirect(config.paths.subdir + '/ghost/editor/' + post.id + '/');
|
||||||
} else if (params.edit !== undefined) {
|
} else if (params.edit !== undefined) {
|
||||||
// reject with type: 'NotFound'
|
// reject with type: 'NotFound'
|
||||||
return when.reject(new errors.NotFoundError());
|
return Promise.reject(new errors.NotFoundError());
|
||||||
}
|
}
|
||||||
|
|
||||||
setReqCtx(req, post);
|
setReqCtx(req, post);
|
||||||
|
@ -380,7 +377,7 @@ frontendControllers = {
|
||||||
|
|
||||||
return render();
|
return render();
|
||||||
|
|
||||||
}).otherwise(function (err) {
|
}).catch(function (err) {
|
||||||
// If we've thrown an error message
|
// If we've thrown an error message
|
||||||
// of type: 'NotFound' then we found
|
// of type: 'NotFound' then we found
|
||||||
// no path match.
|
// no path match.
|
||||||
|
@ -422,13 +419,13 @@ frontendControllers = {
|
||||||
return res.redirect(baseUrl);
|
return res.redirect(baseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.settle([
|
return Promise.all([
|
||||||
api.settings.read('title'),
|
api.settings.read('title'),
|
||||||
api.settings.read('description'),
|
api.settings.read('description'),
|
||||||
api.settings.read('permalinks')
|
api.settings.read('permalinks')
|
||||||
]).then(function (result) {
|
]).then(function (result) {
|
||||||
|
|
||||||
var options = {};
|
var options = {};
|
||||||
|
|
||||||
if (pageParam) { options.page = pageParam; }
|
if (pageParam) { options.page = pageParam; }
|
||||||
if (isTag()) { options.tag = slugParam; }
|
if (isTag()) { options.tag = slugParam; }
|
||||||
if (isAuthor()) { options.author = slugParam; }
|
if (isAuthor()) { options.author = slugParam; }
|
||||||
|
@ -436,16 +433,14 @@ frontendControllers = {
|
||||||
options.include = 'author,tags,fields';
|
options.include = 'author,tags,fields';
|
||||||
|
|
||||||
return api.posts.browse(options).then(function (page) {
|
return api.posts.browse(options).then(function (page) {
|
||||||
|
var title = result[0].settings[0].value,
|
||||||
var title = result[0].value.settings[0].value,
|
description = result[1].settings[0].value,
|
||||||
description = result[1].value.settings[0].value,
|
permalinks = result[2].settings[0],
|
||||||
permalinks = result[2].value.settings[0],
|
|
||||||
majorMinor = /^(\d+\.)?(\d+)/,
|
majorMinor = /^(\d+\.)?(\d+)/,
|
||||||
trimmedVersion = res.locals.version,
|
trimmedVersion = res.locals.version,
|
||||||
siteUrl = config.urlFor('home', {secure: req.secure}, true),
|
siteUrl = config.urlFor('home', {secure: req.secure}, true),
|
||||||
feedUrl = config.urlFor('rss', {secure: req.secure}, true),
|
feedUrl = config.urlFor('rss', {secure: req.secure}, true),
|
||||||
maxPage = page.meta.pagination.pages,
|
maxPage = page.meta.pagination.pages,
|
||||||
feedItems = [],
|
|
||||||
feed;
|
feed;
|
||||||
|
|
||||||
trimmedVersion = trimmedVersion ? trimmedVersion.match(majorMinor)[0] : '?';
|
trimmedVersion = trimmedVersion ? trimmedVersion.match(majorMinor)[0] : '?';
|
||||||
|
@ -482,8 +477,7 @@ frontendControllers = {
|
||||||
|
|
||||||
filters.doFilter('prePostsRender', page.posts).then(function (posts) {
|
filters.doFilter('prePostsRender', page.posts).then(function (posts) {
|
||||||
posts.forEach(function (post) {
|
posts.forEach(function (post) {
|
||||||
var deferred = when.defer(),
|
var item = {
|
||||||
item = {
|
|
||||||
title: post.title,
|
title: post.title,
|
||||||
guid: post.uuid,
|
guid: post.uuid,
|
||||||
url: config.urlFor('post', {post: post, permalinks: permalinks}, true),
|
url: config.urlFor('post', {post: post, permalinks: permalinks}, true),
|
||||||
|
@ -499,25 +493,23 @@ frontendControllers = {
|
||||||
p1 = url.resolve(siteUrl, p1);
|
p1 = url.resolve(siteUrl, p1);
|
||||||
return "src='" + p1 + "' ";
|
return "src='" + p1 + "' ";
|
||||||
});
|
});
|
||||||
|
|
||||||
//set a href to absolute url
|
//set a href to absolute url
|
||||||
content = content.replace(/href=["|'|\s]?([\w\/\?\$\.\+\-;%:@&=,_]+)["|'|\s]?/gi, function (match, p1) {
|
content = content.replace(/href=["|'|\s]?([\w\/\?\$\.\+\-;%:@&=,_]+)["|'|\s]?/gi, function (match, p1) {
|
||||||
/*jslint unparam:true*/
|
/*jslint unparam:true*/
|
||||||
p1 = url.resolve(siteUrl, p1);
|
p1 = url.resolve(siteUrl, p1);
|
||||||
return "href='" + p1 + "' ";
|
return "href='" + p1 + "' ";
|
||||||
});
|
});
|
||||||
|
|
||||||
item.description = content;
|
item.description = content;
|
||||||
feed.item(item);
|
feed.item(item);
|
||||||
feedItems.push(deferred.promise);
|
|
||||||
deferred.resolve();
|
|
||||||
});
|
});
|
||||||
});
|
}).then(function () {
|
||||||
|
|
||||||
when.all(feedItems).then(function () {
|
|
||||||
res.set('Content-Type', 'text/xml; charset=UTF-8');
|
res.set('Content-Type', 'text/xml; charset=UTF-8');
|
||||||
res.send(feed.xml());
|
res.send(feed.xml());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).otherwise(handleError(next));
|
}).catch(handleError(next));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
versioning = require('../versioning'),
|
versioning = require('../versioning'),
|
||||||
config = require('../../config'),
|
config = require('../../config'),
|
||||||
utils = require('../utils'),
|
utils = require('../utils'),
|
||||||
|
@ -28,7 +27,7 @@ exportFileName = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
exporter = function () {
|
exporter = function () {
|
||||||
return when.join(versioning.getDatabaseVersion(), utils.getTables()).then(function (results) {
|
return Promise.join(versioning.getDatabaseVersion(), utils.getTables()).then(function (results) {
|
||||||
var version = results[0],
|
var version = results[0],
|
||||||
tables = results[1],
|
tables = results[1],
|
||||||
selectOps = _.map(tables, function (name) {
|
selectOps = _.map(tables, function (name) {
|
||||||
|
@ -37,7 +36,7 @@ exporter = function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(selectOps).then(function (tableData) {
|
return Promise.all(selectOps).then(function (tableData) {
|
||||||
var exportData = {
|
var exportData = {
|
||||||
meta: {
|
meta: {
|
||||||
exported_on: new Date().getTime(),
|
exported_on: new Date().getTime(),
|
||||||
|
@ -52,7 +51,7 @@ exporter = function () {
|
||||||
exportData.data[name] = tableData[i];
|
exportData.data[name] = tableData[i];
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.resolve(exportData);
|
return exportData;
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
errors.logAndThrowError(err, 'Error exporting data', '');
|
errors.logAndThrowError(err, 'Error exporting data', '');
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
// rather than abstracted into a migration system. The upgrade function checks that its changes are safe before
|
// rather than abstracted into a migration system. The upgrade function checks that its changes are safe before
|
||||||
// making them.
|
// making them.
|
||||||
|
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
sequence = require('when/sequence'),
|
sequence = require('../../utils/sequence'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
errors = require('../../errors'),
|
errors = require('../../errors'),
|
||||||
utils = require('../../utils'),
|
utils = require('../../utils'),
|
||||||
|
@ -101,7 +101,7 @@ populate = function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(ops).then(function () {
|
return Promise.all(ops).then(function () {
|
||||||
return sequence(relations);
|
return sequence(relations);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return permissions.populate(options);
|
return permissions.populate(options);
|
||||||
|
@ -150,7 +150,7 @@ to003 = function () {
|
||||||
});
|
});
|
||||||
ops.push(upgradeOp);
|
ops.push(upgradeOp);
|
||||||
|
|
||||||
return when.all(ops).then(function () {
|
return Promise.all(ops).then(function () {
|
||||||
return permissions.to003(options);
|
return permissions.to003(options);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return convertAdminToOwner();
|
return convertAdminToOwner();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// # Permissions Fixtures
|
// # Permissions Fixtures
|
||||||
// Sets up the permissions, and the default permissions_roles relationships
|
// Sets up the permissions, and the default permissions_roles relationships
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
sequence = require('when/sequence'),
|
sequence = require('../../../utils/sequence'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
errors = require('../../../errors'),
|
errors = require('../../../errors'),
|
||||||
models = require('../../../models'),
|
models = require('../../../models'),
|
||||||
|
@ -52,7 +52,7 @@ addAllRolesPermissions = function () {
|
||||||
ops.push(addRolesPermissionsForRole(roleName));
|
ops.push(addRolesPermissionsForRole(roleName));
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(ops);
|
return Promise.all(ops);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ to003 = function (options) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Now we can perfom the normal populate
|
// Now we can perfom the normal populate
|
||||||
return when.all(ops).then(function () {
|
return Promise.all(ops).then(function () {
|
||||||
return populate(options);
|
return populate(options);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
models = require('../../models'),
|
models = require('../../models'),
|
||||||
utils = require('./utils'),
|
utils = require('./utils'),
|
||||||
|
|
||||||
Importer000;
|
Importer000;
|
||||||
|
|
||||||
|
@ -23,17 +23,15 @@ Importer000.prototype.importData = function (data) {
|
||||||
return this.canImport(data)
|
return this.canImport(data)
|
||||||
.then(function (importerFunc) {
|
.then(function (importerFunc) {
|
||||||
return importerFunc(data);
|
return importerFunc(data);
|
||||||
}, function (reason) {
|
|
||||||
return when.reject(reason);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Importer000.prototype.canImport = function (data) {
|
Importer000.prototype.canImport = function (data) {
|
||||||
if (data.meta && data.meta.version && this.importFrom[data.meta.version]) {
|
if (data.meta && data.meta.version && this.importFrom[data.meta.version]) {
|
||||||
return when.resolve(this.importFrom[data.meta.version]);
|
return Promise.resolve(this.importFrom[data.meta.version]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject('Unsupported version of data: ' + data.meta.version);
|
return Promise.reject('Unsupported version of data: ' + data.meta.version);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,10 +47,10 @@ Importer000.prototype.loadUsers = function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!users.owner) {
|
if (!users.owner) {
|
||||||
return when.reject('Unable to find an owner');
|
return Promise.reject('Unable to find an owner');
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.resolve(users);
|
return users;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,12 +70,12 @@ Importer000.prototype.doUserImport = function (t, tableData, users, errors) {
|
||||||
// Import users, deduplicating with already present users
|
// Import users, deduplicating with already present users
|
||||||
userOps = utils.importUsers(tableData.users, users, t);
|
userOps = utils.importUsers(tableData.users, users, t);
|
||||||
|
|
||||||
return when.settle(userOps).then(function (descriptors) {
|
return Promise.settle(userOps).then(function (descriptors) {
|
||||||
descriptors.forEach(function (d) {
|
descriptors.forEach(function (d) {
|
||||||
if (d.state === 'rejected') {
|
if (d.isRejected()) {
|
||||||
errors = errors.concat(d.reason);
|
errors = errors.concat(d.reason());
|
||||||
} else {
|
} else {
|
||||||
imported.push(d.value.toJSON());
|
imported.push(d.value().toJSON());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -85,12 +83,12 @@ Importer000.prototype.doUserImport = function (t, tableData, users, errors) {
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
t.rollback(errors);
|
t.rollback(errors);
|
||||||
} else {
|
} else {
|
||||||
return when.resolve(imported);
|
return imported;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.resolve({});
|
return Promise.resolve({});
|
||||||
};
|
};
|
||||||
|
|
||||||
Importer000.prototype.doImport = function (data) {
|
Importer000.prototype.doImport = function (data) {
|
||||||
|
@ -149,13 +147,12 @@ Importer000.prototype.doImport = function (data) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Write changes to DB, if successful commit, otherwise rollback
|
// Write changes to DB, if successful commit, otherwise rollback
|
||||||
// when.all() does not work as expected, when.settle() does.
|
Promise.settle(ops).then(function (descriptors) {
|
||||||
when.settle(ops).then(function (descriptors) {
|
|
||||||
var errors = [];
|
var errors = [];
|
||||||
|
|
||||||
descriptors.forEach(function (d) {
|
descriptors.forEach(function (d) {
|
||||||
if (d.state === 'rejected') {
|
if (d.isRejected()) {
|
||||||
errors = errors.concat(d.reason);
|
errors = errors.concat(d.reason());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -168,9 +165,7 @@ Importer000.prototype.doImport = function (data) {
|
||||||
});
|
});
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
//TODO: could return statistics of imported items
|
//TODO: could return statistics of imported items
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}, function (error) {
|
|
||||||
return when.reject(error);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
validation = require('../validation'),
|
validation = require('../validation'),
|
||||||
errors = require('../../errors'),
|
errors = require('../../errors'),
|
||||||
|
@ -43,7 +43,7 @@ handleErrors = function handleErrors(errorList) {
|
||||||
var processedErrors = [];
|
var processedErrors = [];
|
||||||
|
|
||||||
if (!_.isArray(errorList)) {
|
if (!_.isArray(errorList)) {
|
||||||
return when.reject(errorList);
|
return Promise.reject(errorList);
|
||||||
}
|
}
|
||||||
|
|
||||||
_.each(errorList, function (error) {
|
_.each(errorList, function (error) {
|
||||||
|
@ -57,7 +57,7 @@ handleErrors = function handleErrors(errorList) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.reject(processedErrors);
|
return Promise.reject(processedErrors);
|
||||||
};
|
};
|
||||||
|
|
||||||
validate = function validate(data) {
|
validate = function validate(data) {
|
||||||
|
@ -69,20 +69,18 @@ validate = function validate(data) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.settle(validateOps).then(function (descriptors) {
|
return Promise.settle(validateOps).then(function (descriptors) {
|
||||||
var errorList = [];
|
var errorList = [];
|
||||||
|
|
||||||
_.each(descriptors, function (d) {
|
_.each(descriptors, function (d) {
|
||||||
if (d.state === 'rejected') {
|
if (d.isRejected()) {
|
||||||
errorList = errorList.concat(d.reason);
|
errorList = errorList.concat(d.reason());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!_.isEmpty(errorList)) {
|
if (!_.isEmpty(errorList)) {
|
||||||
return when.reject(errorList);
|
return Promise.reject(errorList);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.resolve();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,7 +95,7 @@ module.exports = function (version, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!importer) {
|
if (!importer) {
|
||||||
return when.reject('No importer found');
|
return Promise.reject('No importer found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return importer.importData(data);
|
return importer.importData(data);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
models = require('../../models'),
|
models = require('../../models'),
|
||||||
errors = require('../../errors'),
|
errors = require('../../errors'),
|
||||||
|
@ -162,10 +162,11 @@ utils = {
|
||||||
return models.Tag.add(tag, _.extend(internal, {transacting: transaction}))
|
return models.Tag.add(tag, _.extend(internal, {transacting: transaction}))
|
||||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
return when.reject({raw: error, model: 'tag', data: tag});
|
return Promise.reject({raw: error, model: 'tag', data: tag});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return when.resolve(_tag);
|
|
||||||
|
return _tag;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -180,7 +181,7 @@ utils = {
|
||||||
ops.push(models.Post.add(post, _.extend(internal, {transacting: transaction, importing: true}))
|
ops.push(models.Post.add(post, _.extend(internal, {transacting: transaction, importing: true}))
|
||||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
return when.reject({raw: error, model: 'post', data: post});
|
return Promise.reject({raw: error, model: 'post', data: post});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -207,7 +208,7 @@ utils = {
|
||||||
ops.push(models.User.add(user, _.extend(internal, {transacting: transaction}))
|
ops.push(models.User.add(user, _.extend(internal, {transacting: transaction}))
|
||||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
return when.reject({raw: error, model: 'user', data: user});
|
return Promise.reject({raw: error, model: 'user', data: user});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -233,7 +234,7 @@ utils = {
|
||||||
ops.push(models.Settings.edit(tableData, _.extend(internal, {transacting: transaction}))
|
ops.push(models.Settings.edit(tableData, _.extend(internal, {transacting: transaction}))
|
||||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
return when.reject({raw: error, model: 'setting', data: tableData});
|
return Promise.reject({raw: error, model: 'setting', data: tableData});
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -247,13 +248,14 @@ utils = {
|
||||||
return models.App.add(app, _.extend(internal, {transacting: transaction}))
|
return models.App.add(app, _.extend(internal, {transacting: transaction}))
|
||||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
return when.reject({raw: error, model: 'app', data: app});
|
return Promise.reject({raw: error, model: 'app', data: app});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return when.resolve(_app);
|
|
||||||
|
return _app;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = utils;
|
module.exports = utils;
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
sequence = require('../../utils/sequence'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
errors = require('../../errors'),
|
errors = require('../../errors'),
|
||||||
sequence = require('when/sequence'),
|
|
||||||
|
|
||||||
commands = require('./commands'),
|
commands = require('./commands'),
|
||||||
versioning = require('../versioning'),
|
versioning = require('../versioning'),
|
||||||
models = require('../../models'),
|
models = require('../../models'),
|
||||||
|
@ -47,7 +45,7 @@ backupDatabase = function backupDatabase() {
|
||||||
return dataExport.fileName().then(function (fileName) {
|
return dataExport.fileName().then(function (fileName) {
|
||||||
fileName = path.resolve(config.paths.contentPath + '/data/' + fileName);
|
fileName = path.resolve(config.paths.contentPath + '/data/' + fileName);
|
||||||
|
|
||||||
return nodefn.call(fs.writeFile, fileName, JSON.stringify(exportedData)).then(function () {
|
return Promise.promisify(fs.writeFile)(fileName, JSON.stringify(exportedData)).then(function () {
|
||||||
logInfo('Database backup written to: ' + fileName);
|
logInfo('Database backup written to: ' + fileName);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -80,7 +78,7 @@ init = function (tablesOnly) {
|
||||||
if (databaseVersion === defaultVersion) {
|
if (databaseVersion === defaultVersion) {
|
||||||
// 1. The database exists and is up-to-date
|
// 1. The database exists and is up-to-date
|
||||||
logInfo('Up to date at version ' + databaseVersion);
|
logInfo('Up to date at version ' + databaseVersion);
|
||||||
return when.resolve();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (databaseVersion > defaultVersion) {
|
if (databaseVersion > defaultVersion) {
|
||||||
|
@ -155,7 +153,7 @@ migrateUp = function (fromVersion, toVersion) {
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
migrateOps = migrateOps.concat(commands.getDeleteCommands(oldTables, schemaTables));
|
migrateOps = migrateOps.concat(commands.getDeleteCommands(oldTables, schemaTables));
|
||||||
migrateOps = migrateOps.concat(commands.getAddCommands(oldTables, schemaTables));
|
migrateOps = migrateOps.concat(commands.getAddCommands(oldTables, schemaTables));
|
||||||
return when.all(
|
return Promise.all(
|
||||||
_.map(oldTables, function (table) {
|
_.map(oldTables, function (table) {
|
||||||
return utils.getIndexes(table).then(function (indexes) {
|
return utils.getIndexes(table).then(function (indexes) {
|
||||||
modifyUniCommands = modifyUniCommands.concat(commands.modifyUniqueCommands(table, indexes));
|
modifyUniCommands = modifyUniCommands.concat(commands.modifyUniqueCommands(table, indexes));
|
||||||
|
@ -163,7 +161,7 @@ migrateUp = function (fromVersion, toVersion) {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.all(
|
return Promise.all(
|
||||||
_.map(oldTables, function (table) {
|
_.map(oldTables, function (table) {
|
||||||
return utils.getColumns(table).then(function (columns) {
|
return utils.getColumns(table).then(function (columns) {
|
||||||
migrateOps = migrateOps.concat(commands.addColumnCommands(table, columns));
|
migrateOps = migrateOps.concat(commands.addColumnCommands(table, columns));
|
||||||
|
@ -177,9 +175,9 @@ migrateUp = function (fromVersion, toVersion) {
|
||||||
// execute the commands in sequence
|
// execute the commands in sequence
|
||||||
if (!_.isEmpty(migrateOps)) {
|
if (!_.isEmpty(migrateOps)) {
|
||||||
logInfo('Running migrations');
|
logInfo('Running migrations');
|
||||||
|
|
||||||
return sequence(migrateOps);
|
return sequence(migrateOps);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return fixtures.update(fromVersion, toVersion);
|
return fixtures.update(fromVersion, toVersion);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
@ -192,4 +190,4 @@ module.exports = {
|
||||||
reset: reset,
|
reset: reset,
|
||||||
migrateUp: migrateUp,
|
migrateUp: migrateUp,
|
||||||
migrateUpFreshDb: migrateUpFreshDb
|
migrateUpFreshDb: migrateUpFreshDb
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
|
||||||
config = require('../../../config/index'),
|
config = require('../../../config/index'),
|
||||||
|
|
||||||
//private
|
//private
|
||||||
|
@ -43,9 +42,7 @@ checkPostTable = function checkPostTable() {
|
||||||
return config.database.knex.raw('SHOW FIELDS FROM posts where Field ="html" OR Field = "markdown"').then(function (response) {
|
return config.database.knex.raw('SHOW FIELDS FROM posts where Field ="html" OR Field = "markdown"').then(function (response) {
|
||||||
return _.flatten(_.map(response[0], function (entry) {
|
return _.flatten(_.map(response[0], function (entry) {
|
||||||
if (entry.Type.toLowerCase() !== 'mediumtext') {
|
if (entry.Type.toLowerCase() !== 'mediumtext') {
|
||||||
return config.database.knex.raw('ALTER TABLE posts MODIFY ' + entry.Field + ' MEDIUMTEXT').then(function () {
|
return config.database.knex.raw('ALTER TABLE posts MODIFY ' + entry.Field + ' MEDIUMTEXT');
|
||||||
return when.resolve();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@ -56,4 +53,4 @@ module.exports = {
|
||||||
getTables: getTables,
|
getTables: getTables,
|
||||||
getIndexes: getIndexes,
|
getIndexes: getIndexes,
|
||||||
getColumns: getColumns
|
getColumns: getColumns
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
config = require('../../../config/index'),
|
config = require('../../../config/index'),
|
||||||
|
|
||||||
//private
|
//private
|
||||||
doRaw,
|
doRaw,
|
||||||
|
|
||||||
// public
|
// public
|
||||||
getTables,
|
getTables,
|
||||||
getIndexes,
|
getIndexes,
|
||||||
getColumns;
|
getColumns;
|
||||||
|
|
||||||
|
|
||||||
doRaw = function doRaw(query, fn) {
|
doRaw = function doRaw(query, fn) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
config = require('../../config'),
|
config = require('../../config'),
|
||||||
schema = require('../schema').tables,
|
schema = require('../schema').tables,
|
||||||
clients = require('./clients'),
|
clients = require('./clients'),
|
||||||
|
@ -87,7 +87,7 @@ function getTables() {
|
||||||
return clients[client].getTables();
|
return clients[client].getTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject('No support for database client ' + client);
|
return Promise.reject('No support for database client ' + client);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIndexes(table) {
|
function getIndexes(table) {
|
||||||
|
@ -98,7 +98,7 @@ function getIndexes(table) {
|
||||||
return clients[client].getIndexes(table);
|
return clients[client].getIndexes(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject('No support for database client ' + client);
|
return Promise.reject('No support for database client ' + client);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getColumns(table) {
|
function getColumns(table) {
|
||||||
|
@ -109,7 +109,7 @@ function getColumns(table) {
|
||||||
return clients[client].getColumns(table);
|
return clients[client].getColumns(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject('No support for database client ' + client);
|
return Promise.reject('No support for database client ' + client);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkTables() {
|
function checkTables() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
var schema = require('../schema').tables,
|
var schema = require('../schema').tables,
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
validator = require('validator'),
|
validator = require('validator'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
errors = require('../../errors'),
|
errors = require('../../errors'),
|
||||||
config = require('../../config'),
|
config = require('../../config'),
|
||||||
requireTree = require('../../require-tree').readAll,
|
requireTree = require('../../require-tree').readAll,
|
||||||
|
@ -73,10 +73,10 @@ validateSchema = function (tableName, model) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (validationErrors.length !== 0) {
|
if (validationErrors.length !== 0) {
|
||||||
return when.reject(validationErrors);
|
return Promise.reject(validationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Validation for settings
|
// Validation for settings
|
||||||
|
@ -92,10 +92,10 @@ validateSettings = function (defaultSettings, model) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validationErrors.length !== 0) {
|
if (validationErrors.length !== 0) {
|
||||||
return when.reject(validationErrors);
|
return Promise.reject(validationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
};
|
};
|
||||||
|
|
||||||
// A Promise that will resolve to an object with a property for each installed theme.
|
// A Promise that will resolve to an object with a property for each installed theme.
|
||||||
|
@ -107,15 +107,13 @@ validateActiveTheme = function (themeName) {
|
||||||
// If Ghost is running and its availableThemes collection exists
|
// If Ghost is running and its availableThemes collection exists
|
||||||
// give it priority.
|
// give it priority.
|
||||||
if (config.paths.availableThemes && Object.keys(config.paths.availableThemes).length > 0) {
|
if (config.paths.availableThemes && Object.keys(config.paths.availableThemes).length > 0) {
|
||||||
availableThemes = when(config.paths.availableThemes);
|
availableThemes = Promise.resolve(config.paths.availableThemes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return availableThemes.then(function (themes) {
|
return availableThemes.then(function (themes) {
|
||||||
if (!themes.hasOwnProperty(themeName)) {
|
if (!themes.hasOwnProperty(themeName)) {
|
||||||
return when.reject(new errors.ValidationError(themeName + ' cannot be activated because it is not currently installed.', 'activeTheme'));
|
return Promise.reject(new errors.ValidationError(themeName + ' cannot be activated because it is not currently installed.', 'activeTheme'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.resolve();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ var _ = require('lodash'),
|
||||||
colors = require('colors'),
|
colors = require('colors'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
hbs = require('express-hbs'),
|
hbs = require('express-hbs'),
|
||||||
NotFoundError = require('./notfounderror'),
|
NotFoundError = require('./notfounderror'),
|
||||||
BadRequestError = require('./badrequesterror'),
|
BadRequestError = require('./badrequesterror'),
|
||||||
|
@ -47,7 +47,7 @@ errors = {
|
||||||
// ## Reject Error
|
// ## Reject Error
|
||||||
// Used to pass through promise errors when we want to handle them at a later time
|
// Used to pass through promise errors when we want to handle them at a later time
|
||||||
rejectError: function (err) {
|
rejectError: function (err) {
|
||||||
return when.reject(err);
|
return Promise.reject(err);
|
||||||
},
|
},
|
||||||
|
|
||||||
logInfo: function (component, info) {
|
logInfo: function (component, info) {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
|
pipeline = require('./utils/pipeline'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
defaults;
|
defaults;
|
||||||
|
|
||||||
when.pipeline = require('when/pipeline');
|
|
||||||
|
|
||||||
// ## Default values
|
// ## Default values
|
||||||
/**
|
/**
|
||||||
* A hash of default values to use instead of 'magic' numbers/strings.
|
* A hash of default values to use instead of 'magic' numbers/strings.
|
||||||
|
@ -64,7 +62,7 @@ Filters.prototype.doFilter = function (name, args, context) {
|
||||||
|
|
||||||
// Bug out early if no callbacks by that name
|
// Bug out early if no callbacks by that name
|
||||||
if (!callbacks) {
|
if (!callbacks) {
|
||||||
return when.resolve(args);
|
return Promise.resolve(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each priorityLevel
|
// For each priorityLevel
|
||||||
|
@ -75,7 +73,7 @@ Filters.prototype.doFilter = function (name, args, context) {
|
||||||
|
|
||||||
// Bug out if no handlers on this priority
|
// Bug out if no handlers on this priority
|
||||||
if (!_.isArray(callbacks[priority])) {
|
if (!_.isArray(callbacks[priority])) {
|
||||||
return when.resolve(currentArgs);
|
return Promise.resolve(currentArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
callables = _.map(callbacks[priority], function (callback) {
|
callables = _.map(callbacks[priority], function (callback) {
|
||||||
|
@ -84,11 +82,11 @@ Filters.prototype.doFilter = function (name, args, context) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
// Call each handler for this priority level, allowing for promises or values
|
// Call each handler for this priority level, allowing for promises or values
|
||||||
return when.pipeline(callables, currentArgs);
|
return pipeline(callables, currentArgs);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.pipeline(priorityCallbacks, args);
|
return pipeline(priorityCallbacks, args);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = new Filters();
|
module.exports = new Filters();
|
||||||
|
|
|
@ -2,8 +2,7 @@ var downsize = require('downsize'),
|
||||||
hbs = require('express-hbs'),
|
hbs = require('express-hbs'),
|
||||||
moment = require('moment'),
|
moment = require('moment'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
api = require('../api'),
|
api = require('../api'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
|
@ -147,15 +146,15 @@ coreHelpers.url = function (options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.isTag(this)) {
|
if (schema.isTag(this)) {
|
||||||
return when(config.urlFor('tag', {tag: this}, absolute));
|
return Promise.resolve(config.urlFor('tag', {tag: this}, absolute));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.isUser(this)) {
|
if (schema.isUser(this)) {
|
||||||
return when(config.urlFor('author', {author: this}, absolute));
|
return Promise.resolve(config.urlFor('author', {author: this}, absolute));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return when(config.urlFor(this, absolute));
|
return Promise.resolve(config.urlFor(this, absolute));
|
||||||
};
|
};
|
||||||
|
|
||||||
// ### Asset helper
|
// ### Asset helper
|
||||||
|
@ -786,9 +785,9 @@ function registerAsyncHelper(hbs, name, fn) {
|
||||||
hbs.registerAsyncHelper(name, function (options, cb) {
|
hbs.registerAsyncHelper(name, function (options, cb) {
|
||||||
// Wrap the function passed in with a when.resolve so it can
|
// Wrap the function passed in with a when.resolve so it can
|
||||||
// return either a promise or a value
|
// return either a promise or a value
|
||||||
when.resolve(fn.call(this, options)).then(function (result) {
|
Promise.resolve(fn.call(this, options)).then(function (result) {
|
||||||
cb(result);
|
cb(result);
|
||||||
}).otherwise(function (err) {
|
}).catch(function (err) {
|
||||||
errors.logAndThrowError(err, 'registerAsyncThemeHelper: ' + name);
|
errors.logAndThrowError(err, 'registerAsyncThemeHelper: ' + name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@ var crypto = require('crypto'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
uuid = require('node-uuid'),
|
uuid = require('node-uuid'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
api = require('./api'),
|
api = require('./api'),
|
||||||
config = require('./config'),
|
config = require('./config'),
|
||||||
|
@ -24,13 +24,6 @@ var crypto = require('crypto'),
|
||||||
// Variables
|
// Variables
|
||||||
dbHash;
|
dbHash;
|
||||||
|
|
||||||
// If we're in development mode, require "when/console/monitor"
|
|
||||||
// for help in seeing swallowed promise errors, and log any
|
|
||||||
// stderr messages from bluebird promises.
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
require('when/monitor/console');
|
|
||||||
}
|
|
||||||
|
|
||||||
function doFirstRun() {
|
function doFirstRun() {
|
||||||
var firstRunMessage = [
|
var firstRunMessage = [
|
||||||
'Welcome to Ghost.',
|
'Welcome to Ghost.',
|
||||||
|
@ -80,30 +73,29 @@ function builtFilesExist() {
|
||||||
helpers.scriptFiles.production : helpers.scriptFiles.development;
|
helpers.scriptFiles.production : helpers.scriptFiles.development;
|
||||||
|
|
||||||
function checkExist(fileName) {
|
function checkExist(fileName) {
|
||||||
var deferred = when.defer(),
|
var errorMessage = "Javascript files have not been built.",
|
||||||
errorMessage = "Javascript files have not been built.",
|
|
||||||
errorHelp = "\nPlease read the getting started instructions at:" +
|
errorHelp = "\nPlease read the getting started instructions at:" +
|
||||||
"\nhttps://github.com/TryGhost/Ghost#getting-started-guide-for-developers";
|
"\nhttps://github.com/TryGhost/Ghost#getting-started-guide-for-developers";
|
||||||
|
|
||||||
fs.exists(fileName, function (exists) {
|
return new Promise(function (resolve, reject) {
|
||||||
if (exists) {
|
fs.exists(fileName, function (exists) {
|
||||||
deferred.resolve(true);
|
if (exists) {
|
||||||
} else {
|
resolve(true);
|
||||||
var err = new Error(errorMessage);
|
} else {
|
||||||
|
var err = new Error(errorMessage);
|
||||||
|
|
||||||
err.help = errorHelp;
|
err.help = errorHelp;
|
||||||
deferred.reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fileNames.forEach(function (fileName) {
|
fileNames.forEach(function (fileName) {
|
||||||
deferreds.push(checkExist(location + fileName));
|
deferreds.push(checkExist(location + fileName));
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(deferreds);
|
return Promise.all(deferreds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is run after every initialization is done, right before starting server.
|
// This is run after every initialization is done, right before starting server.
|
||||||
|
@ -174,7 +166,7 @@ function init(server) {
|
||||||
// into this method due to circular dependencies.
|
// into this method due to circular dependencies.
|
||||||
return config.theme.update(api.settings, config.url);
|
return config.theme.update(api.settings, config.url);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.join(
|
return Promise.join(
|
||||||
// Check for or initialise a dbHash.
|
// Check for or initialise a dbHash.
|
||||||
initDbHashAndFirstRun(),
|
initDbHashAndFirstRun(),
|
||||||
// Initialize mail
|
// Initialize mail
|
||||||
|
@ -219,7 +211,6 @@ function init(server) {
|
||||||
errors.logWarn(warn.message, warn.context, warn.help);
|
errors.logWarn(warn.message, warn.context, warn.help);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return new GhostServer(server);
|
return new GhostServer(server);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
var cp = require('child_process'),
|
var cp = require('child_process'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
nodemailer = require('nodemailer'),
|
nodemailer = require('nodemailer'),
|
||||||
config = require('./config');
|
config = require('./config');
|
||||||
|
|
||||||
|
@ -17,7 +16,7 @@ GhostMailer.prototype.init = function () {
|
||||||
self.state = {};
|
self.state = {};
|
||||||
if (config.mail && config.mail.transport) {
|
if (config.mail && config.mail.transport) {
|
||||||
this.createTransport();
|
this.createTransport();
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to detect and fallback to `sendmail`
|
// Attempt to detect and fallback to `sendmail`
|
||||||
|
@ -26,11 +25,9 @@ GhostMailer.prototype.init = function () {
|
||||||
path: binpath
|
path: binpath
|
||||||
});
|
});
|
||||||
self.state.usingSendmail = true;
|
self.state.usingSendmail = true;
|
||||||
}, function () {
|
}).catch(function () {
|
||||||
self.state.emailDisabled = true;
|
self.state.emailDisabled = true;
|
||||||
self.transport = null;
|
self.transport = null;
|
||||||
}).ensure(function () {
|
|
||||||
return when.resolve();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,13 +37,15 @@ GhostMailer.prototype.isWindows = function () {
|
||||||
|
|
||||||
GhostMailer.prototype.detectSendmail = function () {
|
GhostMailer.prototype.detectSendmail = function () {
|
||||||
if (this.isWindows()) {
|
if (this.isWindows()) {
|
||||||
return when.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
return when.promise(function (resolve, reject) {
|
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
cp.exec('which sendmail', function (err, stdout) {
|
cp.exec('which sendmail', function (err, stdout) {
|
||||||
if (err && !/bin\/sendmail/.test(stdout)) {
|
if (err && !/bin\/sendmail/.test(stdout)) {
|
||||||
return reject();
|
return reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
resolve(stdout.toString().replace(/(\n|\r|\r\n)$/, ''));
|
resolve(stdout.toString().replace(/(\n|\r|\r\n)$/, ''));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -63,7 +62,7 @@ GhostMailer.prototype.fromAddress = function () {
|
||||||
|
|
||||||
if (!from) {
|
if (!from) {
|
||||||
// Extract the domain name from url set in config.js
|
// Extract the domain name from url set in config.js
|
||||||
domain = config.url.match(new RegExp("^https?://([^/:?#]+)(?:[/:?#]|$)", "i"));
|
domain = config.url.match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
|
||||||
domain = domain && domain[1];
|
domain = domain && domain[1];
|
||||||
|
|
||||||
// Default to ghost@[blog.url]
|
// Default to ghost@[blog.url]
|
||||||
|
@ -84,12 +83,12 @@ GhostMailer.prototype.send = function (message) {
|
||||||
to = message.to || false;
|
to = message.to || false;
|
||||||
|
|
||||||
if (!this.transport) {
|
if (!this.transport) {
|
||||||
return when.reject(new Error('Email Error: No e-mail transport configured.'));
|
return Promise.reject(new Error('Email Error: No e-mail transport configured.'));
|
||||||
}
|
}
|
||||||
if (!(message && message.subject && message.html && message.to)) {
|
if (!(message && message.subject && message.html && message.to)) {
|
||||||
return when.reject(new Error('Email Error: Incomplete message data.'));
|
return Promise.reject(new Error('Email Error: Incomplete message data.'));
|
||||||
}
|
}
|
||||||
sendMail = nodefn.lift(self.transport.sendMail.bind(self.transport));
|
sendMail = Promise.promisify(self.transport.sendMail.bind(self.transport));
|
||||||
|
|
||||||
message = _.extend(message, {
|
message = _.extend(message, {
|
||||||
from: self.fromAddress(),
|
from: self.fromAddress(),
|
||||||
|
|
|
@ -130,7 +130,7 @@ function updateActiveTheme(req, res, next) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
}).otherwise(function (err) {
|
}).catch(function (err) {
|
||||||
// Trying to start up without the active theme present, setup a simple hbs instance
|
// Trying to start up without the active theme present, setup a simple hbs instance
|
||||||
// and render an error page straight away.
|
// and render an error page straight away.
|
||||||
expressServer.engine('hbs', hbs.express3());
|
expressServer.engine('hbs', hbs.express3());
|
||||||
|
@ -147,7 +147,7 @@ function redirectToSetup(req, res, next) {
|
||||||
return res.redirect(config.paths.subdir + '/ghost/setup/');
|
return res.redirect(config.paths.subdir + '/ghost/setup/');
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
}).otherwise(function (err) {
|
}).catch(function (err) {
|
||||||
return next(new Error(err));
|
return next(new Error(err));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// accesses the models directly. All other parts of Ghost, including the blog frontend, admin UI, and apps are only
|
// accesses the models directly. All other parts of Ghost, including the blog frontend, admin UI, and apps are only
|
||||||
// allowed to access data via the API.
|
// allowed to access data via the API.
|
||||||
var bookshelf = require('bookshelf'),
|
var bookshelf = require('bookshelf'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
moment = require('moment'),
|
moment = require('moment'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
uuid = require('node-uuid'),
|
uuid = require('node-uuid'),
|
||||||
|
@ -55,7 +55,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||||
|
|
||||||
this.on('creating', this.creating, this);
|
this.on('creating', this.creating, this);
|
||||||
this.on('saving', function (model, attributes, options) {
|
this.on('saving', function (model, attributes, options) {
|
||||||
return when(self.saving(model, attributes, options)).then(function () {
|
return Promise.resolve(self.saving(model, attributes, options)).then(function () {
|
||||||
return self.validate(model, attributes, options);
|
return self.validate(model, attributes, options);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -327,7 +327,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
|
||||||
var trimSpace;
|
var trimSpace;
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
return when.resolve(slugToFind);
|
return slugToFind;
|
||||||
}
|
}
|
||||||
|
|
||||||
slugTryCount += 1;
|
slugTryCount += 1;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
requireTree = require('../require-tree'),
|
requireTree = require('../require-tree'),
|
||||||
models;
|
models;
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ models = {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return self.Post.findAll().then(function (posts) {
|
return self.Post.findAll().then(function (posts) {
|
||||||
return when.all(_.map(posts.toJSON(), function (post) {
|
return Promise.all(_.map(posts.toJSON(), function (post) {
|
||||||
return self.Post.destroy({id: post.id});
|
return self.Post.destroy({id: post.id});
|
||||||
}));
|
}));
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return self.Tag.findAll().then(function (tags) {
|
return self.Tag.findAll().then(function (tags) {
|
||||||
return when.all(_.map(tags.toJSON(), function (tag) {
|
return Promise.all(_.map(tags.toJSON(), function (tag) {
|
||||||
return self.Tag.destroy({id: tag.id});
|
return self.Tag.destroy({id: tag.id});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// # Post Model
|
// # Post Model
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
uuid = require('node-uuid'),
|
uuid = require('node-uuid'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
Showdown = require('showdown'),
|
Showdown = require('showdown'),
|
||||||
ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'),
|
ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'),
|
||||||
|
@ -123,7 +123,7 @@ Post = ghostBookshelf.Model.extend({
|
||||||
tagOps.push(post.tags().detach(null, _.omit(options, 'query')));
|
tagOps.push(post.tags().detach(null, _.omit(options, 'query')));
|
||||||
|
|
||||||
if (_.isEmpty(self.myTags)) {
|
if (_.isEmpty(self.myTags)) {
|
||||||
return when.all(tagOps);
|
return Promise.all(tagOps);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ghostBookshelf.collection('Tags').forge().query('whereIn', 'name', _.pluck(self.myTags, 'name')).fetch(options).then(function (existingTags) {
|
return ghostBookshelf.collection('Tags').forge().query('whereIn', 'name', _.pluck(self.myTags, 'name')).fetch(options).then(function (existingTags) {
|
||||||
|
@ -157,7 +157,7 @@ Post = ghostBookshelf.Model.extend({
|
||||||
tagOps.push(post.tags().attach(tag.id, _.omit(options, 'query')));
|
tagOps.push(post.tags().attach(tag.id, _.omit(options, 'query')));
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(tagOps);
|
return Promise.all(tagOps);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -341,7 +341,7 @@ Post = ghostBookshelf.Model.extend({
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.join(fetchTagQuery(), fetchAuthorQuery())
|
return Promise.join(fetchTagQuery(), fetchAuthorQuery())
|
||||||
|
|
||||||
// Set the limit & offset for the query, fetching
|
// Set the limit & offset for the query, fetching
|
||||||
// with the opts (to specify any eager relations, etc.)
|
// with the opts (to specify any eager relations, etc.)
|
||||||
|
@ -536,16 +536,16 @@ Post = ghostBookshelf.Model.extend({
|
||||||
options = this.filterOptions(options, 'destroyByAuthor');
|
options = this.filterOptions(options, 'destroyByAuthor');
|
||||||
if (authorId) {
|
if (authorId) {
|
||||||
return postCollection.query('where', 'author_id', '=', authorId).fetch(options).then(function (results) {
|
return postCollection.query('where', 'author_id', '=', authorId).fetch(options).then(function (results) {
|
||||||
return when.map(results.models, function (post) {
|
return Promise.map(results.models, function (post) {
|
||||||
return post.related('tags').detach(null, options).then(function () {
|
return post.related('tags').detach(null, options).then(function () {
|
||||||
return post.destroy(options);
|
return post.destroy(options);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
return when.reject(new errors.InternalServerError(error.message || error));
|
return Promise.reject(new errors.InternalServerError(error.message || error));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return when.reject(new errors.NotFoundError('No user found'));
|
return Promise.reject(new errors.NotFoundError('No user found'));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -574,10 +574,10 @@ Post = ghostBookshelf.Model.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasUserPermission && hasAppPermission) {
|
if (hasUserPermission && hasAppPermission) {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
ghostBookshelf = require('./base'),
|
ghostBookshelf = require('./base'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
Role,
|
Role,
|
||||||
Roles;
|
Roles;
|
||||||
|
@ -73,9 +73,10 @@ Role = ghostBookshelf.Model.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasUserPermission && hasAppPermission) {
|
if (hasUserPermission && hasAppPermission) {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return when.reject();
|
|
||||||
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ var Settings,
|
||||||
uuid = require('node-uuid'),
|
uuid = require('node-uuid'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
validation = require('../data/validation'),
|
validation = require('../data/validation'),
|
||||||
internal = {context: {internal: true}},
|
internal = {context: {internal: true}},
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||||
var themeName = setting.value || '';
|
var themeName = setting.value || '';
|
||||||
|
|
||||||
if (setting.key !== 'activeTheme') {
|
if (setting.key !== 'activeTheme') {
|
||||||
return when.resolve();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return validation.validateActiveTheme(themeName);
|
return validation.validateActiveTheme(themeName);
|
||||||
|
@ -87,7 +87,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||||
if (!_.isObject(options)) {
|
if (!_.isObject(options)) {
|
||||||
options = { key: options };
|
options = { key: options };
|
||||||
}
|
}
|
||||||
return when(ghostBookshelf.Model.findOne.call(this, options));
|
return Promise.resolve(ghostBookshelf.Model.findOne.call(this, options));
|
||||||
},
|
},
|
||||||
|
|
||||||
edit: function (data, options) {
|
edit: function (data, options) {
|
||||||
|
@ -98,11 +98,11 @@ Settings = ghostBookshelf.Model.extend({
|
||||||
data = [data];
|
data = [data];
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.map(data, function (item) {
|
return Promise.map(data, function (item) {
|
||||||
// Accept an array of models as input
|
// Accept an array of models as input
|
||||||
if (item.toJSON) { item = item.toJSON(); }
|
if (item.toJSON) { item = item.toJSON(); }
|
||||||
if (!(_.isString(item.key) && item.key.length > 0)) {
|
if (!(_.isString(item.key) && item.key.length > 0)) {
|
||||||
return when.reject(new errors.ValidationError('Value in [settings.key] cannot be blank.'));
|
return Promise.reject(new errors.ValidationError('Value in [settings.key] cannot be blank.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
item = self.filterData(item);
|
item = self.filterData(item);
|
||||||
|
@ -113,7 +113,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||||
return setting.save({value: item.value}, options);
|
return setting.save({value: item.value}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject(new errors.NotFoundError('Unable to find setting to update: ' + item.key));
|
return Promise.reject(new errors.NotFoundError('Unable to find setting to update: ' + item.key));
|
||||||
|
|
||||||
}, errors.logAndThrowError);
|
}, errors.logAndThrowError);
|
||||||
});
|
});
|
||||||
|
@ -121,7 +121,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||||
|
|
||||||
populateDefault: function (key) {
|
populateDefault: function (key) {
|
||||||
if (!getDefaultSettings()[key]) {
|
if (!getDefaultSettings()[key]) {
|
||||||
return when.reject(new errors.NotFoundError('Unable to find default setting: ' + key));
|
return Promise.reject(new errors.NotFoundError('Unable to find default setting: ' + key));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.findOne({ key: key }).then(function (foundSetting) {
|
return this.findOne({ key: key }).then(function (foundSetting) {
|
||||||
|
@ -153,7 +153,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return when.all(insertOperations);
|
return Promise.all(insertOperations);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
bcrypt = require('bcryptjs'),
|
bcrypt = require('bcryptjs'),
|
||||||
ghostBookshelf = require('./base'),
|
ghostBookshelf = require('./base'),
|
||||||
http = require('http'),
|
http = require('http'),
|
||||||
|
@ -9,6 +8,10 @@ var _ = require('lodash'),
|
||||||
validator = require('validator'),
|
validator = require('validator'),
|
||||||
validation = require('../data/validation'),
|
validation = require('../data/validation'),
|
||||||
|
|
||||||
|
bcryptGenSalt = Promise.promisify(bcrypt.genSalt),
|
||||||
|
bcryptHash = Promise.promisify(bcrypt.hash),
|
||||||
|
bcryptCompare = Promise.promisify(bcrypt.compare),
|
||||||
|
|
||||||
tokenSecurity = {},
|
tokenSecurity = {},
|
||||||
activeStates = ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked'],
|
activeStates = ['active', 'warn-1', 'warn-2', 'warn-3', 'warn-4', 'locked'],
|
||||||
invitedStates = ['invited', 'invited-pending'],
|
invitedStates = ['invited', 'invited-pending'],
|
||||||
|
@ -21,16 +24,16 @@ function validatePasswordLength(password) {
|
||||||
throw new Error('Your password must be at least 8 characters long.');
|
throw new Error('Your password must be at least 8 characters long.');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return when.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePasswordHash(password) {
|
function generatePasswordHash(password) {
|
||||||
// Generate a new salt
|
// Generate a new salt
|
||||||
return nodefn.call(bcrypt.genSalt).then(function (salt) {
|
return bcryptGenSalt().then(function (salt) {
|
||||||
// Hash the provided password with bcrypt
|
// Hash the provided password with bcrypt
|
||||||
return nodefn.call(bcrypt.hash, password, salt);
|
return bcryptHash(password, salt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +242,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return when(fetchRoleQuery())
|
return Promise.resolve(fetchRoleQuery())
|
||||||
.then(function () {
|
.then(function () {
|
||||||
|
|
||||||
if (roleInstance) {
|
if (roleInstance) {
|
||||||
|
@ -394,7 +397,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
roleId = parseInt(data.roles[0].id || data.roles[0], 10);
|
roleId = parseInt(data.roles[0].id || data.roles[0], 10);
|
||||||
|
|
||||||
if (data.roles.length > 1) {
|
if (data.roles.length > 1) {
|
||||||
return when.reject(
|
return Promise.reject(
|
||||||
new errors.ValidationError('Only one role per user is supported at the moment.')
|
new errors.ValidationError('Only one role per user is supported at the moment.')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -407,7 +410,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
return ghostBookshelf.model('Role').findOne({id: roleId});
|
return ghostBookshelf.model('Role').findOne({id: roleId});
|
||||||
}).then(function (roleToAssign) {
|
}).then(function (roleToAssign) {
|
||||||
if (roleToAssign && roleToAssign.get('name') === 'Owner') {
|
if (roleToAssign && roleToAssign.get('name') === 'Owner') {
|
||||||
return when.reject(
|
return Promise.reject(
|
||||||
new errors.ValidationError('This method does not support assigning the owner role')
|
new errors.ValidationError('This method does not support assigning the owner role')
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -447,7 +450,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
|
|
||||||
// check for too many roles
|
// check for too many roles
|
||||||
if (roles.length > 1) {
|
if (roles.length > 1) {
|
||||||
return when.reject(new errors.ValidationError('Only one role per user is supported at the moment.'));
|
return Promise.reject(new errors.ValidationError('Only one role per user is supported at the moment.'));
|
||||||
}
|
}
|
||||||
// remove roles from the object
|
// remove roles from the object
|
||||||
delete data.roles;
|
delete data.roles;
|
||||||
|
@ -552,7 +555,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
if (action === 'destroy') {
|
if (action === 'destroy') {
|
||||||
// Owner cannot be deleted EVER
|
// Owner cannot be deleted EVER
|
||||||
if (userModel.hasRole('Owner')) {
|
if (userModel.hasRole('Owner')) {
|
||||||
return when.reject();
|
return Promise.reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Users with the role 'Editor' have complex permissions when the action === 'destroy'
|
// Users with the role 'Editor' have complex permissions when the action === 'destroy'
|
||||||
|
@ -566,10 +569,10 @@ User = ghostBookshelf.Model.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasUserPermission && hasAppPermission) {
|
if (hasUserPermission && hasAppPermission) {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject();
|
return Promise.reject();
|
||||||
},
|
},
|
||||||
|
|
||||||
setWarning: function (user, options) {
|
setWarning: function (user, options) {
|
||||||
|
@ -588,7 +591,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
user.set('status', 'warn-' + level);
|
user.set('status', 'warn-' + level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return when(user.save(options)).then(function () {
|
return Promise.resolve(user.save(options)).then(function () {
|
||||||
return 5 - level;
|
return 5 - level;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -599,19 +602,19 @@ User = ghostBookshelf.Model.extend({
|
||||||
s;
|
s;
|
||||||
return this.getByEmail(object.email).then(function (user) {
|
return this.getByEmail(object.email).then(function (user) {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return when.reject(new errors.NotFoundError('There is no user with that email address.'));
|
return Promise.reject(new errors.NotFoundError('There is no user with that email address.'));
|
||||||
}
|
}
|
||||||
if (user.get('status') === 'invited' || user.get('status') === 'invited-pending' ||
|
if (user.get('status') === 'invited' || user.get('status') === 'invited-pending' ||
|
||||||
user.get('status') === 'inactive'
|
user.get('status') === 'inactive'
|
||||||
) {
|
) {
|
||||||
return when.reject(new Error('The user with that email address is inactive.'));
|
return Promise.reject(new Error('The user with that email address is inactive.'));
|
||||||
}
|
}
|
||||||
if (user.get('status') !== 'locked') {
|
if (user.get('status') !== 'locked') {
|
||||||
return nodefn.call(bcrypt.compare, object.password, user.get('password')).then(function (matched) {
|
return bcryptCompare(object.password, user.get('password')).then(function (matched) {
|
||||||
if (!matched) {
|
if (!matched) {
|
||||||
return when(self.setWarning(user, {validate: false})).then(function (remaining) {
|
return Promise.resolve(self.setWarning(user, {validate: false})).then(function (remaining) {
|
||||||
s = (remaining > 1) ? 's' : '';
|
s = (remaining > 1) ? 's' : '';
|
||||||
return when.reject(new errors.UnauthorizedError('Your password is incorrect.<br>' +
|
return Promise.reject(new errors.UnauthorizedError('Your password is incorrect.<br>' +
|
||||||
remaining + ' attempt' + s + ' remaining!'));
|
remaining + ' attempt' + s + ' remaining!'));
|
||||||
|
|
||||||
// Use comma structure, not .catch, because we don't want to catch incorrect passwords
|
// Use comma structure, not .catch, because we don't want to catch incorrect passwords
|
||||||
|
@ -624,11 +627,11 @@ User = ghostBookshelf.Model.extend({
|
||||||
'Error thrown from user update during login',
|
'Error thrown from user update during login',
|
||||||
'Visit and save your profile after logging in to check for problems.'
|
'Visit and save your profile after logging in to check for problems.'
|
||||||
);
|
);
|
||||||
return when.reject(new errors.UnauthorizedError('Your password is incorrect.'));
|
return Promise.reject(new errors.UnauthorizedError('Your password is incorrect.'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return when(user.set({status : 'active', last_login : new Date()}).save({validate: false}))
|
return Promise.resolve(user.set({status : 'active', last_login : new Date()}).save({validate: false}))
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
// If we get a validation or other error during this save, catch it and log it, but don't
|
// If we get a validation or other error during this save, catch it and log it, but don't
|
||||||
// cause a login error because of it. The user validation is not important here.
|
// cause a login error because of it. The user validation is not important here.
|
||||||
|
@ -641,16 +644,16 @@ User = ghostBookshelf.Model.extend({
|
||||||
});
|
});
|
||||||
}, errors.logAndThrowError);
|
}, errors.logAndThrowError);
|
||||||
}
|
}
|
||||||
return when.reject(new errors.NoPermissionError('Your account is locked due to too many ' +
|
return Promise.reject(new errors.NoPermissionError('Your account is locked due to too many ' +
|
||||||
'login attempts. Please reset your password to log in again by clicking ' +
|
'login attempts. Please reset your password to log in again by clicking ' +
|
||||||
'the "Forgotten password?" link!'));
|
'the "Forgotten password?" link!'));
|
||||||
|
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
if (error.message === 'NotFound' || error.message === 'EmptyResponse') {
|
if (error.message === 'NotFound' || error.message === 'EmptyResponse') {
|
||||||
return when.reject(new errors.NotFoundError('There is no user with that email address.'));
|
return Promise.reject(new errors.NotFoundError('There is no user with that email address.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.reject(error);
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -664,21 +667,21 @@ User = ghostBookshelf.Model.extend({
|
||||||
user = null;
|
user = null;
|
||||||
|
|
||||||
if (newPassword !== ne2Password) {
|
if (newPassword !== ne2Password) {
|
||||||
return when.reject(new Error('Your new passwords do not match'));
|
return Promise.reject(new Error('Your new passwords do not match'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return validatePasswordLength(newPassword).then(function () {
|
return validatePasswordLength(newPassword).then(function () {
|
||||||
return self.forge({id: userid}).fetch({require: true});
|
return self.forge({id: userid}).fetch({require: true});
|
||||||
}).then(function (_user) {
|
}).then(function (_user) {
|
||||||
user = _user;
|
user = _user;
|
||||||
return nodefn.call(bcrypt.compare, oldPassword, user.get('password'));
|
return bcryptCompare(oldPassword, user.get('password'));
|
||||||
}).then(function (matched) {
|
}).then(function (matched) {
|
||||||
if (!matched) {
|
if (!matched) {
|
||||||
return when.reject(new Error('Your password is incorrect'));
|
return Promise.reject(new Error('Your password is incorrect'));
|
||||||
}
|
}
|
||||||
return nodefn.call(bcrypt.genSalt);
|
return bcryptGenSalt();
|
||||||
}).then(function (salt) {
|
}).then(function (salt) {
|
||||||
return nodefn.call(bcrypt.hash, newPassword, salt);
|
return bcryptHash(newPassword, salt);
|
||||||
}).then(function (hash) {
|
}).then(function (hash) {
|
||||||
user.save({password: hash});
|
user.save({password: hash});
|
||||||
return user;
|
return user;
|
||||||
|
@ -688,7 +691,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
generateResetToken: function (email, expires, dbHash) {
|
generateResetToken: function (email, expires, dbHash) {
|
||||||
return this.getByEmail(email).then(function (foundUser) {
|
return this.getByEmail(email).then(function (foundUser) {
|
||||||
if (!foundUser) {
|
if (!foundUser) {
|
||||||
return when.reject(new errors.NotFoundError('There is no user with that email address.'));
|
return Promise.reject(new errors.NotFoundError('There is no user with that email address.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var hash = crypto.createHash('sha256'),
|
var hash = crypto.createHash('sha256'),
|
||||||
|
@ -720,25 +723,25 @@ User = ghostBookshelf.Model.extend({
|
||||||
|
|
||||||
// Check if invalid structure
|
// Check if invalid structure
|
||||||
if (!parts || parts.length !== 3) {
|
if (!parts || parts.length !== 3) {
|
||||||
return when.reject(new Error('Invalid token structure'));
|
return Promise.reject(new Error('Invalid token structure'));
|
||||||
}
|
}
|
||||||
|
|
||||||
expires = parseInt(parts[0], 10);
|
expires = parseInt(parts[0], 10);
|
||||||
email = parts[1];
|
email = parts[1];
|
||||||
|
|
||||||
if (isNaN(expires)) {
|
if (isNaN(expires)) {
|
||||||
return when.reject(new Error('Invalid token expiration'));
|
return Promise.reject(new Error('Invalid token expiration'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if token is expired to prevent replay attacks
|
// Check if token is expired to prevent replay attacks
|
||||||
if (expires < Date.now()) {
|
if (expires < Date.now()) {
|
||||||
return when.reject(new Error('Expired token'));
|
return Promise.reject(new Error('Expired token'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// to prevent brute force attempts to reset the password the combination of email+expires is only allowed for
|
// to prevent brute force attempts to reset the password the combination of email+expires is only allowed for
|
||||||
// 10 attempts
|
// 10 attempts
|
||||||
if (tokenSecurity[email + '+' + expires] && tokenSecurity[email + '+' + expires].count >= 10) {
|
if (tokenSecurity[email + '+' + expires] && tokenSecurity[email + '+' + expires].count >= 10) {
|
||||||
return when.reject(new Error('Token locked'));
|
return Promise.reject(new Error('Token locked'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.generateResetToken(email, expires, dbHash).then(function (generatedToken) {
|
return this.generateResetToken(email, expires, dbHash).then(function (generatedToken) {
|
||||||
|
@ -756,14 +759,14 @@ User = ghostBookshelf.Model.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diff === 0) {
|
if (diff === 0) {
|
||||||
return when.resolve(email);
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increase the count for email+expires for each failed attempt
|
// increase the count for email+expires for each failed attempt
|
||||||
tokenSecurity[email + '+' + expires] = {
|
tokenSecurity[email + '+' + expires] = {
|
||||||
count: tokenSecurity[email + '+' + expires] ? tokenSecurity[email + '+' + expires].count + 1 : 1
|
count: tokenSecurity[email + '+' + expires] ? tokenSecurity[email + '+' + expires].count + 1 : 1
|
||||||
};
|
};
|
||||||
return when.reject(new Error('Invalid token'));
|
return Promise.reject(new Error('Invalid token'));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -771,7 +774,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (newPassword !== ne2Password) {
|
if (newPassword !== ne2Password) {
|
||||||
return when.reject(new Error('Your new passwords do not match'));
|
return Promise.reject(new Error('Your new passwords do not match'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return validatePasswordLength(newPassword).then(function () {
|
return validatePasswordLength(newPassword).then(function () {
|
||||||
|
@ -779,7 +782,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
return self.validateToken(token, dbHash);
|
return self.validateToken(token, dbHash);
|
||||||
}).then(function (email) {
|
}).then(function (email) {
|
||||||
// Fetch the user by email, and hash the password at the same time.
|
// Fetch the user by email, and hash the password at the same time.
|
||||||
return when.join(
|
return Promise.join(
|
||||||
self.forge({email: email.toLocaleLowerCase()}).fetch({require: true}),
|
self.forge({email: email.toLocaleLowerCase()}).fetch({require: true}),
|
||||||
generatePasswordHash(newPassword)
|
generatePasswordHash(newPassword)
|
||||||
);
|
);
|
||||||
|
@ -809,7 +812,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
// check if user has the owner role
|
// check if user has the owner role
|
||||||
var currentRoles = ctxUser.toJSON().roles;
|
var currentRoles = ctxUser.toJSON().roles;
|
||||||
if (!_.contains(currentRoles, ownerRole.id)) {
|
if (!_.contains(currentRoles, ownerRole.id)) {
|
||||||
return when.reject(new errors.NoPermissionError('Only owners are able to transfer the owner role.'));
|
return Promise.reject(new errors.NoPermissionError('Only owners are able to transfer the owner role.'));
|
||||||
}
|
}
|
||||||
contextUser = ctxUser;
|
contextUser = ctxUser;
|
||||||
return User.findOne({id: object.id});
|
return User.findOne({id: object.id});
|
||||||
|
@ -817,7 +820,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
|
|
||||||
var currentRoles = user.toJSON().roles;
|
var currentRoles = user.toJSON().roles;
|
||||||
if (!_.contains(currentRoles, adminRole.id)) {
|
if (!_.contains(currentRoles, adminRole.id)) {
|
||||||
return when.reject(new errors.ValidationError('Only administrators can be assigned the owner role.'));
|
return Promise.reject(new errors.ValidationError('Only administrators can be assigned the owner role.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
assignUser = user;
|
assignUser = user;
|
||||||
|
@ -838,20 +841,20 @@ User = ghostBookshelf.Model.extend({
|
||||||
gravatarLookup: function (userData) {
|
gravatarLookup: function (userData) {
|
||||||
var gravatarUrl = '//www.gravatar.com/avatar/' +
|
var gravatarUrl = '//www.gravatar.com/avatar/' +
|
||||||
crypto.createHash('md5').update(userData.email.toLowerCase().trim()).digest('hex') +
|
crypto.createHash('md5').update(userData.email.toLowerCase().trim()).digest('hex') +
|
||||||
'?d=404&s=250',
|
'?d=404&s=250';
|
||||||
checkPromise = when.defer();
|
|
||||||
|
|
||||||
http.get('http:' + gravatarUrl, function (res) {
|
return new Promise(function (resolve) {
|
||||||
if (res.statusCode !== 404) {
|
http.get('http:' + gravatarUrl, function (res) {
|
||||||
userData.image = gravatarUrl;
|
if (res.statusCode !== 404) {
|
||||||
}
|
userData.image = gravatarUrl;
|
||||||
checkPromise.resolve(userData);
|
}
|
||||||
}).on('error', function () {
|
|
||||||
//Error making request just continue.
|
resolve(userData);
|
||||||
checkPromise.resolve(userData);
|
}).on('error', function () {
|
||||||
|
//Error making request just continue.
|
||||||
|
resolve(userData);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return checkPromise.promise;
|
|
||||||
},
|
},
|
||||||
// Get the user by email address, enforces case insensitivity rejects if the user is not found
|
// Get the user by email address, enforces case insensitivity rejects if the user is not found
|
||||||
// When multi-user support is added, email addresses must be deduplicated with case insensitivity, so that
|
// When multi-user support is added, email addresses must be deduplicated with case insensitivity, so that
|
||||||
|
@ -869,7 +872,7 @@ User = ghostBookshelf.Model.extend({
|
||||||
return user.get('email').toLowerCase() === email.toLowerCase();
|
return user.get('email').toLowerCase() === email.toLowerCase();
|
||||||
});
|
});
|
||||||
if (userWithEmail) {
|
if (userWithEmail) {
|
||||||
return when.resolve(userWithEmail);
|
return userWithEmail;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// canThis(someUser).edit.post(somePost|somePostId)
|
// canThis(someUser).edit.post(somePost|somePostId)
|
||||||
|
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
Models = require('../models'),
|
Models = require('../models'),
|
||||||
effectivePerms = require('./effective'),
|
effectivePerms = require('./effective'),
|
||||||
init,
|
init,
|
||||||
|
@ -65,7 +65,7 @@ CanThisResult.prototype.buildObjectTypeHandlers = function (obj_types, act_type,
|
||||||
|
|
||||||
// If it's an internal request, resolve immediately
|
// If it's an internal request, resolve immediately
|
||||||
if (context.internal) {
|
if (context.internal) {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_.isNumber(modelOrId) || _.isString(modelOrId)) {
|
if (_.isNumber(modelOrId) || _.isString(modelOrId)) {
|
||||||
|
@ -127,9 +127,10 @@ CanThisResult.prototype.buildObjectTypeHandlers = function (obj_types, act_type,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasUserPermission && hasAppPermission) {
|
if (hasUserPermission && hasAppPermission) {
|
||||||
return when.resolve();
|
return;
|
||||||
}
|
}
|
||||||
return when.reject();
|
|
||||||
|
return Promise.reject();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ CanThisResult.prototype.beginCheck = function (context) {
|
||||||
userPermissionLoad = effectivePerms.user(context.user);
|
userPermissionLoad = effectivePerms.user(context.user);
|
||||||
} else {
|
} else {
|
||||||
// Resolve null if no context.user to prevent db call
|
// Resolve null if no context.user to prevent db call
|
||||||
userPermissionLoad = when.resolve(null);
|
userPermissionLoad = Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,11 +165,11 @@ CanThisResult.prototype.beginCheck = function (context) {
|
||||||
appPermissionLoad = effectivePerms.app(context.app);
|
appPermissionLoad = effectivePerms.app(context.app);
|
||||||
} else {
|
} else {
|
||||||
// Resolve null if no context.app
|
// Resolve null if no context.app
|
||||||
appPermissionLoad = when.resolve(null);
|
appPermissionLoad = Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for both user and app permissions to load
|
// Wait for both user and app permissions to load
|
||||||
permissionsLoad = when.all([userPermissionLoad, appPermissionLoad]).then(function (result) {
|
permissionsLoad = Promise.all([userPermissionLoad, appPermissionLoad]).then(function (result) {
|
||||||
return {
|
return {
|
||||||
user: result[0],
|
user: result[0],
|
||||||
app: result[1]
|
app: result[1]
|
||||||
|
@ -232,7 +233,7 @@ init = refresh = function () {
|
||||||
seenActions[action_type][object_type] = true;
|
seenActions[action_type][object_type] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
return when(exported.actionsMap);
|
return exported.actionsMap;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
keys = require('when/keys'),
|
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
readdirAsync = Promise.promisify(fs.readdir),
|
||||||
|
lstatAsync = Promise.promisify(fs.lstat),
|
||||||
|
|
||||||
parsePackageJson = function (path, messages) {
|
parsePackageJson = function (path, messages) {
|
||||||
// Default the messages if non were passed
|
// Default the messages if non were passed
|
||||||
messages = messages || {
|
messages = messages || {
|
||||||
|
@ -10,42 +12,42 @@ var _ = require('lodash'),
|
||||||
warns: []
|
warns: []
|
||||||
};
|
};
|
||||||
|
|
||||||
var packageDeferred = when.defer(),
|
var jsonContainer;
|
||||||
packagePromise = packageDeferred.promise,
|
|
||||||
jsonContainer;
|
|
||||||
|
|
||||||
fs.readFile(path, function (error, data) {
|
return new Promise(function (resolve) {
|
||||||
if (error) {
|
fs.readFile(path, function (error, data) {
|
||||||
messages.errors.push({
|
if (error) {
|
||||||
message: 'Could not read package.json file',
|
|
||||||
context: path
|
|
||||||
});
|
|
||||||
packageDeferred.resolve(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
jsonContainer = JSON.parse(data);
|
|
||||||
if (jsonContainer.hasOwnProperty('name') && jsonContainer.hasOwnProperty('version')) {
|
|
||||||
packageDeferred.resolve(jsonContainer);
|
|
||||||
} else {
|
|
||||||
messages.errors.push({
|
messages.errors.push({
|
||||||
message: '"name" or "version" is missing from theme package.json file.',
|
message: 'Could not read package.json file',
|
||||||
|
context: path
|
||||||
|
});
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
jsonContainer = JSON.parse(data);
|
||||||
|
if (jsonContainer.hasOwnProperty('name') && jsonContainer.hasOwnProperty('version')) {
|
||||||
|
resolve(jsonContainer);
|
||||||
|
} else {
|
||||||
|
messages.errors.push({
|
||||||
|
message: '"name" or "version" is missing from theme package.json file.',
|
||||||
|
context: path,
|
||||||
|
help: 'This will be required in future. Please see http://docs.ghost.org/themes/'
|
||||||
|
});
|
||||||
|
resolve(false);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
messages.errors.push({
|
||||||
|
message: 'Theme package.json file is malformed',
|
||||||
context: path,
|
context: path,
|
||||||
help: 'This will be required in future. Please see http://docs.ghost.org/themes/'
|
help: 'This will be required in future. Please see http://docs.ghost.org/themes/'
|
||||||
});
|
});
|
||||||
packageDeferred.resolve(false);
|
resolve(false);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
messages.errors.push({
|
|
||||||
message: 'Theme package.json file is malformed',
|
|
||||||
context: path,
|
|
||||||
help: 'This will be required in future. Please see http://docs.ghost.org/themes/'
|
|
||||||
});
|
|
||||||
packageDeferred.resolve(false);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return when(packagePromise);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
readDir = function (dir, options, depth, messages) {
|
readDir = function (dir, options, depth, messages) {
|
||||||
depth = depth || 0;
|
depth = depth || 0;
|
||||||
messages = messages || {
|
messages = messages || {
|
||||||
|
@ -58,44 +60,29 @@ var _ = require('lodash'),
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
if (depth > 1) {
|
if (depth > 1) {
|
||||||
return null;
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var subtree = {},
|
return readdirAsync(dir).then(function (files) {
|
||||||
treeDeferred = when.defer(),
|
|
||||||
treePromise = treeDeferred.promise;
|
|
||||||
|
|
||||||
fs.readdir(dir, function (error, files) {
|
|
||||||
if (error) {
|
|
||||||
return treeDeferred.reject(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
files = files || [];
|
files = files || [];
|
||||||
|
|
||||||
files.forEach(function (file) {
|
return Promise.reduce(files, function (results, file) {
|
||||||
var fileDeferred = when.defer(),
|
var fpath = path.join(dir, file);
|
||||||
filePromise = fileDeferred.promise,
|
|
||||||
fpath = path.join(dir, file);
|
return lstatAsync(fpath).then(function (result) {
|
||||||
subtree[file] = filePromise;
|
|
||||||
fs.lstat(fpath, function (error, result) {
|
|
||||||
/*jslint unparam:true*/
|
|
||||||
if (result.isDirectory()) {
|
if (result.isDirectory()) {
|
||||||
fileDeferred.resolve(readDir(fpath, options, depth + 1, messages));
|
return readDir(fpath, options, depth + 1, messages);
|
||||||
} else if (depth === 1 && file === 'package.json') {
|
} else if (depth === 1 && file === 'package.json') {
|
||||||
fileDeferred.resolve(parsePackageJson(fpath, messages));
|
return parsePackageJson(fpath, messages);
|
||||||
} else {
|
} else {
|
||||||
fileDeferred.resolve(fpath);
|
return fpath;
|
||||||
}
|
}
|
||||||
|
}).then(function (result) {
|
||||||
|
results[file] = result;
|
||||||
|
|
||||||
|
return results;
|
||||||
});
|
});
|
||||||
});
|
}, {});
|
||||||
|
|
||||||
return keys.all(subtree).then(function (theFiles) {
|
|
||||||
return treeDeferred.resolve(theFiles);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return when(treePromise).then(function (prom) {
|
|
||||||
return prom;
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
readAll = function (dir, options, depth) {
|
readAll = function (dir, options, depth) {
|
||||||
|
@ -105,7 +92,7 @@ var _ = require('lodash'),
|
||||||
warns: []
|
warns: []
|
||||||
};
|
};
|
||||||
|
|
||||||
return when(readDir(dir, options, depth, messages)).then(function (paths) {
|
return readDir(dir, options, depth, messages).then(function (paths) {
|
||||||
// for all contents of the dir, I'm interested in the ones that are directories and within /theme/
|
// for all contents of the dir, I'm interested in the ones that are directories and within /theme/
|
||||||
if (typeof paths === 'object' && dir.indexOf('theme') !== -1) {
|
if (typeof paths === 'object' && dir.indexOf('theme') !== -1) {
|
||||||
_.each(paths, function (path, index) {
|
_.each(paths, function (path, index) {
|
||||||
|
@ -118,9 +105,11 @@ var _ = require('lodash'),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
paths._messages = messages;
|
paths._messages = messages;
|
||||||
|
|
||||||
return paths;
|
return paths;
|
||||||
}).otherwise(function () {
|
}).catch(function () {
|
||||||
return {'_messages': messages};
|
return {'_messages': messages};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -129,4 +118,4 @@ module.exports = {
|
||||||
readAll: readAll,
|
readAll: readAll,
|
||||||
readDir: readDir,
|
readDir: readDir,
|
||||||
parsePackageJson: parsePackageJson
|
parsePackageJson: parsePackageJson
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
var moment = require('moment'),
|
var moment = require('moment'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
baseStore;
|
baseStore;
|
||||||
|
|
||||||
// TODO: would probably be better to put these on the prototype and have proper constructors etc
|
// TODO: would probably be better to put these on the prototype and have proper constructors etc
|
||||||
|
@ -34,18 +34,18 @@ baseStore = {
|
||||||
self.generateUnique(store, dir, name, ext, i, done);
|
self.generateUnique(store, dir, name, ext, i, done);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
done.resolve(filename);
|
done(filename);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'getUniqueFileName': function (store, image, targetDir) {
|
'getUniqueFileName': function (store, image, targetDir) {
|
||||||
var done = when.defer(),
|
var ext = path.extname(image.name),
|
||||||
ext = path.extname(image.name),
|
name = path.basename(image.name, ext).replace(/[\W]/gi, '-'),
|
||||||
name = path.basename(image.name, ext).replace(/[\W]/gi, '-');
|
self = this;
|
||||||
|
|
||||||
this.generateUnique(store, targetDir, name, ext, 0, done);
|
return new Promise(function (resolve) {
|
||||||
|
self.generateUnique(store, targetDir, name, ext, 0, resolve);
|
||||||
return done.promise;
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
express = require('express'),
|
express = require('express'),
|
||||||
fs = require('fs-extra'),
|
fs = require('fs-extra'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
errors = require('../errors'),
|
errors = require('../errors'),
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
utils = require('../utils'),
|
utils = require('../utils'),
|
||||||
|
@ -20,37 +19,31 @@ localFileStore = _.extend(baseStore, {
|
||||||
// - image is the express image object
|
// - image is the express image object
|
||||||
// - returns a promise which ultimately returns the full url to the uploaded image
|
// - returns a promise which ultimately returns the full url to the uploaded image
|
||||||
'save': function (image) {
|
'save': function (image) {
|
||||||
var saved = when.defer(),
|
var targetDir = this.getTargetDir(config.paths.imagesPath),
|
||||||
targetDir = this.getTargetDir(config.paths.imagesPath),
|
|
||||||
targetFilename;
|
targetFilename;
|
||||||
|
|
||||||
this.getUniqueFileName(this, image, targetDir).then(function (filename) {
|
return this.getUniqueFileName(this, image, targetDir).then(function (filename) {
|
||||||
targetFilename = filename;
|
targetFilename = filename;
|
||||||
return nodefn.call(fs.mkdirs, targetDir);
|
return Promise.promisify(fs.mkdirs)(targetDir);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return nodefn.call(fs.copy, image.path, targetFilename);
|
return Promise.promisify(fs.copy)(image.path, targetFilename);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// The src for the image must be in URI format, not a file system path, which in Windows uses \
|
// The src for the image must be in URI format, not a file system path, which in Windows uses \
|
||||||
// For local file system storage can use relative path so add a slash
|
// For local file system storage can use relative path so add a slash
|
||||||
var fullUrl = (config.paths.subdir + '/' + config.paths.imagesRelPath + '/' + path.relative(config.paths.imagesPath, targetFilename)).replace(new RegExp('\\' + path.sep, 'g'), '/');
|
var fullUrl = (config.paths.subdir + '/' + config.paths.imagesRelPath + '/' + path.relative(config.paths.imagesPath, targetFilename)).replace(new RegExp('\\' + path.sep, 'g'), '/');
|
||||||
return saved.resolve(fullUrl);
|
return fullUrl;
|
||||||
}).otherwise(function (e) {
|
}).catch(function (e) {
|
||||||
errors.logError(e);
|
errors.logError(e);
|
||||||
return saved.reject(e);
|
return Promise.reject(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
return saved.promise;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
'exists': function (filename) {
|
'exists': function (filename) {
|
||||||
// fs.exists does not play nicely with nodefn because the callback doesn't have an error argument
|
return new Promise(function (resolve) {
|
||||||
var done = when.defer();
|
fs.exists(filename, function (exists) {
|
||||||
|
resolve(exists);
|
||||||
fs.exists(filename, function (exists) {
|
});
|
||||||
done.resolve(exists);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return done.promise;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// middleware for serving the files
|
// middleware for serving the files
|
||||||
|
|
|
@ -23,8 +23,7 @@ var crypto = require('crypto'),
|
||||||
https = require('https'),
|
https = require('https'),
|
||||||
moment = require('moment'),
|
moment = require('moment'),
|
||||||
semver = require('semver'),
|
semver = require('semver'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
url = require('url'),
|
url = require('url'),
|
||||||
|
|
||||||
|
@ -51,8 +50,8 @@ function updateCheckData() {
|
||||||
ops = [],
|
ops = [],
|
||||||
mailConfig = config.mail;
|
mailConfig = config.mail;
|
||||||
|
|
||||||
ops.push(api.settings.read(_.extend(internal, {key: 'dbHash'})).otherwise(errors.rejectError));
|
ops.push(api.settings.read(_.extend(internal, {key: 'dbHash'})).catch(errors.rejectError));
|
||||||
ops.push(api.settings.read(_.extend(internal, {key: 'activeTheme'})).otherwise(errors.rejectError));
|
ops.push(api.settings.read(_.extend(internal, {key: 'activeTheme'})).catch(errors.rejectError));
|
||||||
ops.push(api.settings.read(_.extend(internal, {key: 'activeApps'}))
|
ops.push(api.settings.read(_.extend(internal, {key: 'activeApps'}))
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
var apps = response.settings[0];
|
var apps = response.settings[0];
|
||||||
|
@ -63,10 +62,10 @@ function updateCheckData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.reduce(apps, function (memo, item) { return memo === '' ? memo + item : memo + ', ' + item; }, '');
|
return _.reduce(apps, function (memo, item) { return memo === '' ? memo + item : memo + ', ' + item; }, '');
|
||||||
}).otherwise(errors.rejectError));
|
}).catch(errors.rejectError));
|
||||||
ops.push(api.posts.browse().otherwise(errors.rejectError));
|
ops.push(api.posts.browse().catch(errors.rejectError));
|
||||||
ops.push(api.users.browse(internal).otherwise(errors.rejectError));
|
ops.push(api.users.browse(internal).catch(errors.rejectError));
|
||||||
ops.push(nodefn.call(exec, 'npm -v').otherwise(errors.rejectError));
|
ops.push(Promise.promisify(exec)('npm -v').catch(errors.rejectError));
|
||||||
|
|
||||||
data.ghost_version = currentVersion;
|
data.ghost_version = currentVersion;
|
||||||
data.node_version = process.versions.node;
|
data.node_version = process.versions.node;
|
||||||
|
@ -74,13 +73,13 @@ function updateCheckData() {
|
||||||
data.database_type = config.database.client;
|
data.database_type = config.database.client;
|
||||||
data.email_transport = mailConfig && (mailConfig.options && mailConfig.options.service ? mailConfig.options.service : mailConfig.transport);
|
data.email_transport = mailConfig && (mailConfig.options && mailConfig.options.service ? mailConfig.options.service : mailConfig.transport);
|
||||||
|
|
||||||
return when.settle(ops).then(function (descriptors) {
|
return Promise.settle(ops).then(function (descriptors) {
|
||||||
var hash = descriptors[0].value.settings[0],
|
var hash = descriptors[0].value().settings[0],
|
||||||
theme = descriptors[1].value.settings[0],
|
theme = descriptors[1].value().settings[0],
|
||||||
apps = descriptors[2].value,
|
apps = descriptors[2].value(),
|
||||||
posts = descriptors[3].value,
|
posts = descriptors[3].value(),
|
||||||
users = descriptors[4].value,
|
users = descriptors[4].value(),
|
||||||
npm = descriptors[5].value,
|
npm = descriptors[5].value(),
|
||||||
blogUrl = url.parse(config.url),
|
blogUrl = url.parse(config.url),
|
||||||
blogId = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value;
|
blogId = blogUrl.hostname + blogUrl.pathname.replace(/\//, '') + hash.value;
|
||||||
|
|
||||||
|
@ -93,13 +92,12 @@ function updateCheckData() {
|
||||||
data.npm_version = _.isArray(npm) && npm[0] ? npm[0].toString().replace(/\n/, '') : '';
|
data.npm_version = _.isArray(npm) && npm[0] ? npm[0].toString().replace(/\n/, '') : '';
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}).otherwise(updateCheckError);
|
}).catch(updateCheckError);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCheckRequest() {
|
function updateCheckRequest() {
|
||||||
return updateCheckData().then(function (reqData) {
|
return updateCheckData().then(function (reqData) {
|
||||||
var deferred = when.defer(),
|
var resData = '',
|
||||||
resData = '',
|
|
||||||
headers,
|
headers,
|
||||||
req;
|
req;
|
||||||
|
|
||||||
|
@ -109,31 +107,31 @@ function updateCheckRequest() {
|
||||||
'Content-Length': reqData.length
|
'Content-Length': reqData.length
|
||||||
};
|
};
|
||||||
|
|
||||||
req = https.request({
|
return new Promise(function (resolve, reject) {
|
||||||
hostname: checkEndpoint,
|
req = https.request({
|
||||||
method: 'POST',
|
hostname: checkEndpoint,
|
||||||
headers: headers
|
method: 'POST',
|
||||||
}, function (res) {
|
headers: headers
|
||||||
res.on('error', function (error) { deferred.reject(error); });
|
}, function (res) {
|
||||||
res.on('data', function (chunk) { resData += chunk; });
|
res.on('error', function (error) { reject(error); });
|
||||||
res.on('end', function () {
|
res.on('data', function (chunk) { resData += chunk; });
|
||||||
try {
|
res.on('end', function () {
|
||||||
resData = JSON.parse(resData);
|
try {
|
||||||
deferred.resolve(resData);
|
resData = JSON.parse(resData);
|
||||||
} catch (e) {
|
resolve(resData);
|
||||||
deferred.reject('Unable to decode update response');
|
} catch (e) {
|
||||||
}
|
reject('Unable to decode update response');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
req.write(reqData);
|
||||||
|
req.end();
|
||||||
|
|
||||||
|
req.on('error', function (error) {
|
||||||
|
reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
req.write(reqData);
|
|
||||||
req.end();
|
|
||||||
|
|
||||||
req.on('error', function (error) {
|
|
||||||
deferred.reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,53 +147,45 @@ function updateCheckResponse(response) {
|
||||||
api.settings.edit(
|
api.settings.edit(
|
||||||
{settings: [{key: 'nextUpdateCheck', value: response.next_check}]},
|
{settings: [{key: 'nextUpdateCheck', value: response.next_check}]},
|
||||||
internal
|
internal
|
||||||
)
|
).catch(errors.rejectError),
|
||||||
.otherwise(errors.rejectError),
|
|
||||||
api.settings.edit(
|
api.settings.edit(
|
||||||
{settings: [{key: 'displayUpdateNotification', value: response.version}]},
|
{settings: [{key: 'displayUpdateNotification', value: response.version}]},
|
||||||
internal
|
internal
|
||||||
)
|
).catch(errors.rejectError)
|
||||||
.otherwise(errors.rejectError)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return when.settle(ops).then(function (descriptors) {
|
return Promise.settle(ops).then(function (descriptors) {
|
||||||
descriptors.forEach(function (d) {
|
descriptors.forEach(function (d) {
|
||||||
if (d.state === 'rejected') {
|
if (d.isRejected()) {
|
||||||
errors.rejectError(d.reason);
|
errors.rejectError(d.reason());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return when.resolve();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCheck() {
|
function updateCheck() {
|
||||||
var deferred = when.defer();
|
|
||||||
|
|
||||||
// The check will not happen if:
|
// The check will not happen if:
|
||||||
// 1. updateCheck is defined as false in config.js
|
// 1. updateCheck is defined as false in config.js
|
||||||
// 2. we've already done a check this session
|
// 2. we've already done a check this session
|
||||||
// 3. we're not in production or development mode
|
// 3. we're not in production or development mode
|
||||||
if (config.updateCheck === false || _.indexOf(allowedCheckEnvironments, process.env.NODE_ENV) === -1) {
|
if (config.updateCheck === false || _.indexOf(allowedCheckEnvironments, process.env.NODE_ENV) === -1) {
|
||||||
// No update check
|
// No update check
|
||||||
deferred.resolve();
|
return Promise.resolve();
|
||||||
} else {
|
} else {
|
||||||
api.settings.read(_.extend(internal, {key: 'nextUpdateCheck'})).then(function (result) {
|
return api.settings.read(_.extend(internal, {key: 'nextUpdateCheck'})).then(function (result) {
|
||||||
var nextUpdateCheck = result.settings[0];
|
var nextUpdateCheck = result.settings[0];
|
||||||
|
|
||||||
if (nextUpdateCheck && nextUpdateCheck.value && nextUpdateCheck.value > moment().unix()) {
|
if (nextUpdateCheck && nextUpdateCheck.value && nextUpdateCheck.value > moment().unix()) {
|
||||||
// It's not time to check yet
|
// It's not time to check yet
|
||||||
deferred.resolve();
|
return;
|
||||||
} else {
|
} else {
|
||||||
// We need to do a check
|
// We need to do a check
|
||||||
return updateCheckRequest()
|
return updateCheckRequest()
|
||||||
.then(updateCheckResponse)
|
.then(updateCheckResponse)
|
||||||
.otherwise(updateCheckError);
|
.catch(updateCheckError);
|
||||||
}
|
}
|
||||||
}).otherwise(updateCheckError)
|
}).catch(updateCheckError);
|
||||||
.then(deferred.resolve);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showUpdateNotification() {
|
function showUpdateNotification() {
|
||||||
|
@ -210,9 +200,10 @@ function showUpdateNotification() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (display && display.value && currentVersion && semver.gt(display.value, currentVersion)) {
|
if (display && display.value && currentVersion && semver.gt(display.value, currentVersion)) {
|
||||||
return when(display.value);
|
return display.value;
|
||||||
}
|
}
|
||||||
return when(false);
|
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
core/server/utils/pipeline.js
Normal file
21
core/server/utils/pipeline.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
var Promise = require('bluebird');
|
||||||
|
|
||||||
|
function pipeline(tasks /* initial arguments */) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1),
|
||||||
|
|
||||||
|
runTask = function (task, args) {
|
||||||
|
runTask = function (task, arg) {
|
||||||
|
return task(arg);
|
||||||
|
};
|
||||||
|
|
||||||
|
return task.apply(null, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise.all(tasks).reduce(function (arg, task) {
|
||||||
|
return Promise.resolve(runTask(task, arg)).then(function (result) {
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = pipeline;
|
13
core/server/utils/sequence.js
Normal file
13
core/server/utils/sequence.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
var Promise = require('bluebird');
|
||||||
|
|
||||||
|
function sequence(tasks) {
|
||||||
|
return Promise.reduce(tasks, function (results, task) {
|
||||||
|
return task().then(function (result) {
|
||||||
|
results.push(result);
|
||||||
|
|
||||||
|
return results;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = sequence;
|
|
@ -62,7 +62,7 @@ describe('Admin Routing', function () {
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
}).otherwise(function (e) {
|
}).catch(function (e) {
|
||||||
console.log('Ghost Error: ', e);
|
console.log('Ghost Error: ', e);
|
||||||
console.log(e.stack);
|
console.log(e.stack);
|
||||||
});
|
});
|
||||||
|
@ -332,7 +332,7 @@ describe('Admin Routing', function () {
|
||||||
|
|
||||||
// });
|
// });
|
||||||
// }).catch(done);
|
// }).catch(done);
|
||||||
// }).otherwise(function (e) {
|
// }).catch(function (e) {
|
||||||
// console.log('Ghost Error: ', e);
|
// console.log('Ghost Error: ', e);
|
||||||
// console.log(e.stack);
|
// console.log(e.stack);
|
||||||
// });
|
// });
|
||||||
|
|
|
@ -334,7 +334,8 @@ describe('User API', function () {
|
||||||
|
|
||||||
var jsonResponse = res.body,
|
var jsonResponse = res.body,
|
||||||
changedValue = 'joe-bloggs.ghost.org';
|
changedValue = 'joe-bloggs.ghost.org';
|
||||||
jsonResponse.users[0].should.exist;
|
|
||||||
|
should.exist(jsonResponse.users[0]);
|
||||||
jsonResponse.users[0].website = changedValue;
|
jsonResponse.users[0].website = changedValue;
|
||||||
|
|
||||||
request.put(testUtils.API.getApiQuery('users/me/'))
|
request.put(testUtils.API.getApiQuery('users/me/'))
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var testUtils = require('../../utils'),
|
var testUtils = require('../../utils'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -43,7 +43,7 @@ describe('Authentication API', function () {
|
||||||
send = mail.__get__('mail.send');
|
send = mail.__get__('mail.send');
|
||||||
|
|
||||||
mail.__set__('mail.send', function () {
|
mail.__set__('mail.send', function () {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
AuthAPI.setup({ setup: [setupData] }).then(function (result) {
|
AuthAPI.setup({ setup: [setupData] }).then(function (result) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ var _ = require('lodash'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
SettingsAPI = require('../../../server/api/settings'),
|
SettingsAPI = require('../../../server/api/settings'),
|
||||||
|
@ -30,11 +30,11 @@ describe('Themes API', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
// Override settings.read for activeTheme
|
// Override settings.read for activeTheme
|
||||||
sandbox.stub(SettingsAPI, 'read', function () {
|
sandbox.stub(SettingsAPI, 'read', function () {
|
||||||
return when({ settings: [{value: 'casper'}] });
|
return Promise.resolve({ settings: [{value: 'casper'}] });
|
||||||
});
|
});
|
||||||
|
|
||||||
sandbox.stub(SettingsAPI, 'edit', function () {
|
sandbox.stub(SettingsAPI, 'edit', function () {
|
||||||
return when({ settings: [{value: 'rasper'}] });
|
return Promise.resolve({ settings: [{value: 'rasper'}] });
|
||||||
});
|
});
|
||||||
|
|
||||||
configStub = {
|
configStub = {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var fs = require('fs-extra'),
|
var fs = require('fs-extra'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
storage = require('../../../server/storage'),
|
storage = require('../../../server/storage'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -23,9 +23,9 @@ describe('Upload API', function () {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
store = sinon.stub();
|
store = sinon.stub();
|
||||||
store.save = sinon.stub().returns(when('URL'));
|
store.save = sinon.stub().returns(Promise.resolve('URL'));
|
||||||
store.exists = sinon.stub().returns(when(true));
|
store.exists = sinon.stub().returns(Promise.resolve(true));
|
||||||
store.destroy = sinon.stub().returns(when());
|
store.destroy = sinon.stub().returns(Promise.resolve());
|
||||||
sinon.stub(storage, 'get_storage').returns(store);
|
sinon.stub(storage, 'get_storage').returns(store);
|
||||||
sinon.stub(fs, 'unlink').yields();
|
sinon.stub(fs, 'unlink').yields();
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var testUtils = require('../../utils'),
|
var testUtils = require('../../utils'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -340,11 +340,11 @@ describe('Users API', function () {
|
||||||
newUser = _.clone(testUtils.DataGenerator.forKnex.createUser(testUtils.DataGenerator.Content.users[4]));
|
newUser = _.clone(testUtils.DataGenerator.forKnex.createUser(testUtils.DataGenerator.Content.users[4]));
|
||||||
|
|
||||||
sandbox.stub(ModelUser.User, 'gravatarLookup', function (userData) {
|
sandbox.stub(ModelUser.User, 'gravatarLookup', function (userData) {
|
||||||
return when.resolve(userData);
|
return Promise.resolve(userData);
|
||||||
});
|
});
|
||||||
|
|
||||||
sandbox.stub(mail, 'send', function () {
|
sandbox.stub(mail, 'send', function () {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
|
@ -933,11 +933,11 @@ describe('Users API', function () {
|
||||||
{name: newName, roles: [roleIdFor.admin]}
|
{name: newName, roles: [roleIdFor.admin]}
|
||||||
]}, _.extend({}, context.editor, {id: userIdFor.author}, {include: 'roles'})
|
]}, _.extend({}, context.editor, {id: userIdFor.author}, {include: 'roles'})
|
||||||
).then(function (response) {
|
).then(function (response) {
|
||||||
done(new Error('Editor should not be able to upgrade the role of authors'));
|
done(new Error('Editor should not be able to upgrade the role of authors'));
|
||||||
}, function (error) {
|
}).catch(function (error) {
|
||||||
error.type.should.eql('NoPermissionError');
|
error.type.should.eql('NoPermissionError');
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var testUtils = require('../utils/index'),
|
var testUtils = require('../utils/index'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -25,7 +25,7 @@ describe('Exporter', function () {
|
||||||
it('exports data', function (done) {
|
it('exports data', function (done) {
|
||||||
// Stub migrations to return 000 as the current database version
|
// Stub migrations to return 000 as the current database version
|
||||||
var versioningStub = sandbox.stub(versioning, 'getDatabaseVersion', function () {
|
var versioningStub = sandbox.stub(versioning, 'getDatabaseVersion', function () {
|
||||||
return when.resolve('003');
|
return Promise.resolve('003');
|
||||||
});
|
});
|
||||||
|
|
||||||
exporter().then(function (exportData) {
|
exporter().then(function (exportData) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var testUtils = require('../utils/index'),
|
var testUtils = require('../utils/index'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
assert = require('assert'),
|
assert = require('assert'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
|
@ -48,7 +48,7 @@ describe('Import', function () {
|
||||||
|
|
||||||
it('resolves 000', function (done) {
|
it('resolves 000', function (done) {
|
||||||
var importStub = sandbox.stub(Importer000, 'importData', function () {
|
var importStub = sandbox.stub(Importer000, 'importData', function () {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}),
|
}),
|
||||||
fakeData = { test: true };
|
fakeData = { test: true };
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ describe('Import', function () {
|
||||||
|
|
||||||
it('resolves 001', function (done) {
|
it('resolves 001', function (done) {
|
||||||
var importStub = sandbox.stub(Importer001, 'importData', function () {
|
var importStub = sandbox.stub(Importer001, 'importData', function () {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}),
|
}),
|
||||||
fakeData = { test: true };
|
fakeData = { test: true };
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ describe('Import', function () {
|
||||||
|
|
||||||
it('resolves 002', function (done) {
|
it('resolves 002', function (done) {
|
||||||
var importStub = sandbox.stub(Importer002, 'importData', function () {
|
var importStub = sandbox.stub(Importer002, 'importData', function () {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}),
|
}),
|
||||||
fakeData = { test: true };
|
fakeData = { test: true };
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ describe('Import', function () {
|
||||||
|
|
||||||
it('resolves 003', function (done) {
|
it('resolves 003', function (done) {
|
||||||
var importStub = sandbox.stub(Importer003, 'importData', function () {
|
var importStub = sandbox.stub(Importer003, 'importData', function () {
|
||||||
return when.resolve();
|
return Promise.resolve();
|
||||||
}),
|
}),
|
||||||
fakeData = { test: true };
|
fakeData = { test: true };
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ describe('Import', function () {
|
||||||
it('imports data from 000', function (done) {
|
it('imports data from 000', function (done) {
|
||||||
var exportData,
|
var exportData,
|
||||||
versioningStub = sandbox.stub(versioning, 'getDatabaseVersion', function () {
|
versioningStub = sandbox.stub(versioning, 'getDatabaseVersion', function () {
|
||||||
return when.resolve('000');
|
return Promise.resolve('000');
|
||||||
});
|
});
|
||||||
|
|
||||||
testUtils.fixtures.loadExportFixture('export-000').then(function (exported) {
|
testUtils.fixtures.loadExportFixture('export-000').then(function (exported) {
|
||||||
|
@ -127,7 +127,7 @@ describe('Import', function () {
|
||||||
return importer('000', exportData);
|
return importer('000', exportData);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Grab the data from tables
|
// Grab the data from tables
|
||||||
return when.all([
|
return Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -186,7 +186,7 @@ describe('Import', function () {
|
||||||
return importer('001', exportData);
|
return importer('001', exportData);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Grab the data from tables
|
// Grab the data from tables
|
||||||
return when.all([
|
return Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -261,7 +261,7 @@ describe('Import', function () {
|
||||||
error[0].message.should.eql('Value in [posts.title] exceeds maximum length of 150 characters.');
|
error[0].message.should.eql('Value in [posts.title] exceeds maximum length of 150 characters.');
|
||||||
error[0].type.should.eql('ValidationError');
|
error[0].type.should.eql('ValidationError');
|
||||||
|
|
||||||
when.all([
|
Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -310,7 +310,7 @@ describe('Import', function () {
|
||||||
error[0].message.should.eql('Value in [settings.key] cannot be blank.');
|
error[0].message.should.eql('Value in [settings.key] cannot be blank.');
|
||||||
error[0].type.should.eql('ValidationError');
|
error[0].type.should.eql('ValidationError');
|
||||||
|
|
||||||
when.all([
|
Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -367,7 +367,7 @@ describe('Import', function () {
|
||||||
return importer('002', exportData);
|
return importer('002', exportData);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Grab the data from tables
|
// Grab the data from tables
|
||||||
return when.all([
|
return Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -443,7 +443,7 @@ describe('Import', function () {
|
||||||
error[0].message.should.eql('Value in [posts.title] exceeds maximum length of 150 characters.');
|
error[0].message.should.eql('Value in [posts.title] exceeds maximum length of 150 characters.');
|
||||||
error[0].type.should.eql('ValidationError');
|
error[0].type.should.eql('ValidationError');
|
||||||
|
|
||||||
when.all([
|
Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -489,7 +489,7 @@ describe('Import', function () {
|
||||||
error[0].message.should.eql('Value in [settings.key] cannot be blank.');
|
error[0].message.should.eql('Value in [settings.key] cannot be blank.');
|
||||||
error[0].type.should.eql('ValidationError');
|
error[0].type.should.eql('ValidationError');
|
||||||
|
|
||||||
when.all([
|
Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -537,7 +537,7 @@ describe('Import', function () {
|
||||||
return importer('003', exportData);
|
return importer('003', exportData);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Grab the data from tables
|
// Grab the data from tables
|
||||||
return when.all([
|
return Promise.all([
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
|
@ -704,7 +704,7 @@ describe('Import (new test structure)', function () {
|
||||||
after(testUtils.teardown);
|
after(testUtils.teardown);
|
||||||
|
|
||||||
it('gets the right data', function (done) {
|
it('gets the right data', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
knex('tags').select()
|
knex('tags').select()
|
||||||
|
@ -755,7 +755,7 @@ describe('Import (new test structure)', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports users with correct roles and status', function (done) {
|
it('imports users with correct roles and status', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('roles_users').select()
|
knex('roles_users').select()
|
||||||
);
|
);
|
||||||
|
@ -829,7 +829,7 @@ describe('Import (new test structure)', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports posts & tags with correct authors, owners etc', function (done) {
|
it('imports posts & tags with correct authors, owners etc', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('tags').select()
|
knex('tags').select()
|
||||||
|
@ -931,7 +931,7 @@ describe('Import (new test structure)', function () {
|
||||||
after(testUtils.teardown);
|
after(testUtils.teardown);
|
||||||
|
|
||||||
it('gets the right data', function (done) {
|
it('gets the right data', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
knex('tags').select()
|
knex('tags').select()
|
||||||
|
@ -982,7 +982,7 @@ describe('Import (new test structure)', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports users with correct roles and status', function (done) {
|
it('imports users with correct roles and status', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('roles_users').select()
|
knex('roles_users').select()
|
||||||
);
|
);
|
||||||
|
@ -1056,7 +1056,7 @@ describe('Import (new test structure)', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports posts & tags with correct authors, owners etc', function (done) {
|
it('imports posts & tags with correct authors, owners etc', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('tags').select()
|
knex('tags').select()
|
||||||
|
@ -1159,7 +1159,7 @@ describe('Import (new test structure)', function () {
|
||||||
after(testUtils.teardown);
|
after(testUtils.teardown);
|
||||||
|
|
||||||
it('gets the right data', function (done) {
|
it('gets the right data', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('settings').select(),
|
knex('settings').select(),
|
||||||
knex('tags').select()
|
knex('tags').select()
|
||||||
|
@ -1221,7 +1221,7 @@ describe('Import (new test structure)', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports users with correct roles and status', function (done) {
|
it('imports users with correct roles and status', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('roles_users').select()
|
knex('roles_users').select()
|
||||||
);
|
);
|
||||||
|
@ -1290,7 +1290,7 @@ describe('Import (new test structure)', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('imports posts & tags with correct authors, owners etc', function (done) {
|
it('imports posts & tags with correct authors, owners etc', function (done) {
|
||||||
var fetchImported = when.join(
|
var fetchImported = Promise.join(
|
||||||
knex('users').select(),
|
knex('users').select(),
|
||||||
knex('posts').select(),
|
knex('posts').select(),
|
||||||
knex('tags').select()
|
knex('tags').select()
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var testUtils = require('../../utils'),
|
var testUtils = require('../../utils'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sequence = require('when/sequence'),
|
Promise = require('bluebird'),
|
||||||
|
sequence = require('../../../server/utils/sequence'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var testUtils = require('../../utils'),
|
var testUtils = require('../../utils'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sequence = require('when/sequence'),
|
Promise = require('bluebird'),
|
||||||
|
sequence = require('../../../server/utils/sequence'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -541,6 +542,6 @@ describe('Post Model', function () {
|
||||||
// }).then(function (saved) {
|
// }).then(function (saved) {
|
||||||
// saved.get('title').should.eql("</title></head><body>[removed]alert('blogtitle');[removed]");
|
// saved.get('title').should.eql("</title></head><body>[removed]alert('blogtitle');[removed]");
|
||||||
// done();
|
// done();
|
||||||
// }).otherwise(done);
|
// }).catch(done);
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var testUtils = require('../../utils'),
|
var testUtils = require('../../utils'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -44,7 +44,7 @@ describe('Tag Model', function () {
|
||||||
newTag = testUtils.DataGenerator.forModel.tags[0],
|
newTag = testUtils.DataGenerator.forModel.tags[0],
|
||||||
createdPostID;
|
createdPostID;
|
||||||
|
|
||||||
when.all([
|
Promise.all([
|
||||||
PostModel.add(newPost, context),
|
PostModel.add(newPost, context),
|
||||||
TagModel.add(newTag, context)
|
TagModel.add(newTag, context)
|
||||||
]).then(function (models) {
|
]).then(function (models) {
|
||||||
|
@ -71,7 +71,7 @@ describe('Tag Model', function () {
|
||||||
createdTagID,
|
createdTagID,
|
||||||
createdPostID;
|
createdPostID;
|
||||||
|
|
||||||
when.all([
|
Promise.all([
|
||||||
PostModel.add(newPost, context),
|
PostModel.add(newPost, context),
|
||||||
TagModel.add(newTag, context)
|
TagModel.add(newTag, context)
|
||||||
]).then(function (models) {
|
]).then(function (models) {
|
||||||
|
@ -106,7 +106,7 @@ describe('Tag Model', function () {
|
||||||
var tagModels = tagNames.map(function (tagName) { return TagModel.add({name: tagName}, context); });
|
var tagModels = tagNames.map(function (tagName) { return TagModel.add({name: tagName}, context); });
|
||||||
createOperations = createOperations.concat(tagModels);
|
createOperations = createOperations.concat(tagModels);
|
||||||
|
|
||||||
return when.all(createOperations).then(function (models) {
|
return Promise.all(createOperations).then(function (models) {
|
||||||
var postModel = models[0],
|
var postModel = models[0],
|
||||||
attachOperations;
|
attachOperations;
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ describe('Tag Model', function () {
|
||||||
attachOperations.push(postModel.tags().attach(models[i]));
|
attachOperations.push(postModel.tags().attach(models[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return when.all(attachOperations).then(function () {
|
return Promise.all(attachOperations).then(function () {
|
||||||
return postModel;
|
return postModel;
|
||||||
});
|
});
|
||||||
}).then(function (postModel) {
|
}).then(function (postModel) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var testUtils = require('../../utils'),
|
var testUtils = require('../../utils'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
uuid = require('node-uuid'),
|
uuid = require('node-uuid'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
@ -33,7 +33,7 @@ describe('User Model', function run() {
|
||||||
var userData = testUtils.DataGenerator.forModel.users[0];
|
var userData = testUtils.DataGenerator.forModel.users[0];
|
||||||
|
|
||||||
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
||||||
return when.resolve(userData);
|
return Promise.resolve(userData);
|
||||||
});
|
});
|
||||||
|
|
||||||
UserModel.add(userData, context).then(function (createdUser) {
|
UserModel.add(userData, context).then(function (createdUser) {
|
||||||
|
@ -50,7 +50,7 @@ describe('User Model', function run() {
|
||||||
var userData = testUtils.DataGenerator.forModel.users[2];
|
var userData = testUtils.DataGenerator.forModel.users[2];
|
||||||
|
|
||||||
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
||||||
return when.resolve(userData);
|
return Promise.resolve(userData);
|
||||||
});
|
});
|
||||||
|
|
||||||
UserModel.add(userData, context).then(function (createdUser) {
|
UserModel.add(userData, context).then(function (createdUser) {
|
||||||
|
@ -66,7 +66,7 @@ describe('User Model', function run() {
|
||||||
|
|
||||||
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
||||||
userData.image = 'http://www.gravatar.com/avatar/2fab21a4c4ed88e76add10650c73bae1?d=404';
|
userData.image = 'http://www.gravatar.com/avatar/2fab21a4c4ed88e76add10650c73bae1?d=404';
|
||||||
return when.resolve(userData);
|
return Promise.resolve(userData);
|
||||||
});
|
});
|
||||||
|
|
||||||
UserModel.add(userData, context).then(function (createdUser) {
|
UserModel.add(userData, context).then(function (createdUser) {
|
||||||
|
@ -83,7 +83,7 @@ describe('User Model', function run() {
|
||||||
var userData = testUtils.DataGenerator.forModel.users[0];
|
var userData = testUtils.DataGenerator.forModel.users[0];
|
||||||
|
|
||||||
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
||||||
return when.resolve(userData);
|
return Promise.resolve(userData);
|
||||||
});
|
});
|
||||||
|
|
||||||
UserModel.add(userData, context).then(function (createdUser) {
|
UserModel.add(userData, context).then(function (createdUser) {
|
||||||
|
@ -271,7 +271,7 @@ describe('User Model', function run() {
|
||||||
var userData = testUtils.DataGenerator.forModel.users[4];
|
var userData = testUtils.DataGenerator.forModel.users[4];
|
||||||
|
|
||||||
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
sandbox.stub(UserModel, 'gravatarLookup', function (userData) {
|
||||||
return when.resolve(userData);
|
return Promise.resolve(userData);
|
||||||
});
|
});
|
||||||
|
|
||||||
RoleModel.findOne().then(function (role) {
|
RoleModel.findOne().then(function (role) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ var path = require('path'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
helpers = require('../../server/helpers'),
|
helpers = require('../../server/helpers'),
|
||||||
filters = require('../../server/filters'),
|
filters = require('../../server/filters'),
|
||||||
|
|
||||||
|
@ -432,7 +432,7 @@ describe('Apps', function () {
|
||||||
var perms = new AppPermissions("test");
|
var perms = new AppPermissions("test");
|
||||||
|
|
||||||
// No package.json in this directory
|
// No package.json in this directory
|
||||||
sandbox.stub(perms, "checkPackageContentsExists").returns(when.resolve(false));
|
sandbox.stub(perms, "checkPackageContentsExists").returns(Promise.resolve(false));
|
||||||
|
|
||||||
perms.read().then(function (readPerms) {
|
perms.read().then(function (readPerms) {
|
||||||
should.exist(readPerms);
|
should.exist(readPerms);
|
||||||
|
@ -447,9 +447,9 @@ describe('Apps', function () {
|
||||||
noGhostPackageJsonContents = JSON.stringify(noGhostPackageJson, null, 2);
|
noGhostPackageJsonContents = JSON.stringify(noGhostPackageJson, null, 2);
|
||||||
|
|
||||||
// package.json IS in this directory
|
// package.json IS in this directory
|
||||||
sandbox.stub(perms, "checkPackageContentsExists").returns(when.resolve(true));
|
sandbox.stub(perms, "checkPackageContentsExists").returns(Promise.resolve(true));
|
||||||
// no ghost property on package
|
// no ghost property on package
|
||||||
sandbox.stub(perms, "getPackageContents").returns(when.resolve(noGhostPackageJsonContents));
|
sandbox.stub(perms, "getPackageContents").returns(Promise.resolve(noGhostPackageJsonContents));
|
||||||
|
|
||||||
perms.read().then(function (readPerms) {
|
perms.read().then(function (readPerms) {
|
||||||
should.exist(readPerms);
|
should.exist(readPerms);
|
||||||
|
@ -463,9 +463,9 @@ describe('Apps', function () {
|
||||||
var perms = new AppPermissions("test");
|
var perms = new AppPermissions("test");
|
||||||
|
|
||||||
// package.json IS in this directory
|
// package.json IS in this directory
|
||||||
sandbox.stub(perms, "checkPackageContentsExists").returns(when.resolve(true));
|
sandbox.stub(perms, "checkPackageContentsExists").returns(Promise.resolve(true));
|
||||||
// malformed JSON on package
|
// malformed JSON on package
|
||||||
sandbox.stub(perms, "getPackageContents").returns(when.reject(new Error('package.json file is malformed')));
|
sandbox.stub(perms, "getPackageContents").returns(Promise.reject(new Error('package.json file is malformed')));
|
||||||
|
|
||||||
perms.read().then(function (readPerms) {
|
perms.read().then(function (readPerms) {
|
||||||
/*jshint unused:false*/
|
/*jshint unused:false*/
|
||||||
|
@ -480,9 +480,9 @@ describe('Apps', function () {
|
||||||
validGhostPackageJsonContents = validGhostPackageJson;
|
validGhostPackageJsonContents = validGhostPackageJson;
|
||||||
|
|
||||||
// package.json IS in this directory
|
// package.json IS in this directory
|
||||||
sandbox.stub(perms, "checkPackageContentsExists").returns(when.resolve(true));
|
sandbox.stub(perms, "checkPackageContentsExists").returns(Promise.resolve(true));
|
||||||
// valid ghost property on package
|
// valid ghost property on package
|
||||||
sandbox.stub(perms, "getPackageContents").returns(when.resolve(validGhostPackageJsonContents));
|
sandbox.stub(perms, "getPackageContents").returns(Promise.resolve(validGhostPackageJsonContents));
|
||||||
|
|
||||||
perms.read().then(function (readPerms) {
|
perms.read().then(function (readPerms) {
|
||||||
should.exist(readPerms);
|
should.exist(readPerms);
|
||||||
|
|
9
core/test/unit/bootstrap_spec.js
vendored
9
core/test/unit/bootstrap_spec.js
vendored
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
@ -62,13 +62,10 @@ describe('Bootstrap', function () {
|
||||||
|
|
||||||
it('creates the config file if one does not exist', function (done) {
|
it('creates the config file if one does not exist', function (done) {
|
||||||
|
|
||||||
var deferred = when.defer(),
|
|
||||||
// trick bootstrap into thinking that the config file doesn't exist yet
|
// trick bootstrap into thinking that the config file doesn't exist yet
|
||||||
existsStub = sandbox.stub(fs, 'exists', function (file, cb) { return cb(false); }),
|
var existsStub = sandbox.stub(fs, 'exists', function (file, cb) { return cb(false); }),
|
||||||
// create a method which will return a pre-resolved promise
|
// create a method which will return a pre-resolved promise
|
||||||
resolvedPromise = sandbox.stub().returns(deferred.promise);
|
resolvedPromise = sandbox.stub().returns(Promise.resolve());
|
||||||
|
|
||||||
deferred.resolve();
|
|
||||||
|
|
||||||
// ensure that the file creation is a stub, the tests shouldn't really create a file
|
// ensure that the file creation is a stub, the tests shouldn't really create a file
|
||||||
bootstrap.__set__('writeConfigFile', resolvedPromise);
|
bootstrap.__set__('writeConfigFile', resolvedPromise);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
|
@ -32,7 +32,7 @@ describe('Config', function () {
|
||||||
settings = {'read': function read() {}};
|
settings = {'read': function read() {}};
|
||||||
|
|
||||||
settingsStub = sandbox.stub(settings, 'read', function () {
|
settingsStub = sandbox.stub(settings, 'read', function () {
|
||||||
return when({ settings: [{value: 'casper'}] });
|
return Promise.resolve({ settings: [{value: 'casper'}] });
|
||||||
});
|
});
|
||||||
|
|
||||||
theme.update(settings, 'http://my-ghost-blog.com')
|
theme.update(settings, 'http://my-ghost-blog.com')
|
||||||
|
@ -270,7 +270,7 @@ describe('Config', function () {
|
||||||
it('should output correct url for post', function (done) {
|
it('should output correct url for post', function (done) {
|
||||||
var settings = {'read': function read() {}},
|
var settings = {'read': function read() {}},
|
||||||
settingsStub = sandbox.stub(settings, 'read', function () {
|
settingsStub = sandbox.stub(settings, 'read', function () {
|
||||||
return when({ settings: [{value: '/:slug/'}] });
|
return Promise.resolve({ settings: [{value: '/:slug/'}] });
|
||||||
}),
|
}),
|
||||||
/*jshint unused:false*/
|
/*jshint unused:false*/
|
||||||
testData = testUtils.DataGenerator.Content.posts[2],
|
testData = testUtils.DataGenerator.Content.posts[2],
|
||||||
|
@ -308,7 +308,7 @@ describe('Config', function () {
|
||||||
it('should output correct url for post with date permalink', function (done) {
|
it('should output correct url for post with date permalink', function (done) {
|
||||||
var settings = {'read': function read() {}},
|
var settings = {'read': function read() {}},
|
||||||
settingsStub = sandbox.stub(settings, 'read', function () {
|
settingsStub = sandbox.stub(settings, 'read', function () {
|
||||||
return when({ settings: [{value: '/:year/:month/:day/:slug/'}] });
|
return Promise.resolve({ settings: [{value: '/:year/:month/:day/:slug/'}] });
|
||||||
}),
|
}),
|
||||||
/*jshint unused:false*/
|
/*jshint unused:false*/
|
||||||
testData = testUtils.DataGenerator.Content.posts[2],
|
testData = testUtils.DataGenerator.Content.posts[2],
|
||||||
|
@ -349,7 +349,7 @@ describe('Config', function () {
|
||||||
it('should output correct url for page with date permalink', function (done) {
|
it('should output correct url for page with date permalink', function (done) {
|
||||||
var settings = {'read': function read() {}},
|
var settings = {'read': function read() {}},
|
||||||
settingsStub = sandbox.stub(settings, 'read', function () {
|
settingsStub = sandbox.stub(settings, 'read', function () {
|
||||||
return when({ settings: [{value: '/:year/:month/:day/:slug/'}] });
|
return Promise.resolve({ settings: [{value: '/:year/:month/:day/:slug/'}] });
|
||||||
}),
|
}),
|
||||||
/*jshint unused:false*/
|
/*jshint unused:false*/
|
||||||
testData = testUtils.DataGenerator.Content.posts[5],
|
testData = testUtils.DataGenerator.Content.posts[5],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*globals describe, after, before, beforeEach, afterEach, it*/
|
/*globals describe, after, before, beforeEach, afterEach, it*/
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
express = require('express'),
|
express = require('express'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
|
@ -181,9 +181,7 @@ describe('Error handling', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logs promise errors and redirects', function (done) {
|
it('logs promise errors and redirects', function (done) {
|
||||||
var def = when.defer(),
|
var req = null,
|
||||||
prom = def.promise,
|
|
||||||
req = null,
|
|
||||||
res = {
|
res = {
|
||||||
redirect: function () {
|
redirect: function () {
|
||||||
return;
|
return;
|
||||||
|
@ -192,11 +190,11 @@ describe('Error handling', function () {
|
||||||
redirectStub = sinon.stub(res, 'redirect');
|
redirectStub = sinon.stub(res, 'redirect');
|
||||||
|
|
||||||
// give environment a value that will console log
|
// give environment a value that will console log
|
||||||
prom.then(function () {
|
Promise.reject().then(function () {
|
||||||
throw new Error('Ran success handler');
|
throw new Error('Ran success handler');
|
||||||
}, errors.logErrorWithRedirect('test1', null, null, '/testurl', req, res));
|
}, errors.logErrorWithRedirect('test1', null, null, '/testurl', req, res));
|
||||||
|
|
||||||
prom.otherwise(function () {
|
Promise.reject().catch(function () {
|
||||||
logStub.calledWith('\nERROR:'.red, 'test1'.red).should.equal(true);
|
logStub.calledWith('\nERROR:'.red, 'test1'.red).should.equal(true);
|
||||||
logStub.restore();
|
logStub.restore();
|
||||||
|
|
||||||
|
@ -205,7 +203,6 @@ describe('Error handling', function () {
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
def.reject();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -85,7 +85,7 @@ describe('Filters', function () {
|
||||||
it('executes filters that return a promise', function (done) {
|
it('executes filters that return a promise', function (done) {
|
||||||
var filterName = 'testprioritypromise',
|
var filterName = 'testprioritypromise',
|
||||||
testFilterHandler1 = sinon.spy(function (args) {
|
testFilterHandler1 = sinon.spy(function (args) {
|
||||||
return when.promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
args.filter1 = true;
|
args.filter1 = true;
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ describe('Filters', function () {
|
||||||
return args;
|
return args;
|
||||||
}),
|
}),
|
||||||
testFilterHandler3 = sinon.spy(function (args) {
|
testFilterHandler3 = sinon.spy(function (args) {
|
||||||
return when.promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
args.filter3 = true;
|
args.filter3 = true;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ var assert = require('assert'),
|
||||||
moment = require('moment'),
|
moment = require('moment'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
|
@ -53,11 +53,11 @@ describe('Frontend Controller', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
sandbox.stub(api.posts, 'browse', function () {
|
sandbox.stub(api.posts, 'browse', function () {
|
||||||
return when({posts: {}, meta: {pagination: { pages: 3}}});
|
return Promise.resolve({posts: {}, meta: {pagination: { pages: 3}}});
|
||||||
});
|
});
|
||||||
|
|
||||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||||
apiSettingsStub.withArgs('postsPerPage').returns(when({
|
apiSettingsStub.withArgs('postsPerPage').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'postsPerPage',
|
'key': 'postsPerPage',
|
||||||
'value': 5
|
'value': 5
|
||||||
|
@ -156,7 +156,7 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
sandbox.stub(api.posts, 'browse', function () {
|
sandbox.stub(api.posts, 'browse', function () {
|
||||||
return when({
|
return Promise.resolve({
|
||||||
posts: [],
|
posts: [],
|
||||||
meta: {
|
meta: {
|
||||||
pagination: {
|
pagination: {
|
||||||
|
@ -169,14 +169,14 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||||
|
|
||||||
apiSettingsStub.withArgs(sinon.match.has('key', 'activeTheme')).returns(when({
|
apiSettingsStub.withArgs(sinon.match.has('key', 'activeTheme')).returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'activeTheme',
|
'key': 'activeTheme',
|
||||||
'value': 'casper'
|
'value': 'casper'
|
||||||
}]
|
}]
|
||||||
}));
|
}));
|
||||||
|
|
||||||
apiSettingsStub.withArgs('postsPerPage').returns(when({
|
apiSettingsStub.withArgs('postsPerPage').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'postsPerPage',
|
'key': 'postsPerPage',
|
||||||
'value': '10'
|
'value': '10'
|
||||||
|
@ -306,7 +306,7 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
sandbox.stub(api.posts, 'browse', function () {
|
sandbox.stub(api.posts, 'browse', function () {
|
||||||
return when({
|
return Promise.resolve({
|
||||||
posts: mockPosts,
|
posts: mockPosts,
|
||||||
meta: {
|
meta: {
|
||||||
pagination: {
|
pagination: {
|
||||||
|
@ -322,14 +322,14 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||||
|
|
||||||
apiSettingsStub.withArgs(sinon.match.has('key', 'activeTheme')).returns(when({
|
apiSettingsStub.withArgs(sinon.match.has('key', 'activeTheme')).returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'activeTheme',
|
'key': 'activeTheme',
|
||||||
'value': 'casper'
|
'value': 'casper'
|
||||||
}]
|
}]
|
||||||
}));
|
}));
|
||||||
|
|
||||||
apiSettingsStub.withArgs('postsPerPage').returns(when({
|
apiSettingsStub.withArgs('postsPerPage').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'postsPerPage',
|
'key': 'postsPerPage',
|
||||||
'value': '10'
|
'value': '10'
|
||||||
|
@ -355,7 +355,7 @@ describe('Frontend Controller', function () {
|
||||||
describe('custom tag template', function () {
|
describe('custom tag template', function () {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
key: 'permalinks',
|
key: 'permalinks',
|
||||||
value: '/tag/:slug/'
|
value: '/tag/:slug/'
|
||||||
|
@ -392,11 +392,11 @@ describe('Frontend Controller', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
sandbox.stub(api.posts, 'browse', function () {
|
sandbox.stub(api.posts, 'browse', function () {
|
||||||
return when({posts: {}, meta: {pagination: { pages: 3}}});
|
return Promise.resolve({posts: {}, meta: {pagination: { pages: 3}}});
|
||||||
});
|
});
|
||||||
|
|
||||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||||
apiSettingsStub.withArgs('postsPerPage').returns(when({
|
apiSettingsStub.withArgs('postsPerPage').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'postsPerPage',
|
'key': 'postsPerPage',
|
||||||
'value': 5
|
'value': 5
|
||||||
|
@ -542,14 +542,14 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
sandbox.stub(api.posts, 'read', function (args) {
|
sandbox.stub(api.posts, 'read', function (args) {
|
||||||
return when(_.find(mockPosts, function(mock) {
|
return Promise.resolve(_.find(mockPosts, function(mock) {
|
||||||
return mock.posts[0].slug === args.slug;
|
return mock.posts[0].slug === args.slug;
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||||
|
|
||||||
apiSettingsStub.withArgs(sinon.match.has('key', 'activeTheme')).returns(when({
|
apiSettingsStub.withArgs(sinon.match.has('key', 'activeTheme')).returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'activeTheme',
|
'key': 'activeTheme',
|
||||||
'value': 'casper'
|
'value': 'casper'
|
||||||
|
@ -577,7 +577,7 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
describe('custom page templates', function () {
|
describe('custom page templates', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
value: '/:slug/'
|
value: '/:slug/'
|
||||||
}]
|
}]
|
||||||
|
@ -602,7 +602,7 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
describe('permalink set to slug', function () {
|
describe('permalink set to slug', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
value: '/:slug/'
|
value: '/:slug/'
|
||||||
}]
|
}]
|
||||||
|
@ -674,7 +674,7 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
describe('permalink set to date', function () {
|
describe('permalink set to date', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
value: '/:year/:month/:day/:slug/'
|
value: '/:year/:month/:day/:slug/'
|
||||||
}]
|
}]
|
||||||
|
@ -747,7 +747,7 @@ describe('Frontend Controller', function () {
|
||||||
describe('post', function () {
|
describe('post', function () {
|
||||||
describe('permalink set to slug', function () {
|
describe('permalink set to slug', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
value: '/:slug'
|
value: '/:slug'
|
||||||
}]
|
}]
|
||||||
|
@ -821,7 +821,7 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
describe('permalink set to date', function () {
|
describe('permalink set to date', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
value: '/:year/:month/:day/:slug'
|
value: '/:year/:month/:day/:slug'
|
||||||
}]
|
}]
|
||||||
|
@ -912,7 +912,7 @@ describe('Frontend Controller', function () {
|
||||||
|
|
||||||
describe('permalink set to custom format', function () {
|
describe('permalink set to custom format', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
value: '/:year/:slug'
|
value: '/:year/:slug'
|
||||||
}]
|
}]
|
||||||
|
@ -1035,25 +1035,25 @@ describe('Frontend Controller', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
sandbox.stub(api.posts, 'browse', function () {
|
sandbox.stub(api.posts, 'browse', function () {
|
||||||
return when({posts: {}, meta: {pagination: { pages: 3}}});
|
return Promise.resolve({posts: {}, meta: {pagination: { pages: 3}}});
|
||||||
});
|
});
|
||||||
|
|
||||||
apiUsersStub = sandbox.stub(api.users, 'read').returns(when({}));
|
apiUsersStub = sandbox.stub(api.users, 'read').returns(Promise.resolve({}));
|
||||||
|
|
||||||
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
apiSettingsStub = sandbox.stub(api.settings, 'read');
|
||||||
apiSettingsStub.withArgs('title').returns(when({
|
apiSettingsStub.withArgs('title').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'title',
|
'key': 'title',
|
||||||
'value': 'Test'
|
'value': 'Test'
|
||||||
}]
|
}]
|
||||||
}));
|
}));
|
||||||
apiSettingsStub.withArgs('description').returns(when({
|
apiSettingsStub.withArgs('description').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'description',
|
'key': 'description',
|
||||||
'value': 'Some Text'
|
'value': 'Some Text'
|
||||||
}]
|
}]
|
||||||
}));
|
}));
|
||||||
apiSettingsStub.withArgs('permalinks').returns(when({
|
apiSettingsStub.withArgs('permalinks').returns(Promise.resolve({
|
||||||
settings: [{
|
settings: [{
|
||||||
'key': 'permalinks',
|
'key': 'permalinks',
|
||||||
'value': '/:slug/'
|
'value': '/:slug/'
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ describe('Mail', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
sandbox.stub(mailer, 'detectSendmail', function () {
|
sandbox.stub(mailer, 'detectSendmail', function () {
|
||||||
return when.resolve(fakeSendmail);
|
return Promise.resolve(fakeSendmail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ describe('Mail', function () {
|
||||||
it('should disable transport if config is empty & sendmail not found', function (done) {
|
it('should disable transport if config is empty & sendmail not found', function (done) {
|
||||||
overrideConfig({mail: {}});
|
overrideConfig({mail: {}});
|
||||||
mailer.detectSendmail.restore();
|
mailer.detectSendmail.restore();
|
||||||
sandbox.stub(mailer, 'detectSendmail', when.reject);
|
sandbox.stub(mailer, 'detectSendmail', Promise.reject);
|
||||||
mailer.init().then(function () {
|
mailer.init().then(function () {
|
||||||
should.not.exist(mailer.transport);
|
should.not.exist(mailer.transport);
|
||||||
done();
|
done();
|
||||||
|
@ -141,7 +141,7 @@ describe('Mail', function () {
|
||||||
|
|
||||||
it('should fail to send messages when no transport is set', function (done) {
|
it('should fail to send messages when no transport is set', function (done) {
|
||||||
mailer.detectSendmail.restore();
|
mailer.detectSendmail.restore();
|
||||||
sandbox.stub(mailer, 'detectSendmail', when.reject);
|
sandbox.stub(mailer, 'detectSendmail', Promise.reject);
|
||||||
mailer.init().then(function () {
|
mailer.init().then(function () {
|
||||||
mailer.send().then(function () {
|
mailer.send().then(function () {
|
||||||
should.fail();
|
should.fail();
|
||||||
|
@ -154,15 +154,15 @@ describe('Mail', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to send messages when given insufficient data', function (done) {
|
it('should fail to send messages when given insufficient data', function (done) {
|
||||||
when.settle([
|
Promise.settle([
|
||||||
mailer.send(),
|
mailer.send(),
|
||||||
mailer.send({}),
|
mailer.send({}),
|
||||||
mailer.send({ subject: '123' }),
|
mailer.send({ subject: '123' }),
|
||||||
mailer.send({ subject: '', html: '123' })
|
mailer.send({ subject: '', html: '123' })
|
||||||
]).then(function (descriptors) {
|
]).then(function (descriptors) {
|
||||||
descriptors.forEach(function (d) {
|
descriptors.forEach(function (d) {
|
||||||
d.state.should.equal('rejected');
|
d.isRejected().should.be.true;
|
||||||
d.reason.should.be.an.instanceOf(Error);
|
d.reason().should.be.an.instanceOf(Error);
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
var testUtils = require('../utils'),
|
var testUtils = require('../utils'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
|
|
||||||
// Stuff we are testing
|
// Stuff we are testing
|
||||||
|
@ -31,7 +31,7 @@ describe('Permissions', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
sandbox.stub(Models.Permission, 'findAll', function () {
|
sandbox.stub(Models.Permission, 'findAll', function () {
|
||||||
return when(Models.Permissions.forge(permissions));
|
return Promise.resolve(Models.Permissions.forge(permissions));
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -112,7 +112,7 @@ describe('Permissions', function () {
|
||||||
// it('can use permissible function on Model to allow something', function (done) {
|
// it('can use permissible function on Model to allow something', function (done) {
|
||||||
// var testUser,
|
// var testUser,
|
||||||
// permissibleStub = sandbox.stub(Models.Post, 'permissible', function () {
|
// permissibleStub = sandbox.stub(Models.Post, 'permissible', function () {
|
||||||
// return when.resolve();
|
// return Promise.resolve();
|
||||||
// });
|
// });
|
||||||
//
|
//
|
||||||
// testUtils.insertAuthorUser()
|
// testUtils.insertAuthorUser()
|
||||||
|
@ -141,7 +141,7 @@ describe('Permissions', function () {
|
||||||
// it('can use permissible function on Model to forbid something', function (done) {
|
// it('can use permissible function on Model to forbid something', function (done) {
|
||||||
// var testUser,
|
// var testUser,
|
||||||
// permissibleStub = sandbox.stub(Models.Post, 'permissible', function () {
|
// permissibleStub = sandbox.stub(Models.Post, 'permissible', function () {
|
||||||
// return when.reject();
|
// return Promise.reject();
|
||||||
// });
|
// });
|
||||||
//
|
//
|
||||||
// testUtils.insertAuthorUser()
|
// testUtils.insertAuthorUser()
|
||||||
|
@ -203,7 +203,7 @@ describe('Permissions', function () {
|
||||||
//
|
//
|
||||||
// return newPerm.save(null, context).then(function () {
|
// return newPerm.save(null, context).then(function () {
|
||||||
// return foundUser.permissions().attach(newPerm).then(function () {
|
// return foundUser.permissions().attach(newPerm).then(function () {
|
||||||
// return when.all([updatedPost, foundUser]);
|
// return Promise.all([updatedPost, foundUser]);
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/*jshint expr:true*/
|
/*jshint expr:true*/
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
rewire = require('rewire'),
|
rewire = require('rewire'),
|
||||||
moment = require('moment'),
|
moment = require('moment'),
|
||||||
|
@ -30,7 +30,7 @@ describe('Core Helpers', function () {
|
||||||
helpers = rewire('../../server/helpers');
|
helpers = rewire('../../server/helpers');
|
||||||
sandbox = sinon.sandbox.create();
|
sandbox = sinon.sandbox.create();
|
||||||
apiStub = sandbox.stub(api.settings, 'read', function () {
|
apiStub = sandbox.stub(api.settings, 'read', function () {
|
||||||
return when({
|
return Promise.resolve({
|
||||||
settings: [{value: 'casper'}]
|
settings: [{value: 'casper'}]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -393,7 +393,7 @@ describe('Core Helpers', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can render class string for context', function (done) {
|
it('can render class string for context', function (done) {
|
||||||
when.all([
|
Promise.all([
|
||||||
helpers.body_class.call({relativeUrl: '/'}),
|
helpers.body_class.call({relativeUrl: '/'}),
|
||||||
helpers.body_class.call({relativeUrl: '/a-post-title', post: {}}),
|
helpers.body_class.call({relativeUrl: '/a-post-title', post: {}}),
|
||||||
helpers.body_class.call({relativeUrl: '/page/4'}),
|
helpers.body_class.call({relativeUrl: '/page/4'}),
|
||||||
|
@ -762,7 +762,7 @@ describe('Core Helpers', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
apiStub.restore();
|
apiStub.restore();
|
||||||
apiStub = sandbox.stub(api.settings, 'read', function () {
|
apiStub = sandbox.stub(api.settings, 'read', function () {
|
||||||
return when({ settings: [{ value: '/:slug/' }] });
|
return Promise.resolve({ settings: [{ value: '/:slug/' }] });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ var nock = require('nock'),
|
||||||
should = require('should'),
|
should = require('should'),
|
||||||
sinon = require('sinon'),
|
sinon = require('sinon'),
|
||||||
testUtils = require('../utils'),
|
testUtils = require('../utils'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
xmlrpc = require('../../server/xmlrpc'),
|
xmlrpc = require('../../server/xmlrpc'),
|
||||||
// storing current environment
|
// storing current environment
|
||||||
currentEnv = process.env.NODE_ENV;
|
currentEnv = process.env.NODE_ENV;
|
||||||
|
@ -34,7 +34,7 @@ describe('XMLRPC', function () {
|
||||||
ping2 = nock('http://rpc.pingomatic.com').post('/').reply(200),
|
ping2 = nock('http://rpc.pingomatic.com').post('/').reply(200),
|
||||||
testPost = testUtils.DataGenerator.Content.posts[2],
|
testPost = testUtils.DataGenerator.Content.posts[2],
|
||||||
settingsStub = sandbox.stub(settings, 'read', function () {
|
settingsStub = sandbox.stub(settings, 'read', function () {
|
||||||
return when({ settings: [{value: '/:slug/'}] });
|
return Promise.resolve({ settings: [{value: '/:slug/'}] });
|
||||||
});
|
});
|
||||||
/*jshint unused:false */
|
/*jshint unused:false */
|
||||||
|
|
||||||
|
|
|
@ -3,33 +3,39 @@ var cp = require('child_process'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
url = require('url'),
|
url = require('url'),
|
||||||
net = require('net'),
|
net = require('net'),
|
||||||
when = require('when'),
|
Promise = require('bluebird'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
config = require('../../server/config');
|
config = require('../../server/config');
|
||||||
|
|
||||||
function findFreePort(port) {
|
function findFreePort(port) {
|
||||||
var deferred = when.defer();
|
return new Promise(function (resolve, reject) {
|
||||||
|
if (typeof port === 'string') {
|
||||||
if (typeof port === 'string') port = parseInt(port);
|
port = parseInt(port);
|
||||||
if (typeof port !== 'number') port = 2368;
|
|
||||||
port = port + 1;
|
|
||||||
|
|
||||||
var server = net.createServer();
|
|
||||||
server.on('error', function(e) {
|
|
||||||
if (e.code === 'EADDRINUSE') {
|
|
||||||
when.chain(findFreePort(port), deferred);
|
|
||||||
} else {
|
|
||||||
deferred.reject(e);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
server.listen(port, function() {
|
if (typeof port !== 'number') {
|
||||||
var listenPort = server.address().port;
|
port = 2368;
|
||||||
server.close(function() {
|
}
|
||||||
deferred.resolve(listenPort);
|
|
||||||
|
port = port + 1;
|
||||||
|
|
||||||
|
var server = net.createServer();
|
||||||
|
|
||||||
|
server.on('error', function(e) {
|
||||||
|
if (e.code === 'EADDRINUSE') {
|
||||||
|
resolve(findFreePort(port));
|
||||||
|
} else {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(port, function() {
|
||||||
|
var listenPort = server.address().port;
|
||||||
|
server.close(function() {
|
||||||
|
resolve(listenPort);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a copy of current config object from file, to be modified before
|
// Get a copy of current config object from file, to be modified before
|
||||||
|
@ -43,85 +49,87 @@ function forkConfig() {
|
||||||
// Creates a new fork of Ghost process with a given config
|
// Creates a new fork of Ghost process with a given config
|
||||||
// Useful for tests that want to verify certain config options
|
// Useful for tests that want to verify certain config options
|
||||||
function forkGhost(newConfig, envName) {
|
function forkGhost(newConfig, envName) {
|
||||||
var deferred = when.defer();
|
|
||||||
envName = envName || 'forked';
|
envName = envName || 'forked';
|
||||||
findFreePort(newConfig.server ? newConfig.server.port : undefined)
|
|
||||||
|
return findFreePort(newConfig.server ? newConfig.server.port : undefined)
|
||||||
.then(function(port) {
|
.then(function(port) {
|
||||||
newConfig.server = newConfig.server || {};
|
newConfig.server = newConfig.server || {};
|
||||||
newConfig.server.port = port;
|
newConfig.server.port = port;
|
||||||
newConfig.url = url.format(_.extend(url.parse(newConfig.url), {port: port, host: null}));
|
newConfig.url = url.format(_.extend(url.parse(newConfig.url), {port: port, host: null}));
|
||||||
|
|
||||||
var newConfigFile = path.join(config.paths.appRoot, 'config.test' + port + '.js');
|
var newConfigFile = path.join(config.paths.appRoot, 'config.test' + port + '.js');
|
||||||
fs.writeFile(newConfigFile, 'module.exports = {' + envName + ': ' + JSON.stringify(newConfig) + '}', function(err) {
|
|
||||||
if (err) throw err;
|
return new Promise(function (resolve, reject) {
|
||||||
|
fs.writeFile(newConfigFile, 'module.exports = {' + envName + ': ' + JSON.stringify(newConfig) + '}', function(err) {
|
||||||
// setup process environment for the forked Ghost to use the new config file
|
if (err) {
|
||||||
var env = _.clone(process.env);
|
return reject(err);
|
||||||
env['GHOST_CONFIG'] = newConfigFile;
|
|
||||||
env['NODE_ENV'] = envName;
|
|
||||||
var child = cp.fork(path.join(config.paths.appRoot, 'index.js'), {env: env});
|
|
||||||
|
|
||||||
var pingTries = 0;
|
|
||||||
var pingCheck;
|
|
||||||
var pingStop = function() {
|
|
||||||
if (pingCheck) {
|
|
||||||
clearInterval(pingCheck);
|
|
||||||
pingCheck = undefined;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
};
|
// setup process environment for the forked Ghost to use the new config file
|
||||||
// periodic check until forked Ghost is running and is listening on the port
|
var env = _.clone(process.env);
|
||||||
pingCheck = setInterval(function() {
|
env['GHOST_CONFIG'] = newConfigFile;
|
||||||
var socket = net.connect(port);
|
env['NODE_ENV'] = envName;
|
||||||
socket.on('connect', function() {
|
var child = cp.fork(path.join(config.paths.appRoot, 'index.js'), {env: env});
|
||||||
socket.end();
|
|
||||||
if (pingStop()) {
|
var pingTries = 0;
|
||||||
deferred.resolve(child);
|
var pingCheck;
|
||||||
|
var pingStop = function() {
|
||||||
|
if (pingCheck) {
|
||||||
|
clearInterval(pingCheck);
|
||||||
|
pingCheck = undefined;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
});
|
return false;
|
||||||
socket.on('error', function(err) {
|
};
|
||||||
// continue checking
|
// periodic check until forked Ghost is running and is listening on the port
|
||||||
if (++pingTries >= 20 && pingStop()) {
|
pingCheck = setInterval(function() {
|
||||||
deferred.reject(new Error("Timed out waiting for child process"));
|
var socket = net.connect(port);
|
||||||
}
|
socket.on('connect', function() {
|
||||||
});
|
socket.end();
|
||||||
}, 200);
|
if (pingStop()) {
|
||||||
|
resolve(child);
|
||||||
child.on('exit', function(code, signal) {
|
}
|
||||||
child.exited = true;
|
|
||||||
if (pingStop()) {
|
|
||||||
deferred.reject(new Error("Child process exit code: " + code));
|
|
||||||
}
|
|
||||||
// cleanup the temporary config file
|
|
||||||
fs.unlink(newConfigFile);
|
|
||||||
});
|
|
||||||
|
|
||||||
// override kill() to have an async callback
|
|
||||||
var baseKill = child.kill;
|
|
||||||
child.kill = function(signal, cb) {
|
|
||||||
if (typeof signal === 'function') {
|
|
||||||
cb = signal;
|
|
||||||
signal = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cb) {
|
|
||||||
child.on('exit', function() {
|
|
||||||
cb();
|
|
||||||
});
|
});
|
||||||
}
|
socket.on('error', function(err) {
|
||||||
|
// continue checking
|
||||||
|
if (++pingTries >= 20 && pingStop()) {
|
||||||
|
reject(new Error("Timed out waiting for child process"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 200);
|
||||||
|
|
||||||
if (child.exited) {
|
child.on('exit', function(code, signal) {
|
||||||
process.nextTick(cb);
|
child.exited = true;
|
||||||
} else {
|
if (pingStop()) {
|
||||||
baseKill.apply(child, [signal]);
|
reject(new Error("Child process exit code: " + code));
|
||||||
}
|
}
|
||||||
};
|
// cleanup the temporary config file
|
||||||
|
fs.unlink(newConfigFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
// override kill() to have an async callback
|
||||||
|
var baseKill = child.kill;
|
||||||
|
child.kill = function(signal, cb) {
|
||||||
|
if (typeof signal === 'function') {
|
||||||
|
cb = signal;
|
||||||
|
signal = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb) {
|
||||||
|
child.on('exit', function() {
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.exited) {
|
||||||
|
process.nextTick(cb);
|
||||||
|
} else {
|
||||||
|
baseKill.apply(child, [signal]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
.otherwise(deferred.reject);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.ghost = forkGhost;
|
module.exports.ghost = forkGhost;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
var when = require('when'),
|
var Promise = require('bluebird'),
|
||||||
sequence = require('when/sequence'),
|
sequence = require('../../server/utils/sequence'),
|
||||||
nodefn = require('when/node'),
|
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
fs = require('fs-extra'),
|
fs = require('fs-extra'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
|
@ -32,7 +31,7 @@ var when = require('when'),
|
||||||
fixtures = {
|
fixtures = {
|
||||||
insertPosts: function insertPosts() {
|
insertPosts: function insertPosts() {
|
||||||
var knex = config.database.knex;
|
var knex = config.database.knex;
|
||||||
return when(knex('posts').insert(DataGenerator.forKnex.posts)).then(function () {
|
return Promise.resolve(knex('posts').insert(DataGenerator.forKnex.posts)).then(function () {
|
||||||
return knex('tags').insert(DataGenerator.forKnex.tags);
|
return knex('tags').insert(DataGenerator.forKnex.tags);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return knex('posts_tags').insert(DataGenerator.forKnex.posts_tags);
|
return knex('posts_tags').insert(DataGenerator.forKnex.posts_tags);
|
||||||
|
@ -49,7 +48,7 @@ fixtures = {
|
||||||
|
|
||||||
max = max || 50;
|
max = max || 50;
|
||||||
// insert users of different roles
|
// insert users of different roles
|
||||||
return when(fixtures.createUsersWithRoles()).then(function (results) {
|
return Promise.resolve(fixtures.createUsersWithRoles()).then(function (results) {
|
||||||
// create the tags
|
// create the tags
|
||||||
return knex('tags').insert(DataGenerator.forKnex.tags);
|
return knex('tags').insert(DataGenerator.forKnex.tags);
|
||||||
}).then(function (results) {
|
}).then(function (results) {
|
||||||
|
@ -72,7 +71,7 @@ fixtures = {
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return when.all([
|
return Promise.all([
|
||||||
// PostgreSQL can return results in any order
|
// PostgreSQL can return results in any order
|
||||||
knex('posts').orderBy('id', 'asc').select('id'),
|
knex('posts').orderBy('id', 'asc').select('id'),
|
||||||
knex('tags').select('id')
|
knex('tags').select('id')
|
||||||
|
@ -84,7 +83,7 @@ fixtures = {
|
||||||
i;
|
i;
|
||||||
|
|
||||||
if (max > posts.length) {
|
if (max > posts.length) {
|
||||||
throw new Error('Trying to add more posts_tags than the number of posts.');
|
throw new Error('Trying to add more posts_tags than the number of posts. ' + max + ' ' + posts.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < max; i += 1) {
|
for (i = 0; i < max; i += 1) {
|
||||||
|
@ -133,7 +132,7 @@ fixtures = {
|
||||||
|
|
||||||
var knex = config.database.knex;
|
var knex = config.database.knex;
|
||||||
|
|
||||||
return when.all([
|
return Promise.all([
|
||||||
// PostgreSQL can return results in any order
|
// PostgreSQL can return results in any order
|
||||||
knex('posts').orderBy('id', 'asc').select('id'),
|
knex('posts').orderBy('id', 'asc').select('id'),
|
||||||
knex('tags').select('id', 'name')
|
knex('tags').select('id', 'name')
|
||||||
|
@ -268,16 +267,17 @@ fixtures = {
|
||||||
},
|
},
|
||||||
|
|
||||||
loadExportFixture: function loadExportFixture(filename) {
|
loadExportFixture: function loadExportFixture(filename) {
|
||||||
var filepath = path.resolve(__dirname + '/fixtures/' + filename + '.json');
|
var filepath = path.resolve(__dirname + '/fixtures/' + filename + '.json'),
|
||||||
|
readFile = Promise.promisify(fs.readFile);
|
||||||
|
|
||||||
return nodefn.call(fs.readFile, filepath).then(function (fileContents) {
|
return readFile(filepath).then(function (fileContents) {
|
||||||
var data;
|
var data;
|
||||||
|
|
||||||
// Parse the json data
|
// Parse the json data
|
||||||
try {
|
try {
|
||||||
data = JSON.parse(fileContents);
|
data = JSON.parse(fileContents);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return when.reject(new Error('Failed to parse the file'));
|
return new Error('Failed to parse the file');
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -451,7 +451,6 @@ setup = function setup() {
|
||||||
// TODO make this do the DB init as well
|
// TODO make this do the DB init as well
|
||||||
doAuth = function doAuth() {
|
doAuth = function doAuth() {
|
||||||
var options = arguments,
|
var options = arguments,
|
||||||
deferred = when.defer(),
|
|
||||||
request = arguments[0],
|
request = arguments[0],
|
||||||
user = DataGenerator.forModel.users[0],
|
user = DataGenerator.forModel.users[0],
|
||||||
fixtureOps;
|
fixtureOps;
|
||||||
|
@ -466,19 +465,19 @@ doAuth = function doAuth() {
|
||||||
|
|
||||||
fixtureOps = getFixtureOps(options);
|
fixtureOps = getFixtureOps(options);
|
||||||
|
|
||||||
sequence(fixtureOps).then(function () {
|
return new Promise(function (resolve, reject) {
|
||||||
request.post('/ghost/api/v0.1/authentication/token/')
|
return sequence(fixtureOps).then(function () {
|
||||||
.send({ grant_type: 'password', username: user.email, password: user.password, client_id: 'ghost-admin'})
|
request.post('/ghost/api/v0.1/authentication/token/')
|
||||||
.end(function (err, res) {
|
.send({ grant_type: 'password', username: user.email, password: user.password, client_id: 'ghost-admin'})
|
||||||
if (err) {
|
.end(function (err, res) {
|
||||||
deferred.reject(err);
|
if (err) {
|
||||||
}
|
return reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
deferred.resolve(res.body.access_token);
|
resolve(res.body.access_token);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
teardown = function teardown(done) {
|
teardown = function teardown(done) {
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
"engineStrict": true,
|
"engineStrict": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcryptjs": "0.7.10",
|
"bcryptjs": "0.7.10",
|
||||||
|
"bluebird": "2.3.0",
|
||||||
"body-parser": "1.6.3",
|
"body-parser": "1.6.3",
|
||||||
"bookshelf": "0.7.6",
|
"bookshelf": "0.7.6",
|
||||||
"busboy": "0.2.3",
|
"busboy": "0.2.3",
|
||||||
|
@ -63,7 +64,6 @@
|
||||||
"static-favicon": "1.0.2",
|
"static-favicon": "1.0.2",
|
||||||
"unidecode": "0.1.3",
|
"unidecode": "0.1.3",
|
||||||
"validator": "3.4.0",
|
"validator": "3.4.0",
|
||||||
"when": "3.2.3",
|
|
||||||
"xml": "0.0.12"
|
"xml": "0.0.12"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
|
Loading…
Reference in a new issue