mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-14 09:52:09 +03:00
071f9769c6
Closes #282 * Added a new route * Added new methods * Triple security! * Passwords are actually changed * Also added a change password button, because 'save' has too much baggage. On security: checks whether you're logged in. Then checks whether your old password is actually the one that belongs to you (gets value from the email field for the email, see caveat no2). Checks the new passwords for === and length > 6 on client and server side as well. And THEN changes passwords. Caveats: * didn't add a test, as mocha fails spectacularly on my machine. SQLITE_CORRUPT: database disk image is malformed. Cute, huh? * Because we don't have / I'm not aware of / could not find a "currentuser" variable, I need to get the email address of the user we want to change from the email field. Theoretically if they replace that with another user's email address, and supply their pw, they will change THEIR password instead of their own.
202 lines
6.0 KiB
JavaScript
202 lines
6.0 KiB
JavaScript
// # Ghost Data API
|
|
// Provides access to the data model
|
|
|
|
/**
|
|
* This is intended to replace the old dataProvider files and should access & manipulate the models directly
|
|
*/
|
|
var Ghost = require('../ghost'),
|
|
_ = require('underscore'),
|
|
when = require('when'),
|
|
errors = require('./errorHandling'),
|
|
|
|
ghost = new Ghost(),
|
|
dataProvider = ghost.dataProvider,
|
|
posts,
|
|
users,
|
|
notifications,
|
|
settings,
|
|
requestHandler,
|
|
cachedSettingsRequestHandler,
|
|
settingsObject,
|
|
settingsCollection;
|
|
|
|
// # Posts
|
|
posts = {
|
|
// takes filter / pagination parameters
|
|
// returns a page of posts in a json response
|
|
browse: function browse(options) {
|
|
return dataProvider.Post.findPage(options);
|
|
},
|
|
// takes an identifier (id or slug?)
|
|
// returns a single post in a json response
|
|
read: function read(args) {
|
|
return dataProvider.Post.findOne(args);
|
|
},
|
|
// takes a json object with all the properties which should be updated
|
|
// returns the resulting post in a json response
|
|
edit: function edit(postData) {
|
|
return dataProvider.Post.edit(postData);
|
|
},
|
|
// takes a json object representing a post,
|
|
// returns the resulting post in a json response
|
|
add: function add(postData) {
|
|
return dataProvider.Post.add(postData);
|
|
},
|
|
// takes an identifier (id or slug?)
|
|
// returns a json response with the id of the deleted post
|
|
destroy: function destroy(args) {
|
|
return dataProvider.Post.destroy(args.id);
|
|
}
|
|
};
|
|
|
|
// # Users
|
|
users = {
|
|
browse: function browse(options) {
|
|
return dataProvider.User.browse(options);
|
|
},
|
|
read: function read(args) {
|
|
return dataProvider.User.read(args);
|
|
},
|
|
edit: function edit(postData) {
|
|
return dataProvider.User.edit(postData);
|
|
},
|
|
add: function add(postData) {
|
|
return dataProvider.User.add(postData);
|
|
},
|
|
check: function check(postData) {
|
|
return dataProvider.User.check(postData);
|
|
},
|
|
changePassword: function changePassword(postData) {
|
|
return dataProvider.User.changePassword(postData);
|
|
}
|
|
};
|
|
|
|
// # Notifications
|
|
|
|
notifications = {
|
|
destroy: function destroy(i) {
|
|
ghost.notifications = _.reject(ghost.notifications, function (element) {
|
|
return element.id === i.id;
|
|
});
|
|
return when(ghost.notifications);
|
|
},
|
|
add: function add(notification) {
|
|
return when(ghost.notifications.push(notification));
|
|
}
|
|
};
|
|
|
|
// # Settings
|
|
|
|
// Turn a settings collection into a single object/hashmap
|
|
settingsObject = function (settings) {
|
|
return (settings.toJSON ? settings.toJSON() : settings).reduce(function (res, item) {
|
|
if (item.toJSON) { item = item.toJSON(); }
|
|
if (item.key) { res[item.key] = item.value; }
|
|
return res;
|
|
}, {});
|
|
};
|
|
// Turn an object into a collection
|
|
settingsCollection = function (settings) {
|
|
return _.map(settings, function (value, key) {
|
|
return { key: key, value: value };
|
|
});
|
|
};
|
|
|
|
settings = {
|
|
browse: function browse(options) {
|
|
return dataProvider.Settings.browse(options).then(settingsObject, errors.logAndThrowError);
|
|
},
|
|
read: function read(options) {
|
|
if (_.isString(options)) {
|
|
options = { key: options };
|
|
}
|
|
|
|
return dataProvider.Settings.read(options.key).then(function (setting) {
|
|
if (!setting) {
|
|
return when.reject("Unable to find setting: " + options.key);
|
|
}
|
|
|
|
return _.pick(setting.toJSON(), 'key', 'value');
|
|
}, errors.logAndThrowError);
|
|
},
|
|
edit: function edit(key, value) {
|
|
// Check for passing a collection of settings first
|
|
if (_.isObject(key)) {
|
|
key = settingsCollection(key);
|
|
return dataProvider.Settings.edit(key).then(settingsObject, errors.logAndThrowError);
|
|
}
|
|
|
|
return dataProvider.Settings.read(key).then(function (setting) {
|
|
if (!setting) {
|
|
return when.reject("Unable to find setting: " + key);
|
|
}
|
|
|
|
if (!_.isString(value)) {
|
|
value = JSON.stringify(value);
|
|
}
|
|
|
|
setting.set('value', value);
|
|
|
|
return dataProvider.Settings.edit(setting);
|
|
}, errors.logAndThrowError);
|
|
}
|
|
};
|
|
|
|
// categories: {};
|
|
// post_categories: {};
|
|
|
|
|
|
// requestHandler
|
|
// decorator for api functions which are called via an HTTP request
|
|
// takes the API method and wraps it so that it gets data from the request and returns a sensible JSON response
|
|
requestHandler = function (apiMethod) {
|
|
return function (req, res) {
|
|
var options = _.extend(req.body, req.query, req.params);
|
|
return apiMethod(options).then(function (result) {
|
|
res.json(result || {});
|
|
}, function (error) {
|
|
res.json(400, {error: error});
|
|
});
|
|
};
|
|
};
|
|
|
|
cachedSettingsRequestHandler = function (apiMethod) {
|
|
if (!ghost.settings()) {
|
|
return requestHandler(apiMethod);
|
|
}
|
|
|
|
return function (req, res) {
|
|
var options = _.extend(req.body, req.query, req.params),
|
|
promise;
|
|
|
|
switch (apiMethod.name) {
|
|
case 'browse':
|
|
promise = when(ghost.settings());
|
|
break;
|
|
case 'read':
|
|
promise = when(ghost.settings()[options.key]);
|
|
break;
|
|
case 'edit':
|
|
promise = apiMethod(options).then(function (result) {
|
|
ghost.updateSettingsCache(result);
|
|
return result;
|
|
});
|
|
break;
|
|
default:
|
|
errors.logAndThrowError(new Error('Unknown method name for settings API: ' + apiMethod.name));
|
|
}
|
|
return promise.then(function (result) {
|
|
res.json(result || {});
|
|
}, function (error) {
|
|
res.json(400, {error: error});
|
|
});
|
|
};
|
|
};
|
|
|
|
module.exports.posts = posts;
|
|
module.exports.users = users;
|
|
module.exports.notifications = notifications;
|
|
module.exports.settings = settings;
|
|
module.exports.requestHandler = requestHandler;
|
|
module.exports.cachedSettingsRequestHandler = cachedSettingsRequestHandler;
|