0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-15 03:01:37 -05:00

Misc cleanup: moving files & naming functions

This commit is contained in:
Hannah Wolfe 2015-06-14 16:58:49 +01:00
parent 78157078f8
commit 177cdf1eb1
14 changed files with 232 additions and 232 deletions

View file

@ -1,5 +1,5 @@
var ghostBookshelf = require('./base'),
Basetoken = require('./basetoken'),
Basetoken = require('./base/token'),
Accesstoken,
Accesstokens;

View file

@ -5,7 +5,7 @@ var ghostBookshelf = require('./base'),
AppField = ghostBookshelf.Model.extend({
tableName: 'app_fields',
post: function () {
post: function post() {
return this.morphOne('Post', 'relatable');
}
});

View file

@ -5,7 +5,7 @@ var ghostBookshelf = require('./base'),
AppSetting = ghostBookshelf.Model.extend({
tableName: 'app_settings',
app: function () {
app: function app() {
return this.belongsTo('App');
}
});

View file

@ -5,7 +5,7 @@ var ghostBookshelf = require('./base'),
App = ghostBookshelf.Model.extend({
tableName: 'apps',
saving: function (newPage, attr, options) {
saving: function saving(newPage, attr, options) {
/*jshint unused:false*/
var self = this;
@ -15,17 +15,17 @@ App = ghostBookshelf.Model.extend({
// Pass the new slug through the generator to strip illegal characters, detect duplicates
return ghostBookshelf.Model.generateSlug(App, this.get('slug') || this.get('name'),
{transacting: options.transacting})
.then(function (slug) {
.then(function then(slug) {
self.set({slug: slug});
});
}
},
permissions: function () {
permissions: function permissions() {
return this.belongsToMany('Permission', 'permissions_apps');
},
settings: function () {
settings: function settings() {
return this.belongsToMany('AppSetting', 'app_settings');
}
}, {
@ -34,7 +34,7 @@ App = ghostBookshelf.Model.extend({
* @param {String} methodName The name of the method to check valid options for.
* @return {Array} Keys allowed in the `options` hash of the model's method.
*/
permittedOptions: function (methodName) {
permittedOptions: function permittedOptions(methodName) {
var options = ghostBookshelf.Model.permittedOptions(),
// whitelists for the `options` hash argument on methods, by method name.

View file

@ -7,16 +7,16 @@
// allowed to access data via the API.
var _ = require('lodash'),
bookshelf = require('bookshelf'),
config = require('../config'),
errors = require('../errors'),
filters = require('../filters'),
config = require('../../config'),
errors = require('../../errors'),
filters = require('../../filters'),
moment = require('moment'),
Promise = require('bluebird'),
sanitize = require('validator').sanitize,
schema = require('../data/schema'),
utils = require('../utils'),
sanitizer = require('validator').sanitize,
schema = require('../../data/schema'),
utils = require('../../utils'),
uuid = require('node-uuid'),
validation = require('../data/validation'),
validation = require('../../data/validation'),
ghostBookshelf;
@ -35,17 +35,17 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
hasTimestamps: true,
// Get permitted attributes from server/data/schema.js, which is where the DB schema is defined
permittedAttributes: function () {
permittedAttributes: function permittedAttributes() {
return _.keys(schema.tables[this.tableName]);
},
defaults: function () {
defaults: function defaults() {
return {
uuid: uuid.v4()
};
},
initialize: function () {
initialize: function initialize() {
var self = this,
options = arguments[1] || {};
@ -55,24 +55,24 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
}
this.on('creating', this.creating, this);
this.on('saving', function (model, attributes, options) {
return Promise.resolve(self.saving(model, attributes, options)).then(function () {
this.on('saving', function onSaving(model, attributes, options) {
return Promise.resolve(self.saving(model, attributes, options)).then(function then() {
return self.validate(model, attributes, options);
});
});
},
validate: function () {
validate: function validate() {
return validation.validateSchema(this.tableName, this.toJSON());
},
creating: function (newObj, attr, options) {
creating: function creating(newObj, attr, options) {
if (!this.get('created_by')) {
this.set('created_by', this.contextUser(options));
}
},
saving: function (newObj, attr, options) {
saving: function saving(newObj, attr, options) {
// Remove any properties which don't belong on the model
this.attributes = this.pick(this.permittedAttributes());
// Store the previous attributes so we can tell what was updated later
@ -83,10 +83,10 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
// Base prototype properties will go here
// Fix problems with dates
fixDates: function (attrs) {
fixDates: function fixDates(attrs) {
var self = this;
_.each(attrs, function (value, key) {
_.each(attrs, function each(value, key) {
if (value !== null
&& schema.tables[self.tableName].hasOwnProperty(key)
&& schema.tables[self.tableName][key].type === 'dateTime') {
@ -99,9 +99,9 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
},
// Convert integers to real booleans
fixBools: function (attrs) {
fixBools: function fixBools(attrs) {
var self = this;
_.each(attrs, function (value, key) {
_.each(attrs, function each(value, key) {
if (schema.tables[self.tableName].hasOwnProperty(key)
&& schema.tables[self.tableName][key].type === 'bool') {
attrs[key] = value ? true : false;
@ -112,7 +112,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
},
// Get the user from the options object
contextUser: function (options) {
contextUser: function contextUser(options) {
// Default to context user
if (options.context && options.context.user) {
return options.context.user;
@ -125,16 +125,16 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
},
// format date before writing to DB, bools work
format: function (attrs) {
format: function format(attrs) {
return this.fixDates(attrs);
},
// format data and bool when fetching from DB
parse: function (attrs) {
parse: function parse(attrs) {
return this.fixBools(this.fixDates(attrs));
},
toJSON: function (options) {
toJSON: function toJSON(options) {
var attrs = _.extend({}, this.attributes),
self = this;
options = options || {};
@ -148,7 +148,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
this.include = _.union(this.include, options.include);
}
_.each(this.relations, function (relation, key) {
_.each(this.relations, function each(relation, key) {
if (key.substring(0, 7) !== '_pivot_') {
// if include is set, expand to full object
var fullKey = _.isEmpty(options.baseKey) ? key : options.baseKey + '.' + key;
@ -161,17 +161,17 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
return attrs;
},
sanitize: function (attr) {
return sanitize(this.get(attr)).xss();
sanitize: function sanitize(attr) {
return sanitizer(this.get(attr)).xss();
},
// Get attributes that have been updated (values before a .save() call)
updatedAttributes: function () {
updatedAttributes: function updatedAttributes() {
return this._updatedAttributes || {};
},
// Get a specific updated attribute value
updated: function (attr) {
updated: function updated(attr) {
return this.updatedAttributes()[attr];
}
@ -183,7 +183,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* Can be overridden and added to by a model's `permittedOptions` method.
* @return {Array} Keys allowed in the `options` hash of every model's method.
*/
permittedOptions: function () {
permittedOptions: function permittedOptions() {
// terms to whitelist for all methods.
return ['context', 'include', 'transacting'];
},
@ -193,7 +193,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {Object} data Has keys representing the model's attributes/fields in the database.
* @return {Object} The filtered results of the passed in data, containing only what's allowed in the schema.
*/
filterData: function (data) {
filterData: function filterData(data) {
var permittedAttributes = this.prototype.permittedAttributes(),
filteredData = _.pick(data, permittedAttributes);
@ -206,7 +206,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {String} methodName The name of the method to check valid options for.
* @return {Object} The filtered results of `options`.
*/
filterOptions: function (options, methodName) {
filterOptions: function filterOptions(options, methodName) {
var permittedOptions = this.permittedOptions(methodName),
filteredOptions = _.pick(options, permittedOptions);
@ -221,11 +221,11 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {Object} options (optional)
* @return {Promise(ghostBookshelf.Collection)} Collection of all Models
*/
findAll: function (options) {
findAll: function findAll(options) {
options = this.filterOptions(options, 'findAll');
return ghostBookshelf.Collection.forge([], {model: this}).fetch(options).then(function (result) {
return ghostBookshelf.Collection.forge([], {model: this}).fetch(options).then(function then(result) {
if (options.include) {
_.each(result.models, function (item) {
_.each(result.models, function each(item) {
item.include = options.include;
});
}
@ -240,7 +240,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {Object} options (optional)
* @return {Promise(ghostBookshelf.Model)} Single Model
*/
findOne: function (data, options) {
findOne: function findOne(data, options) {
data = this.filterData(data);
options = this.filterOptions(options, 'findOne');
// We pass include to forge so that toJSON has access
@ -254,12 +254,12 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {Object} options (optional)
* @return {Promise(ghostBookshelf.Model)} Edited Model
*/
edit: function (data, options) {
edit: function edit(data, options) {
var id = options.id;
data = this.filterData(data);
options = this.filterOptions(options, 'edit');
return this.forge({id: id}).fetch(options).then(function (object) {
return this.forge({id: id}).fetch(options).then(function then(object) {
if (object) {
return object.save(data, options);
}
@ -273,7 +273,7 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {Object} options (optional)
* @return {Promise(ghostBookshelf.Model)} Newly Added Model
*/
add: function (data, options) {
add: function add(data, options) {
data = this.filterData(data);
options = this.filterOptions(options, 'add');
var model = this.forge(data);
@ -291,12 +291,12 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {Object} options (optional)
* @return {Promise(ghostBookshelf.Model)} Empty Model
*/
destroy: function (options) {
destroy: function destroy(options) {
var id = options.id;
options = this.filterOptions(options, 'destroy');
// Fetch the object before destroying it, so that the changed data is available to events
return this.forge({id: id}).fetch(options).then(function (obj) {
return this.forge({id: id}).fetch(options).then(function then(obj) {
return obj.destroy(options);
});
},
@ -309,20 +309,20 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
* @param {Object} options Options to pass to findOne
* @return {Promise(String)} Resolves to a unique slug string
*/
generateSlug: function (Model, base, options) {
generateSlug: function generateSlug(Model, base, options) {
var slug,
slugTryCount = 1,
baseName = Model.prototype.tableName.replace(/s$/, ''),
// Look for a matching slug, append an incrementing number if so
checkIfSlugExists, longSlug;
checkIfSlugExists = function (slugToFind) {
checkIfSlugExists = function checkIfSlugExists(slugToFind) {
var args = {slug: slugToFind};
// status is needed for posts
if (options && options.status) {
args.status = options.status;
}
return Model.findOne(args, options).then(function (found) {
return Model.findOne(args, options).then(function then(found) {
var trimSpace;
if (!found) {
@ -363,12 +363,12 @@ ghostBookshelf.Model = ghostBookshelf.Model.extend({
}
// Check the filtered slug doesn't match any of the reserved keywords
return filters.doFilter('slug.reservedSlugs', config.slugs.reserved).then(function (slugList) {
return filters.doFilter('slug.reservedSlugs', config.slugs.reserved).then(function then(slugList) {
// Some keywords cannot be changed
slugList = _.union(slugList, config.slugs.protected);
return _.contains(slugList, slug) ? slug + '-' + baseName : slug;
}).then(function (slug) {
}).then(function then(slug) {
// if slug is empty after trimming use the model name
if (!slug) {
slug = baseName;

View file

@ -1,40 +1,40 @@
var Promise = require('bluebird'),
ghostBookshelf = require('./base'),
errors = require('../errors'),
ghostBookshelf = require('./index'),
errors = require('../../errors'),
Basetoken;
Basetoken = ghostBookshelf.Model.extend({
user: function () {
user: function user() {
return this.belongsTo('User');
},
client: function () {
client: function client() {
return this.belongsTo('Client');
},
// override for base function since we don't have
// a created_by field for sessions
creating: function (newObj, attr, options) {
creating: function creating(newObj, attr, options) {
/*jshint unused:false*/
},
// override for base function since we don't have
// a updated_by field for sessions
saving: function (newObj, attr, options) {
saving: function saving(newObj, attr, options) {
/*jshint unused:false*/
// Remove any properties which don't belong on the model
this.attributes = this.pick(this.permittedAttributes());
}
}, {
destroyAllExpired: function (options) {
destroyAllExpired: function destroyAllExpired(options) {
options = this.filterOptions(options, 'destroyAll');
return ghostBookshelf.Collection.forge([], {model: this})
.query('where', 'expires', '<', Date.now())
.fetch(options)
.then(function (collection) {
.then(function then(collection) {
collection.invokeThen('destroy', options);
});
},
@ -42,7 +42,7 @@ Basetoken = ghostBookshelf.Model.extend({
* ### destroyByUser
* @param {[type]} options has context and id. Context is the user doing the destroy, id is the user to destroy
*/
destroyByUser: function (options) {
destroyByUser: function destroyByUser(options) {
var userId = options.id;
options = this.filterOptions(options, 'destroyByUser');
@ -51,7 +51,7 @@ Basetoken = ghostBookshelf.Model.extend({
return ghostBookshelf.Collection.forge([], {model: this})
.query('where', 'user_id', '=', userId)
.fetch(options)
.then(function (collection) {
.then(function then(collection) {
collection.invokeThen('destroy', options);
});
}
@ -63,7 +63,7 @@ Basetoken = ghostBookshelf.Model.extend({
* ### destroyByToken
* @param {[type]} options has token where token is the token to destroy
*/
destroyByToken: function (options) {
destroyByToken: function destroyByToken(options) {
var token = options.token;
options = this.filterOptions(options, 'destroyByUser');
@ -72,7 +72,7 @@ Basetoken = ghostBookshelf.Model.extend({
return ghostBookshelf.Collection.forge([], {model: this})
.query('where', 'token', '=', token)
.fetch(options)
.then(function (collection) {
.then(function then(collection) {
collection.invokeThen('destroy', options);
});
}

View file

@ -4,7 +4,7 @@ var _ = require('lodash'),
models;
models = {
excludeFiles: ['_messages', 'basetoken.js', 'base.js', 'index.js'],
excludeFiles: ['_messages', 'base', 'index.js'],
// ### init
// Scan all files in this directory and then require each one and cache
@ -12,17 +12,17 @@ models = {
// module can safely access models without fear of introducing circular
// dependency issues.
// @returns {Promise}
init: function () {
init: function init() {
var self = this;
// One off inclusion of Base file.
self.Base = require('./base');
// Require all files in this directory
return requireTree.readAll(__dirname, {followSymlinks: false}).then(function (modelFiles) {
return requireTree.readAll(__dirname, {followSymlinks: false}).then(function then(modelFiles) {
// For each found file, excluding those we don't want,
// we will require it and cache it here.
_.each(modelFiles, function (path, fileName) {
_.each(modelFiles, function each(path, fileName) {
// Return early if this fileName is one of the ones we want
// to exclude.
if (_.contains(self.excludeFiles, fileName)) {
@ -41,16 +41,16 @@ models = {
},
// ### deleteAllContent
// Delete all content from the database (posts, tags, tags_posts)
deleteAllContent: function () {
deleteAllContent: function deleteAllContent() {
var self = this;
return self.Post.findAll().then(function (posts) {
return Promise.all(_.map(posts.toJSON(), function (post) {
return self.Post.findAll().then(function then(posts) {
return Promise.all(_.map(posts.toJSON(), function mapper(post) {
return self.Post.destroy({id: post.id});
}));
}).then(function () {
return self.Tag.findAll().then(function (tags) {
return Promise.all(_.map(tags.toJSON(), function (tag) {
return self.Tag.findAll().then(function then(tags) {
return Promise.all(_.map(tags.toJSON(), function mapper(tag) {
return self.Tag.destroy({id: tag.id});
}));
});

View file

@ -7,15 +7,15 @@ Permission = ghostBookshelf.Model.extend({
tableName: 'permissions',
roles: function () {
roles: function roles() {
return this.belongsToMany('Role');
},
users: function () {
users: function users() {
return this.belongsToMany('User');
},
apps: function () {
apps: function apps() {
return this.belongsToMany('App');
}
});

View file

@ -17,14 +17,14 @@ var _ = require('lodash'),
// Stores model permalink format
getPermalinkSetting = function (model, attributes, options) {
getPermalinkSetting = function getPermalinkSetting(model, attributes, options) {
/*jshint unused:false*/
// Transactions are used for bulk deletes and imports which don't need this anyway
if (options.transacting) {
return Promise.resolve();
}
return ghostBookshelf.model('Settings').findOne({key: 'permalinks'}).then(function (response) {
return ghostBookshelf.model('Settings').findOne({key: 'permalinks'}).then(function then(response) {
if (response) {
response = response.toJSON(options);
permalinkSetting = response.hasOwnProperty('value') ? response.value : '';
@ -36,7 +36,7 @@ Post = ghostBookshelf.Model.extend({
tableName: 'posts',
emitChange: function (event, usePreviousResourceType) {
emitChange: function emitChange(event, usePreviousResourceType) {
var resourceType = this.get('page') ? 'page' : 'post';
if (usePreviousResourceType) {
resourceType = this.updated('page') ? 'page' : 'post';
@ -44,26 +44,26 @@ Post = ghostBookshelf.Model.extend({
events.emit(resourceType + '.' + event, this);
},
defaults: function () {
defaults: function defaults() {
return {
uuid: uuid.v4(),
status: 'draft'
};
},
initialize: function () {
initialize: function initialize() {
var self = this;
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('saved', function (model, response, options) {
this.on('saved', function onSaved(model, response, options) {
return self.updateTags(model, response, options);
});
// Ensures local copy of permalink setting is kept up to date
this.on('fetching', getPermalinkSetting);
this.on('created', function (model) {
this.on('created', function onCreated(model) {
model.emitChange('added');
if (model.get('status') === 'published') {
@ -71,7 +71,7 @@ Post = ghostBookshelf.Model.extend({
}
});
this.on('updated', function (model) {
this.on('updated', function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isPublished = model.get('status') === 'published';
model.wasPublished = model.updated('status') === 'published';
@ -103,7 +103,7 @@ Post = ghostBookshelf.Model.extend({
}
});
this.on('destroyed', function (model) {
this.on('destroyed', function onDestroyed(model) {
if (model.previous('status') === 'published') {
model.emitChange('unpublished');
}
@ -112,7 +112,7 @@ Post = ghostBookshelf.Model.extend({
});
},
saving: function (model, attr, options) {
saving: function saving(model, attr, options) {
var self = this,
tagsToCheck,
i;
@ -122,7 +122,7 @@ Post = ghostBookshelf.Model.extend({
tagsToCheck = this.get('tags');
this.myTags = [];
_.each(tagsToCheck, function (item) {
_.each(tagsToCheck, function each(item) {
for (i = 0; i < self.myTags.length; i = i + 1) {
if (self.myTags[i].name.toLocaleLowerCase() === item.name.toLocaleLowerCase()) {
return;
@ -155,13 +155,13 @@ Post = ghostBookshelf.Model.extend({
// Pass the new slug through the generator to strip illegal characters, detect duplicates
return ghostBookshelf.Model.generateSlug(Post, this.get('slug') || this.get('title'),
{status: 'all', transacting: options.transacting})
.then(function (slug) {
.then(function then(slug) {
self.set({slug: slug});
});
}
},
creating: function (model, attr, options) {
creating: function creating(model, attr, options) {
options = options || {};
// set any dynamic default properties
@ -180,7 +180,7 @@ Post = ghostBookshelf.Model.extend({
* @param {Object} options
* @return {Promise(ghostBookshelf.Models.Post)} Updated Post model
*/
updateTags: function (savedModel, response, options) {
updateTags: function updateTags(savedModel, response, options) {
var self = this;
options = options || {};
@ -188,7 +188,7 @@ Post = ghostBookshelf.Model.extend({
return;
}
return Post.forge({id: savedModel.id}).fetch({withRelated: ['tags'], transacting: options.transacting}).then(function (post) {
return Post.forge({id: savedModel.id}).fetch({withRelated: ['tags'], transacting: options.transacting}).then(function then(post) {
var tagOps = [];
// remove all existing tags from the post
@ -200,7 +200,7 @@ Post = ghostBookshelf.Model.extend({
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 then(existingTags) {
var doNotExist = [],
sequenceTasks = [];
@ -214,8 +214,8 @@ Post = ghostBookshelf.Model.extend({
// Create tags that don't exist and attach to post
_.each(doNotExist, function (tag) {
var createAndAttachOperation = function () {
return ghostBookshelf.model('Tag').add({name: tag.name}, options).then(function (createdTag) {
var createAndAttachOperation = function createAndAttachOperation() {
return ghostBookshelf.model('Tag').add({name: tag.name}, options).then(function then(createdTag) {
// _.omit(options, 'query') is a fix for using bookshelf 0.6.8
// (https://github.com/tgriesser/bookshelf/issues/294)
return post.tags().attach(createdTag.id, _.omit(options, 'query'));
@ -240,31 +240,31 @@ Post = ghostBookshelf.Model.extend({
},
// Relations
author_id: function () {
author_id: function authorId() {
return this.belongsTo('User', 'author_id');
},
created_by: function () {
created_by: function createdBy() {
return this.belongsTo('User', 'created_by');
},
updated_by: function () {
updated_by: function updatedBy() {
return this.belongsTo('User', 'updated_by');
},
published_by: function () {
published_by: function publishedBy() {
return this.belongsTo('User', 'published_by');
},
tags: function () {
tags: function tags() {
return this.belongsToMany('Tag');
},
fields: function () {
fields: function fields() {
return this.morphMany('AppField', 'relatable');
},
toJSON: function (options) {
toJSON: function toJSON(options) {
var attrs = ghostBookshelf.Model.prototype.toJSON.call(this, options);
attrs.author = attrs.author || attrs.author_id;
@ -280,7 +280,7 @@ Post = ghostBookshelf.Model.extend({
* @param {String} methodName The name of the method to check valid options for.
* @return {Array} Keys allowed in the `options` hash of the model's method.
*/
permittedOptions: function (methodName) {
permittedOptions: function permittedOptions(methodName) {
var options = ghostBookshelf.Model.permittedOptions(),
// whitelists for the `options` hash argument on methods, by method name.
@ -304,7 +304,7 @@ Post = ghostBookshelf.Model.extend({
* @param {Object} data Has keys representing the model's attributes/fields in the database.
* @return {Object} The filtered results of the passed in data, containing only what's allowed in the schema.
*/
filterData: function (data) {
filterData: function filterData(data) {
var permittedAttributes = this.prototype.permittedAttributes(),
filteredData;
@ -324,7 +324,7 @@ Post = ghostBookshelf.Model.extend({
* @param {Object} options
* @returns {*}
*/
findAll: function (options) {
findAll: function findAll(options) {
options = options || {};
// fetch relations passed to options.include
@ -352,7 +352,7 @@ Post = ghostBookshelf.Model.extend({
*
* @param {Object} options
*/
findPage: function (options) {
findPage: function findPage(options) {
options = options || {};
var tagInstance = options.tag !== undefined ? ghostBookshelf.model('Tag').forge({slug: options.tag}) : false,
@ -425,7 +425,7 @@ Post = ghostBookshelf.Model.extend({
// with the opts (to specify any eager relations, etc.)
// Omitting the `page`, `limit`, `where` just to be sure
// aren't used for other purposes.
.then(function () {
.then(function then() {
var postCollection = Posts.forge(),
collectionPromise,
countPromise,
@ -482,7 +482,7 @@ Post = ghostBookshelf.Model.extend({
countPromise = qb.count('posts.id as aggregate');
return Promise.join(collectionPromise, countPromise);
}).then(function (results) {
}).then(function then(results) {
var totalPosts = parseInt(results[1][0].aggregate, 10),
calcPages = Math.ceil(totalPosts / options.limit) || 0,
postCollection = results[0],
@ -536,7 +536,7 @@ Post = ghostBookshelf.Model.extend({
* @extends ghostBookshelf.Model.findOne to handle post status
* **See:** [ghostBookshelf.Model.findOne](base.js.html#Find%20One)
*/
findOne: function (data, options) {
findOne: function findOne(data, options) {
options = options || {};
var withNext = _.contains(options.include, 'next'),
@ -553,7 +553,7 @@ Post = ghostBookshelf.Model.extend({
// Add related objects, excluding next and previous as they are not real db objects
options.withRelated = _.union(options.withRelated, _.pull([].concat(options.include), 'next', 'previous'));
return ghostBookshelf.Model.findOne.call(this, data, options).then(function (post) {
return ghostBookshelf.Model.findOne.call(this, data, options).then(function then(post) {
if ((withNext || withPrev) && post && !post.page) {
var postData = post.toJSON(options),
publishedAt = postData.published_at,
@ -561,7 +561,7 @@ Post = ghostBookshelf.Model.extend({
next;
if (withNext) {
next = Post.forge().query(function (qb) {
next = Post.forge().query(function queryBuilder(qb) {
qb.where('status', '=', 'published')
.andWhere('page', '=', 0)
.andWhere('published_at', '>', publishedAt)
@ -571,7 +571,7 @@ Post = ghostBookshelf.Model.extend({
}
if (withPrev) {
prev = Post.forge().query(function (qb) {
prev = Post.forge().query(function queryBuilder(qb) {
qb.where('status', '=', 'published')
.andWhere('page', '=', 0)
.andWhere('published_at', '<', publishedAt)
@ -581,7 +581,7 @@ Post = ghostBookshelf.Model.extend({
}
return Promise.join(next, prev)
.then(function (nextAndPrev) {
.then(function then(nextAndPrev) {
if (nextAndPrev[0]) {
post.relations.next = nextAndPrev[0];
}
@ -601,13 +601,13 @@ Post = ghostBookshelf.Model.extend({
* @extends ghostBookshelf.Model.edit to handle returning the full object and manage _updatedAttributes
* **See:** [ghostBookshelf.Model.edit](base.js.html#edit)
*/
edit: function (data, options) {
edit: function edit(data, options) {
var self = this;
options = options || {};
return ghostBookshelf.Model.edit.call(this, data, options).then(function (post) {
return ghostBookshelf.Model.edit.call(this, data, options).then(function then(post) {
return self.findOne({status: 'all', id: options.id}, options)
.then(function (found) {
.then(function then(found) {
if (found) {
// Pass along the updated attributes for checking status changes
found._updatedAttributes = post._updatedAttributes;
@ -622,11 +622,11 @@ Post = ghostBookshelf.Model.extend({
* @extends ghostBookshelf.Model.add to handle returning the full object
* **See:** [ghostBookshelf.Model.add](base.js.html#add)
*/
add: function (data, options) {
add: function add(data, options) {
var self = this;
options = options || {};
return ghostBookshelf.Model.add.call(this, data, options).then(function (post) {
return ghostBookshelf.Model.add.call(this, data, options).then(function then(post) {
return self.findOne({status: 'all', id: post.id}, options);
});
},
@ -636,12 +636,12 @@ Post = ghostBookshelf.Model.extend({
* @extends ghostBookshelf.Model.destroy to clean up tag relations
* **See:** [ghostBookshelf.Model.destroy](base.js.html#destroy)
*/
destroy: function (options) {
destroy: function destroy(options) {
var id = options.id;
options = this.filterOptions(options, 'destroy');
return this.forge({id: id}).fetch({withRelated: ['tags']}).then(function destroyTagsAndPost(post) {
return post.related('tags').detach().then(function () {
return this.forge({id: id}).fetch({withRelated: ['tags']}).then(function destroyTags(post) {
return post.related('tags').detach().then(function destroyPosts() {
return post.destroy(options);
});
});
@ -651,15 +651,15 @@ Post = ghostBookshelf.Model.extend({
* ### destroyByAuthor
* @param {[type]} options has context and id. Context is the user doing the destroy, id is the user to destroy
*/
destroyByAuthor: function (options) {
destroyByAuthor: function destroyByAuthor(options) {
var postCollection = Posts.forge(),
authorId = options.id;
options = this.filterOptions(options, 'destroyByAuthor');
if (authorId) {
return postCollection.query('where', 'author_id', '=', authorId).fetch(options).then(function (results) {
return Promise.map(results.models, function (post) {
return post.related('tags').detach(null, options).then(function () {
return postCollection.query('where', 'author_id', '=', authorId).fetch(options).then(function destroyTags(results) {
return Promise.map(results.models, function mapper(post) {
return post.related('tags').detach(null, options).then(function destroyPosts() {
return post.destroy(options);
});
});
@ -670,7 +670,7 @@ Post = ghostBookshelf.Model.extend({
return Promise.reject(new errors.NotFoundError('No user found'));
},
permissible: function (postModelOrId, action, context, loadedPermissions, hasUserPermission, hasAppPermission) {
permissible: function permissible(postModelOrId, action, context, loadedPermissions, hasUserPermission, hasAppPermission) {
var self = this,
postModel = postModelOrId,
origArgs;
@ -681,7 +681,7 @@ Post = ghostBookshelf.Model.extend({
// Grab the original args without the first one
origArgs = _.toArray(arguments).slice(1);
// Get the actual post model
return this.findOne({id: postModelOrId, status: 'all'}).then(function (foundPostModel) {
return this.findOne({id: postModelOrId, status: 'all'}).then(function then(foundPostModel) {
// Build up the original args but substitute with actual model
var newArgs = [foundPostModel].concat(origArgs);
@ -705,7 +705,7 @@ Post = ghostBookshelf.Model.extend({
Posts = ghostBookshelf.Collection.extend({
model: Post,
initialize: function () {
initialize: function initialize() {
ghostBookshelf.Collection.prototype.initialize.apply(this, arguments);
// Ensures local copy of permalink setting is kept up to date

View file

@ -1,5 +1,5 @@
var ghostBookshelf = require('./base'),
Basetoken = require('./basetoken'),
Basetoken = require('./base/token'),
Refreshtoken,
Refreshtokens;

View file

@ -10,11 +10,11 @@ Role = ghostBookshelf.Model.extend({
tableName: 'roles',
users: function () {
users: function users() {
return this.belongsToMany('User');
},
permissions: function () {
permissions: function permissions() {
return this.belongsToMany('Permission');
}
}, {
@ -23,7 +23,7 @@ Role = ghostBookshelf.Model.extend({
* @param {String} methodName The name of the method to check valid options for.
* @return {Array} Keys allowed in the `options` hash of the model's method.
*/
permittedOptions: function (methodName) {
permittedOptions: function permittedOptions(methodName) {
var options = ghostBookshelf.Model.permittedOptions(),
// whitelists for the `options` hash argument on methods, by method name.
@ -39,7 +39,7 @@ Role = ghostBookshelf.Model.extend({
return options;
},
permissible: function (roleModelOrId, action, context, loadedPermissions, hasUserPermission, hasAppPermission) {
permissible: function permissible(roleModelOrId, action, context, loadedPermissions, hasUserPermission, hasAppPermission) {
var self = this,
checkAgainst = [],
origArgs;
@ -50,7 +50,7 @@ Role = ghostBookshelf.Model.extend({
// Grab the original args without the first one
origArgs = _.toArray(arguments).slice(1);
// Get the actual post model
return this.findOne({id: roleModelOrId, status: 'all'}).then(function (foundRoleModel) {
return this.findOne({id: roleModelOrId, status: 'all'}).then(function then(foundRoleModel) {
// Build up the original args but substitute with actual model
var newArgs = [foundRoleModel].concat(origArgs);

View file

@ -16,8 +16,8 @@ function parseDefaultSettings() {
var defaultSettingsInCategories = require('../data/default-settings.json'),
defaultSettingsFlattened = {};
_.each(defaultSettingsInCategories, function (settings, categoryName) {
_.each(settings, function (setting, settingName) {
_.each(defaultSettingsInCategories, function each(settings, categoryName) {
_.each(settings, function each(setting, settingName) {
setting.type = categoryName;
setting.key = settingName;
@ -42,18 +42,18 @@ Settings = ghostBookshelf.Model.extend({
tableName: 'settings',
defaults: function () {
defaults: function defaults() {
return {
uuid: uuid.v4(),
type: 'core'
};
},
validate: function () {
validate: function validate() {
var self = this,
setting = this.toJSON();
return validation.validateSchema(self.tableName, setting).then(function () {
return validation.validateSchema(self.tableName, setting).then(function then() {
return validation.validateSettings(getDefaultSettings(), self);
}).then(function () {
var themeName = setting.value || '';
@ -66,7 +66,7 @@ Settings = ghostBookshelf.Model.extend({
});
},
saving: function () {
saving: function saving() {
// disabling sanitization until we can implement a better version
// All blog setting keys that need their values to be escaped.
// if (this.get('type') === 'blog' && _.contains(['title', 'description', 'email'], this.get('key'))) {
@ -102,7 +102,7 @@ Settings = ghostBookshelf.Model.extend({
item = self.filterData(item);
return Settings.forge({key: item.key}).fetch(options).then(function (setting) {
return Settings.forge({key: item.key}).fetch(options).then(function then(setting) {
if (setting) {
return setting.save({value: item.value}, options);
}
@ -117,7 +117,7 @@ Settings = ghostBookshelf.Model.extend({
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 then(foundSetting) {
if (foundSetting) {
return foundSetting;
}
@ -129,12 +129,12 @@ Settings = ghostBookshelf.Model.extend({
});
},
populateDefaults: function () {
return this.findAll().then(function (allSettings) {
var usedKeys = allSettings.models.map(function (setting) { return setting.get('key'); }),
populateDefaults: function populateDefaults() {
return this.findAll().then(function then(allSettings) {
var usedKeys = allSettings.models.map(function mapper(setting) { return setting.get('key'); }),
insertOperations = [];
_.each(getDefaultSettings(), function (defaultSetting, defaultSettingKey) {
_.each(getDefaultSettings(), function each(defaultSetting, defaultSettingKey) {
var isMissingFromDB = usedKeys.indexOf(defaultSettingKey) === -1;
// Temporary code to deal with old databases with currentVersion settings
if (defaultSettingKey === 'databaseVersion' && usedKeys.indexOf('currentVersion') !== -1) {

View file

@ -22,25 +22,25 @@ Tag = ghostBookshelf.Model.extend({
tableName: 'tags',
emitChange: function (event) {
emitChange: function emitChange(event) {
events.emit('tag' + '.' + event, this);
},
initialize: function () {
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('created', function (model) {
this.on('created', function onCreated(model) {
model.emitChange('added');
});
this.on('updated', function (model) {
this.on('updated', function onUpdated(model) {
model.emitChange('edited');
});
this.on('destroyed', function (model) {
this.on('destroyed', function onDestroyed(model) {
model.emitChange('deleted');
});
},
saving: function (newPage, attr, options) {
saving: function saving(newPage, attr, options) {
/*jshint unused:false*/
var self = this;
@ -51,17 +51,17 @@ Tag = ghostBookshelf.Model.extend({
// Pass the new slug through the generator to strip illegal characters, detect duplicates
return ghostBookshelf.Model.generateSlug(Tag, this.get('slug') || this.get('name'),
{transacting: options.transacting})
.then(function (slug) {
.then(function then(slug) {
self.set({slug: slug});
});
}
},
posts: function () {
posts: function posts() {
return this.belongsToMany('Post');
},
toJSON: function (options) {
toJSON: function toJSON(options) {
var attrs = ghostBookshelf.Model.prototype.toJSON.call(this, options);
attrs.parent = attrs.parent || attrs.parent_id;
@ -70,7 +70,7 @@ Tag = ghostBookshelf.Model.extend({
return attrs;
}
}, {
permittedOptions: function (methodName) {
permittedOptions: function permittedOptions(methodName) {
var options = ghostBookshelf.Model.permittedOptions(),
// whitelists for the `options` hash argument on methods, by method name.
@ -90,7 +90,7 @@ Tag = ghostBookshelf.Model.extend({
* ### Find One
* @overrides ghostBookshelf.Model.findOne
*/
findOne: function (data, options) {
findOne: function findOne(data, options) {
options = options || {};
options = this.filterOptions(options, 'findOne');
@ -106,7 +106,7 @@ Tag = ghostBookshelf.Model.extend({
return tag.fetch(options);
},
findPage: function (options) {
findPage: function findPage(options) {
options = options || {};
var tagCollection = Tags.forge(),
@ -148,7 +148,7 @@ Tag = ghostBookshelf.Model.extend({
qb.where(options.where);
}
return Promise.join(collectionPromise, qb.count('tags.id as aggregate')).then(function (results) {
return Promise.join(collectionPromise, qb.count('tags.id as aggregate')).then(function then(results) {
var totalTags = results[1][0].aggregate,
calcPages = Math.ceil(totalTags / options.limit) || 0,
tagCollection = results[0],
@ -182,12 +182,12 @@ Tag = ghostBookshelf.Model.extend({
})
.catch(errors.logAndThrowError);
},
destroy: function (options) {
destroy: function destroy(options) {
var id = options.id;
options = this.filterOptions(options, 'destroy');
return this.forge({id: id}).fetch({withRelated: ['posts']}).then(function destroyTagsAndPost(tag) {
return tag.related('posts').detach().then(function () {
return tag.related('posts').detach().then(function destroyTags() {
return tag.destroy(options);
});
});

View file

@ -37,14 +37,14 @@ User = ghostBookshelf.Model.extend({
tableName: 'users',
emitChange: function (event) {
emitChange: function emitChange(event) {
events.emit('user' + '.' + event, this);
},
initialize: function () {
initialize: function initialize() {
ghostBookshelf.Model.prototype.initialize.apply(this, arguments);
this.on('created', function (model) {
this.on('created', function onCreated(model) {
model.emitChange('added');
// active is the default state, so if status isn't provided, this will be an active user
@ -52,7 +52,7 @@ User = ghostBookshelf.Model.extend({
model.emitChange('activated');
}
});
this.on('updated', function (model) {
this.on('updated', function onUpdated(model) {
model.statusChanging = model.get('status') !== model.updated('status');
model.isActive = _.contains(activeStates, model.get('status'));
@ -66,7 +66,7 @@ User = ghostBookshelf.Model.extend({
model.emitChange('edited');
});
this.on('destroyed', function (model) {
this.on('destroyed', function onDestroyed(model) {
if (_.contains(activeStates, model.previous('status'))) {
model.emitChange('deactivated');
}
@ -75,7 +75,7 @@ User = ghostBookshelf.Model.extend({
});
},
saving: function (newPage, attr, options) {
saving: function saving(newPage, attr, options) {
/*jshint unused:false*/
var self = this;
@ -86,7 +86,7 @@ User = ghostBookshelf.Model.extend({
// Generating a slug requires a db call to look for conflicting slugs
return ghostBookshelf.Model.generateSlug(User, this.get('slug') || this.get('name'),
{status: 'all', transacting: options.transacting, shortSlug: !this.get('slug')})
.then(function (slug) {
.then(function then(slug) {
self.set({slug: slug});
});
}
@ -95,7 +95,7 @@ User = ghostBookshelf.Model.extend({
// For the user model ONLY it is possible to disable validations.
// This is used to bypass validation during the credential check, and must never be done with user-provided data
// Should be removed when #3691 is done
validate: function () {
validate: function validate() {
var opts = arguments[1];
if (opts && _.has(opts, 'validate') && opts.validate === false) {
return;
@ -104,7 +104,7 @@ User = ghostBookshelf.Model.extend({
},
// Get the user from the options object
contextUser: function (options) {
contextUser: function contextUser(options) {
// Default to context user
if (options.context && options.context.user) {
return options.context.user;
@ -119,7 +119,7 @@ User = ghostBookshelf.Model.extend({
}
},
toJSON: function (options) {
toJSON: function toJSON(options) {
var attrs = ghostBookshelf.Model.prototype.toJSON.call(this, options);
// remove password hash for security reasons
delete attrs.password;
@ -131,7 +131,7 @@ User = ghostBookshelf.Model.extend({
return attrs;
},
format: function (options) {
format: function format(options) {
if (!_.isEmpty(options.website) &&
!validator.isURL(options.website, {
require_protocol: true,
@ -141,22 +141,22 @@ User = ghostBookshelf.Model.extend({
return ghostBookshelf.Model.prototype.format.call(this, options);
},
posts: function () {
posts: function posts() {
return this.hasMany('Posts', 'created_by');
},
roles: function () {
roles: function roles() {
return this.belongsToMany('Role');
},
permissions: function () {
permissions: function permissions() {
return this.belongsToMany('Permission');
},
hasRole: function (roleName) {
hasRole: function hasRole(roleName) {
var roles = this.related('roles');
return roles.some(function (role) {
return roles.some(function getRole(role) {
return role.get('name') === roleName;
});
}
@ -167,7 +167,7 @@ User = ghostBookshelf.Model.extend({
* @param {String} methodName The name of the method to check valid options for.
* @return {Array} Keys allowed in the `options` hash of the model's method.
*/
permittedOptions: function (methodName) {
permittedOptions: function permittedOptions(methodName) {
var options = ghostBookshelf.Model.permittedOptions(),
// whitelists for the `options` hash argument on methods, by method name.
@ -193,7 +193,7 @@ User = ghostBookshelf.Model.extend({
* @param {Object} options
* @returns {*}
*/
findAll: function (options) {
findAll: function findAll(options) {
options = options || {};
options.withRelated = _.union(options.withRelated, options.include);
return ghostBookshelf.Model.findAll.call(this, options);
@ -221,7 +221,7 @@ User = ghostBookshelf.Model.extend({
*
* @param {Object} options
*/
findPage: function (options) {
findPage: function findPage(options) {
options = options || {};
var userCollection = Users.forge(),
@ -291,7 +291,7 @@ User = ghostBookshelf.Model.extend({
}
return Promise.resolve(fetchRoleQuery())
.then(function () {
.then(function then() {
function fetchCollection() {
if (roleInstance) {
userCollection
@ -330,7 +330,7 @@ User = ghostBookshelf.Model.extend({
return Promise.join(fetchCollection(), fetchPaginationData());
})
// Format response of data
.then(function (results) {
.then(function then(results) {
var totalUsers = parseInt(results[1][0].aggregate, 10),
calcPages = Math.ceil(totalUsers / options.limit) || 0,
pagination = {},
@ -376,7 +376,7 @@ User = ghostBookshelf.Model.extend({
* @extends ghostBookshelf.Model.findOne to include roles
* **See:** [ghostBookshelf.Model.findOne](base.js.html#Find%20One)
*/
findOne: function (data, options) {
findOne: function findOne(data, options) {
var query,
status,
lookupRole = data.role;
@ -429,7 +429,7 @@ User = ghostBookshelf.Model.extend({
* @extends ghostBookshelf.Model.edit to handle returning the full object
* **See:** [ghostBookshelf.Model.edit](base.js.html#edit)
*/
edit: function (data, options) {
edit: function edit(data, options) {
var self = this,
roleId;
@ -442,20 +442,20 @@ User = ghostBookshelf.Model.extend({
options = options || {};
options.withRelated = _.union(options.withRelated, options.include);
return ghostBookshelf.Model.edit.call(this, data, options).then(function (user) {
return ghostBookshelf.Model.edit.call(this, data, options).then(function then(user) {
if (!data.roles) {
return user;
}
roleId = parseInt(data.roles[0].id || data.roles[0], 10);
return user.roles().fetch().then(function (roles) {
return user.roles().fetch().then(function then(roles) {
// return if the role is already assigned
if (roles.models[0].id === roleId) {
return;
}
return ghostBookshelf.model('Role').findOne({id: roleId});
}).then(function (roleToAssign) {
}).then(function then(roleToAssign) {
if (roleToAssign && roleToAssign.get('name') === 'Owner') {
return Promise.reject(
new errors.ValidationError('This method does not support assigning the owner role')
@ -464,7 +464,7 @@ User = ghostBookshelf.Model.extend({
// assign all other roles
return user.roles().updatePivot({role_id: roleId});
}
}).then(function () {
}).then(function then() {
options.status = 'all';
return self.findOne({id: user.id}, options);
});
@ -481,7 +481,7 @@ User = ghostBookshelf.Model.extend({
* @extends ghostBookshelf.Model.add to manage all aspects of user signup
* **See:** [ghostBookshelf.Model.add](base.js.html#Add)
*/
add: function (data, options) {
add: function add(data, options) {
var self = this,
userData = this.filterData(data),
roles;
@ -499,7 +499,7 @@ User = ghostBookshelf.Model.extend({
}
function getAuthorRole() {
return ghostBookshelf.model('Role').findOne({name: 'Author'}, _.pick(options, 'transacting')).then(function (authorRole) {
return ghostBookshelf.model('Role').findOne({name: 'Author'}, _.pick(options, 'transacting')).then(function then(authorRole) {
return [authorRole.get('id')];
});
}
@ -507,20 +507,20 @@ User = ghostBookshelf.Model.extend({
roles = data.roles || getAuthorRole();
delete data.roles;
return generatePasswordHash(userData.password).then(function (results) {
return generatePasswordHash(userData.password).then(function then(results) {
// Assign the hashed password
userData.password = results[1];
// LookupGravatar
return self.gravatarLookup(userData);
}).then(function (userData) {
}).then(function then(userData) {
// Save the user with the hashed password
return ghostBookshelf.Model.add.call(self, userData, options);
}).then(function (addedUser) {
}).then(function then(addedUser) {
// Assign the userData to our created user so we can pass it back
userData = addedUser;
// if we are given a "role" object, only pass in the role ID in place of the full object
return Promise.resolve(roles).then(function (roles) {
roles = _.map(roles, function (role) {
return Promise.resolve(roles).then(function then(roles) {
roles = _.map(roles, function mapper(role) {
if (_.isString(role)) {
return parseInt(role, 10);
} else if (_.isNumber(role)) {
@ -532,13 +532,13 @@ User = ghostBookshelf.Model.extend({
return addedUser.roles().attach(roles, options);
});
}).then(function () {
}).then(function then() {
// find and return the added user
return self.findOne({id: userData.id, status: 'all'}, options);
});
},
setup: function (data, options) {
setup: function setup(data, options) {
var self = this,
userData = this.filterData(data);
@ -550,13 +550,13 @@ User = ghostBookshelf.Model.extend({
options.withRelated = _.union(options.withRelated, options.include);
options.shortSlug = true;
return generatePasswordHash(data.password).then(function (hash) {
return generatePasswordHash(data.password).then(function then(hash) {
// Assign the hashed password
userData.password = hash;
return Promise.join(self.gravatarLookup(userData),
ghostBookshelf.Model.generateSlug.call(this, User, userData.name, options));
}).then(function (results) {
}).then(function then(results) {
userData = results[0];
userData.slug = results[1];
@ -564,7 +564,7 @@ User = ghostBookshelf.Model.extend({
});
},
permissible: function (userModelOrId, action, context, loadedPermissions, hasUserPermission, hasAppPermission) {
permissible: function permissible(userModelOrId, action, context, loadedPermissions, hasUserPermission, hasAppPermission) {
var self = this,
userModel = userModelOrId,
origArgs;
@ -578,7 +578,7 @@ User = ghostBookshelf.Model.extend({
// Grab the original args without the first one
origArgs = _.toArray(arguments).slice(1);
// Get the actual post model
return this.findOne({id: userModelOrId, status: 'all'}, {include: ['roles']}).then(function (foundUserModel) {
return this.findOne({id: userModelOrId, status: 'all'}, {include: ['roles']}).then(function then(foundUserModel) {
// Build up the original args but substitute with actual model
var newArgs = [foundUserModel].concat(origArgs);
@ -626,7 +626,7 @@ User = ghostBookshelf.Model.extend({
return Promise.reject();
},
setWarning: function (user, options) {
setWarning: function setWarning(user, options) {
var status = user.get('status'),
regexp = /warn-(\d+)/i,
level;
@ -642,16 +642,16 @@ User = ghostBookshelf.Model.extend({
user.set('status', 'warn-' + level);
}
}
return Promise.resolve(user.save(options)).then(function () {
return Promise.resolve(user.save(options)).then(function then() {
return 5 - level;
});
},
// Finds the user by email, and checks the password
check: function (object) {
check: function check(object) {
var self = this,
s;
return this.getByEmail(object.email).then(function (user) {
return this.getByEmail(object.email).then(function then(user) {
if (!user) {
return Promise.reject(new errors.NotFoundError('There is no user with that email address.'));
}
@ -661,15 +661,15 @@ User = ghostBookshelf.Model.extend({
return Promise.reject(new Error('The user with that email address is inactive.'));
}
if (user.get('status') !== 'locked') {
return bcryptCompare(object.password, user.get('password')).then(function (matched) {
return bcryptCompare(object.password, user.get('password')).then(function then(matched) {
if (!matched) {
return Promise.resolve(self.setWarning(user, {validate: false})).then(function (remaining) {
return Promise.resolve(self.setWarning(user, {validate: false})).then(function then(remaining) {
s = (remaining > 1) ? 's' : '';
return Promise.reject(new errors.UnauthorizedError('Your password is incorrect. <br />' +
remaining + ' attempt' + s + ' remaining!'));
// Use comma structure, not .catch, because we don't want to catch incorrect passwords
}, function (error) {
}, function handleError(error) {
// 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.
errors.logError(
@ -682,7 +682,7 @@ User = ghostBookshelf.Model.extend({
}
return Promise.resolve(user.set({status: 'active', last_login: new Date()}).save({validate: false}))
.catch(function (error) {
.catch(function handleError(error) {
// 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.
errors.logError(
@ -696,7 +696,7 @@ User = ghostBookshelf.Model.extend({
}
return Promise.reject(new errors.NoPermissionError('Your account is locked. Please reset your password ' +
'to log in again by clicking the "Forgotten password?" link!'));
}, function (error) {
}, function handleError(error) {
if (error.message === 'NotFound' || error.message === 'EmptyResponse') {
return Promise.reject(new errors.NotFoundError('There is no user with that email address.'));
}
@ -713,7 +713,7 @@ User = ghostBookshelf.Model.extend({
* @param {Integer} userId
* @param {Object} options
*/
changePassword: function (oldPassword, newPassword, ne2Password, userId, options) {
changePassword: function changePassword(oldPassword, newPassword, ne2Password, userId, options) {
var self = this,
user;
@ -729,26 +729,26 @@ User = ghostBookshelf.Model.extend({
return Promise.reject(new errors.ValidationError('Your password must be at least 8 characters long.'));
}
return self.forge({id: userId}).fetch({require: true}).then(function (_user) {
return self.forge({id: userId}).fetch({require: true}).then(function then(_user) {
user = _user;
if (userId === options.context.user) {
return bcryptCompare(oldPassword, user.get('password'));
}
// if user is admin, password isn't compared
return true;
}).then(function (matched) {
}).then(function then(matched) {
if (!matched) {
return Promise.reject(new errors.ValidationError('Your password is incorrect'));
}
return generatePasswordHash(newPassword);
}).then(function (hash) {
}).then(function then(hash) {
return user.save({password: hash});
});
},
generateResetToken: function (email, expires, dbHash) {
return this.getByEmail(email).then(function (foundUser) {
generateResetToken: function generateResetToken(email, expires, dbHash) {
return this.getByEmail(email).then(function then(foundUser) {
if (!foundUser) {
return Promise.reject(new errors.NotFoundError('There is no user with that email address.'));
}
@ -768,7 +768,7 @@ User = ghostBookshelf.Model.extend({
});
},
validateToken: function (token, dbHash) {
validateToken: function validateToken(token, dbHash) {
/*jslint bitwise:true*/
// TODO: Is there a chance the use of ascii here will cause problems if oldPassword has weird characters?
var tokenText = new Buffer(token, 'base64').toString('ascii'),
@ -801,7 +801,7 @@ User = ghostBookshelf.Model.extend({
return Promise.reject(new Error('Token locked'));
}
return this.generateResetToken(email, expires, dbHash).then(function (generatedToken) {
return this.generateResetToken(email, expires, dbHash).then(function then(generatedToken) {
// Check for matching tokens with timing independent comparison
var diff = 0,
i;
@ -827,7 +827,7 @@ User = ghostBookshelf.Model.extend({
});
},
resetPassword: function (token, newPassword, ne2Password, dbHash) {
resetPassword: function resetPassword(token, newPassword, ne2Password, dbHash) {
var self = this;
if (newPassword !== ne2Password) {
@ -839,13 +839,13 @@ User = ghostBookshelf.Model.extend({
}
// Validate the token; returns the email address from token
return self.validateToken(utils.decodeBase64URLsafe(token), dbHash).then(function (email) {
return self.validateToken(utils.decodeBase64URLsafe(token), dbHash).then(function then(email) {
// Fetch the user by email, and hash the password at the same time.
return Promise.join(
self.getByEmail(email),
generatePasswordHash(newPassword)
);
}).then(function (results) {
}).then(function then(results) {
if (!results[0]) {
return Promise.reject(new Error('User not found'));
}
@ -858,13 +858,13 @@ User = ghostBookshelf.Model.extend({
});
},
transferOwnership: function (object, options) {
transferOwnership: function transferOwnership(object, options) {
var ownerRole,
contextUser;
return Promise.join(ghostBookshelf.model('Role').findOne({name: 'Owner'}),
User.findOne({id: options.context.user}, {include: ['roles']}))
.then(function (results) {
.then(function then(results) {
ownerRole = results[0];
contextUser = results[1];
@ -876,7 +876,7 @@ User = ghostBookshelf.Model.extend({
return Promise.join(ghostBookshelf.model('Role').findOne({name: 'Administrator'}),
User.findOne({id: object.id}, {include: ['roles']}));
}).then(function (results) {
}).then(function then(results) {
var adminRole = results[0],
user = results[1],
currentRoles = user.toJSON(options).roles;
@ -889,27 +889,27 @@ User = ghostBookshelf.Model.extend({
return Promise.join(contextUser.roles().updatePivot({role_id: adminRole.id}),
user.roles().updatePivot({role_id: ownerRole.id}),
user.id);
}).then(function (results) {
}).then(function then(results) {
return Users.forge()
.query('whereIn', 'id', [contextUser.id, results[2]])
.fetch({withRelated: ['roles']});
}).then(function (users) {
}).then(function then(users) {
options.include = ['roles'];
return users.toJSON(options);
});
},
gravatarLookup: function (userData) {
gravatarLookup: function gravatarLookup(userData) {
var gravatarUrl = '//www.gravatar.com/avatar/' +
crypto.createHash('md5').update(userData.email.toLowerCase().trim()).digest('hex') +
'?s=250';
return new Promise(function (resolve) {
return new Promise(function gravatarRequest(resolve) {
if (config.isPrivacyDisabled('useGravatar')) {
return resolve(userData);
}
request({url: 'http:' + gravatarUrl + '&d=404&r=x', timeout: 2000}, function (err, response) {
request({url: 'http:' + gravatarUrl + '&d=404&r=x', timeout: 2000}, function handler(err, response) {
if (err) {
// just resolve with no image url
return resolve(userData);
@ -927,7 +927,7 @@ User = ghostBookshelf.Model.extend({
// 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
// joe@bloggs.com and JOE@BLOGGS.COM cannot be created as two separate users.
getByEmail: function (email, options) {
getByEmail: function getByEmail(email, options) {
options = options || {};
// We fetch all users and process them in JS as there is no easy way to make this query across all DBs
// Although they all support `lower()`, sqlite can't case transform unicode characters
@ -935,8 +935,8 @@ User = ghostBookshelf.Model.extend({
// likely to be fixed in the near future.
options.require = true;
return Users.forge(options).fetch(options).then(function (users) {
var userWithEmail = users.find(function (user) {
return Users.forge(options).fetch(options).then(function then(users) {
var userWithEmail = users.find(function findUser(user) {
return user.get('email').toLowerCase() === email.toLowerCase();
});
if (userWithEmail) {