Ghost/core/server/api/v2/users.js
Fabien O'Carroll e865d2218c 🐛 Fixed pagination/duplicate posts and users appearing in admin area (#10031)
closes #10029

- allowed page option for users, posts, & tags browse 
  - The page query param was not forwarding to the query, meaning that when the admin client requested the next page of users or posts, it would receive the first page again.
2018-10-18 10:05:51 +01:00

175 lines
4.6 KiB
JavaScript

const Promise = require('bluebird');
const common = require('../../lib/common');
const models = require('../../models');
const permissionsService = require('../../services/permissions');
const ALLOWED_INCLUDES = ['count.posts', 'permissions', 'roles', 'roles.permissions'];
const UNSAFE_ATTRS = ['status', 'roles'];
module.exports = {
docName: 'users',
browse: {
options: [
'include',
'filter',
'fields',
'limit',
'status',
'order',
'page',
'debug'
],
validation: {
options: {
include: {
values: ALLOWED_INCLUDES
}
}
},
permissions: true,
query(frame) {
return models.User.findPage(frame.options);
}
},
read: {
options: [
'include',
'filter',
'fields',
'debug'
],
data: [
'id',
'slug',
'status',
'email',
'role'
],
validation: {
options: {
include: {
values: ALLOWED_INCLUDES
}
}
},
permissions: true,
query(frame) {
return models.User.findOne(frame.data, frame.options)
.then((model) => {
if (!model) {
return Promise.reject(new common.errors.NotFoundError({
message: common.i18n.t('errors.api.users.userNotFound')
}));
}
return model;
});
}
},
edit: {
headers: {
cacheInvalidate: true
},
options: [
'id',
'include'
],
validation: {
options: {
include: {
values: ALLOWED_INCLUDES
},
id: {
required: true
}
}
},
permissions: {
unsafeAttrs: UNSAFE_ATTRS
},
query(frame) {
return models.User.edit(frame.data.users[0], frame.options)
.then((model) => {
if (!model) {
return Promise.reject(new common.errors.NotFoundError({
message: common.i18n.t('errors.api.users.userNotFound')
}));
}
return model;
});
}
},
destroy: {
statusCode: 204,
headers: {
cacheInvalidate: true
},
options: [
'id'
],
validation: {
options: {
id: {
required: true
}
}
},
permissions: true,
query(frame) {
return models.Base.transaction((t) => {
frame.options.transacting = t;
return Promise.all([
models.Accesstoken.destroyByUser(frame.options),
models.Refreshtoken.destroyByUser(frame.options),
models.Post.destroyByAuthor(frame.options)
]).then(() => {
return models.User.destroy(Object.assign({status: 'all'}, frame.options));
}).return(null);
}).catch((err) => {
return Promise.reject(new common.errors.NoPermissionError({
err: err
}));
});
}
},
changePassword: {
validation: {
docName: 'password',
data: {
newPassword: {required: true},
ne2Password: {required: true},
oldPassword: {required: true},
user_id: {required: true}
}
},
permissions: {
docName: 'user',
method: 'edit',
identifier(frame) {
return frame.data.password[0].user_id;
}
},
query(frame) {
return models.User.changePassword(frame.data.password[0], frame.options);
}
},
transferOwnership: {
permissions(frame) {
return models.Role.findOne({name: 'Owner'})
.then((ownerRole) => {
return permissionsService.canThis(frame.options.context).assign.role(ownerRole);
});
},
query(frame) {
return models.User.transferOwnership(frame.data.owner[0], frame.options);
}
}
};