Merge branch 'develop' of github.com:strapi/strapi into features/media-lib

This commit is contained in:
soupette 2020-03-13 11:04:45 +01:00
commit f99f83af02
12 changed files with 316 additions and 449 deletions

View File

@ -13,9 +13,7 @@ const PLUGIN_NAME_REGEX = /^[A-Za-z][A-Za-z0-9-_]+$/;
* Validates a plugin name format * Validates a plugin name format
*/ */
const isValidPluginName = plugin => { const isValidPluginName = plugin => {
return ( return _.isString(plugin) && !_.isEmpty(plugin) && PLUGIN_NAME_REGEX.test(plugin);
_.isString(plugin) && !_.isEmpty(plugin) && PLUGIN_NAME_REGEX.test(plugin)
);
}; };
/** /**
@ -48,9 +46,7 @@ module.exports = {
const strapiVersion = _.get(strapi.config, 'info.strapi', null); const strapiVersion = _.get(strapi.config, 'info.strapi', null);
return ctx.send({ strapiVersion }); return ctx.send({ strapiVersion });
} catch (err) { } catch (err) {
return ctx.badRequest(null, [ return ctx.badRequest(null, [{ messages: [{ id: 'The version is not available' }] }]);
{ messages: [{ id: 'The version is not available' }] },
]);
} }
}, },
@ -68,9 +64,7 @@ module.exports = {
return ctx.send({ layout }); return ctx.send({ layout });
} catch (err) { } catch (err) {
return ctx.badRequest(null, [ return ctx.badRequest(null, [{ messages: [{ id: 'An error occurred' }] }]);
{ messages: [{ id: 'An error occurred' }] },
]);
} }
}, },
@ -179,9 +173,7 @@ module.exports = {
); );
} }
const adminsWithSameEmail = await strapi const adminsWithSameEmail = await strapi.query('administrator', 'admin').findOne({ email });
.query('administrator', 'admin')
.findOne({ email });
const adminsWithSameUsername = await strapi const adminsWithSameUsername = await strapi
.query('administrator', 'admin') .query('administrator', 'admin')
@ -264,18 +256,14 @@ module.exports = {
}) })
); );
} }
const admin = await strapi const admin = await strapi.query('administrator', 'admin').findOne({ id });
.query('administrator', 'admin')
.findOne(ctx.params);
// check the user exists // check the user exists
if (!admin) return ctx.notFound('Administrator not found'); if (!admin) return ctx.notFound('Administrator not found');
// check there are not user with requested email // check there are not user with requested email
if (email !== admin.email) { if (email !== admin.email) {
const adminsWithSameEmail = await strapi const adminsWithSameEmail = await strapi.query('administrator', 'admin').findOne({ email });
.query('administrator', 'admin')
.findOne({ email });
if (adminsWithSameEmail && adminsWithSameEmail.id !== admin.id) { if (adminsWithSameEmail && adminsWithSameEmail.id !== admin.id) {
return ctx.badRequest( return ctx.badRequest(
@ -317,9 +305,7 @@ module.exports = {
user.password = await strapi.admin.services.auth.hashPassword(password); user.password = await strapi.admin.services.auth.hashPassword(password);
} }
const data = await strapi const data = await strapi.query('administrator', 'admin').update({ id }, user);
.query('administrator', 'admin')
.update({ id }, user);
// Send 200 `ok` // Send 200 `ok`
ctx.send(data); ctx.send(data);

View File

@ -4,11 +4,7 @@
*/ */
const _ = require('lodash'); const _ = require('lodash');
const { const { convertRestQueryParams, buildQuery, models: modelUtils } = require('strapi-utils');
convertRestQueryParams,
buildQuery,
models: modelUtils,
} = require('strapi-utils');
module.exports = function createQueryBuilder({ model, modelKey, strapi }) { module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
/* Utils */ /* Utils */
@ -50,20 +46,8 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
* Find one entry based on params * Find one entry based on params
*/ */
async function findOne(params, populate, { transacting } = {}) { async function findOne(params, populate, { transacting } = {}) {
const primaryKey = params[model.primaryKey] || params.id; const entries = await find({ ...params, _limit: 1 }, populate, { transacting });
return entries[0] || null;
if (primaryKey) {
params = {
[model.primaryKey]: primaryKey,
};
}
const entry = await model.where(params).fetch({
withRelated: populate,
transacting,
});
return entry ? entry.toJSON() : null;
} }
/** /**
@ -99,10 +83,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
const entry = await model.forge(data).save(null, { transacting: trx }); const entry = await model.forge(data).save(null, { transacting: trx });
await createComponents(entry, values, { transacting: trx }); await createComponents(entry, values, { transacting: trx });
return model.updateRelations( return model.updateRelations({ id: entry.id, values: relations }, { transacting: trx });
{ id: entry.id, values: relations },
{ transacting: trx }
);
}; };
return wrapTransaction(runCreate, { transacting }); return wrapTransaction(runCreate, { transacting });
@ -133,10 +114,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
await updateComponents(updatedEntry, values, { transacting: trx }); await updateComponents(updatedEntry, values, { transacting: trx });
if (Object.keys(relations).length > 0) { if (Object.keys(relations).length > 0) {
return model.updateRelations( return model.updateRelations({ id: entry.id, values: relations }, { transacting: trx });
{ id: entry.id, values: relations },
{ transacting: trx }
);
} }
return this.findOne(params, null, { transacting: trx }); return this.findOne(params, null, { transacting: trx });
@ -145,8 +123,8 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
return wrapTransaction(runUpdate, { transacting }); return wrapTransaction(runUpdate, { transacting });
} }
async function deleteOne(params, { transacting } = {}) { async function deleteOne(id, { transacting } = {}) {
const entry = await model.where(params).fetch({ transacting }); const entry = await model.where({ [model.primaryKey]: id }).fetch({ transacting });
if (!entry) { if (!entry) {
const err = new Error('entry.notFound'); const err = new Error('entry.notFound');
@ -173,13 +151,11 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
} }
}); });
await model.updateRelations({ ...params, values }, { transacting }); await model.updateRelations({ [model.primaryKey]: id, values }, { transacting });
const runDelete = async trx => { const runDelete = async trx => {
await deleteComponents(entry, { transacting: trx }); await deleteComponents(entry, { transacting: trx });
await model await model.where({ id: entry.id }).destroy({ transacting: trx, require: false });
.where({ id: entry.id })
.destroy({ transacting: trx, require: false });
return entry.toJSON(); return entry.toJSON();
}; };
@ -187,14 +163,16 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
} }
async function deleteMany(params, { transacting } = {}) { async function deleteMany(params, { transacting } = {}) {
const primaryKey = params[model.primaryKey] || params.id; if (params[model.primaryKey]) {
const entries = await find({ ...params, _limit: 1 }, null, { transacting });
if (primaryKey) return deleteOne(params, { transacting }); if (entries.length > 0) {
return deleteOne(entries[0][model.primaryKey], { transacting });
}
return null;
}
const entries = await find(params, null, { transacting }); const entries = await find(params, null, { transacting });
return await Promise.all( return Promise.all(entries.map(entry => deleteOne(entry.id, { transacting })));
entries.map(entry => deleteOne({ id: entry.id }, { transacting }))
);
} }
function search(params, populate) { function search(params, populate) {
@ -237,12 +215,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
const joinModel = model.componentsJoinModel; const joinModel = model.componentsJoinModel;
const { foreignKey } = joinModel; const { foreignKey } = joinModel;
const createComponentAndLink = async ({ const createComponentAndLink = async ({ componentModel, value, key, order }) => {
componentModel,
value,
key,
order,
}) => {
return strapi return strapi
.query(componentModel.uid) .query(componentModel.uid)
.create(value, { transacting }) .create(value, { transacting })
@ -343,12 +316,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
const joinModel = model.componentsJoinModel; const joinModel = model.componentsJoinModel;
const { foreignKey } = joinModel; const { foreignKey } = joinModel;
const updateOrCreateComponentAndLink = async ({ const updateOrCreateComponentAndLink = async ({ componentModel, key, value, order }) => {
componentModel,
key,
value,
order,
}) => {
// check if value has an id then update else create // check if value has an id then update else create
if (_.has(value, componentModel.primaryKey)) { if (_.has(value, componentModel.primaryKey)) {
return strapi return strapi
@ -481,11 +449,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
return; return;
} }
async function deleteDynamicZoneOldComponents( async function deleteDynamicZoneOldComponents(entry, values, { key, joinModel, transacting }) {
entry,
values,
{ key, joinModel, transacting }
) {
const idsToKeep = values.reduce((acc, value) => { const idsToKeep = values.reduce((acc, value) => {
const component = value.__component; const component = value.__component;
const componentModel = strapi.components[component]; const componentModel = strapi.components[component];
@ -506,8 +470,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
.fetchAll({ transacting }) .fetchAll({ transacting })
.map(el => { .map(el => {
const componentKey = Object.keys(strapi.components).find( const componentKey = Object.keys(strapi.components).find(
key => key => strapi.components[key].collectionName === el.get('component_type')
strapi.components[key].collectionName === el.get('component_type')
); );
return { return {
@ -518,9 +481,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
// verify the provided ids are realted to this entity. // verify the provided ids are realted to this entity.
idsToKeep.forEach(({ id, component }) => { idsToKeep.forEach(({ id, component }) => {
if ( if (!allIds.find(el => el.id === id && el.component.uid === component.uid)) {
!allIds.find(el => el.id === id && el.component.uid === component.uid)
) {
const err = new Error( const err = new Error(
`Some of the provided components in ${key} are not related to the entity` `Some of the provided components in ${key} are not related to the entity`
); );
@ -530,11 +491,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
}); });
const idsToDelete = allIds.reduce((acc, { id, component }) => { const idsToDelete = allIds.reduce((acc, { id, component }) => {
if ( if (!idsToKeep.find(el => el.id === id && el.component.uid === component.uid)) {
!idsToKeep.find(
el => el.id === id && el.component.uid === component.uid
)
) {
acc.push({ acc.push({
id, id,
component, component,
@ -550,10 +507,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
qb.where(qb => { qb.where(qb => {
idsToDelete.forEach(({ id, component }) => { idsToDelete.forEach(({ id, component }) => {
qb.orWhere(qb => { qb.orWhere(qb => {
qb.where('component_id', id).andWhere( qb.where('component_id', id).andWhere('component_type', component.collectionName);
'component_type',
component.collectionName
);
}); });
}); });
}); });
@ -573,9 +527,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
componentValue, componentValue,
{ key, joinModel, componentModel, transacting } { key, joinModel, componentModel, transacting }
) { ) {
const componentArr = Array.isArray(componentValue) const componentArr = Array.isArray(componentValue) ? componentValue : [componentValue];
? componentValue
: [componentValue];
const idsToKeep = componentArr const idsToKeep = componentArr
.filter(el => _.has(el, componentModel.primaryKey)) .filter(el => _.has(el, componentModel.primaryKey))
@ -603,17 +555,12 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
const idsToDelete = _.difference(allIds, idsToKeep); const idsToDelete = _.difference(allIds, idsToKeep);
if (idsToDelete.length > 0) { if (idsToDelete.length > 0) {
await joinModel await joinModel
.query(qb => .query(qb => qb.whereIn('component_id', idsToDelete).andWhere('field', key))
qb.whereIn('component_id', idsToDelete).andWhere('field', key)
)
.destroy({ transacting, require: false }); .destroy({ transacting, require: false });
await strapi await strapi
.query(componentModel.uid) .query(componentModel.uid)
.delete( .delete({ [`${componentModel.primaryKey}_in`]: idsToDelete }, { transacting });
{ [`${componentModel.primaryKey}_in`]: idsToDelete },
{ transacting }
);
} }
} }
@ -643,10 +590,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
await strapi await strapi
.query(componentModel.uid) .query(componentModel.uid)
.delete( .delete({ [`${componentModel.primaryKey}_in`]: ids }, { transacting });
{ [`${componentModel.primaryKey}_in`]: ids },
{ transacting }
);
await joinModel await joinModel
.where({ .where({
@ -674,9 +618,7 @@ module.exports = function createQueryBuilder({ model, modelKey, strapi }) {
const { uid, collectionName } = strapi.components[compo]; const { uid, collectionName } = strapi.components[compo];
const model = strapi.query(uid); const model = strapi.query(uid);
const toDelete = componentJoins.filter( const toDelete = componentJoins.filter(el => el.componentType === collectionName);
el => el.componentType === collectionName
);
if (toDelete.length > 0) { if (toDelete.length > 0) {
await model.delete( await model.delete(
@ -725,33 +667,18 @@ const buildSearchQuery = (qb, model, params) => {
const associations = model.associations.map(x => x.alias); const associations = model.associations.map(x => x.alias);
const searchText = Object.keys(model._attributes) const searchText = Object.keys(model._attributes)
.filter( .filter(attribute => attribute !== model.primaryKey && !associations.includes(attribute))
attribute => .filter(attribute => ['string', 'text'].includes(model._attributes[attribute].type));
attribute !== model.primaryKey && !associations.includes(attribute)
)
.filter(attribute =>
['string', 'text'].includes(model._attributes[attribute].type)
);
const searchInt = Object.keys(model._attributes) const searchInt = Object.keys(model._attributes)
.filter( .filter(attribute => attribute !== model.primaryKey && !associations.includes(attribute))
attribute =>
attribute !== model.primaryKey && !associations.includes(attribute)
)
.filter(attribute => .filter(attribute =>
['integer', 'decimal', 'float'].includes( ['integer', 'decimal', 'float'].includes(model._attributes[attribute].type)
model._attributes[attribute].type
)
); );
const searchBool = Object.keys(model._attributes) const searchBool = Object.keys(model._attributes)
.filter( .filter(attribute => attribute !== model.primaryKey && !associations.includes(attribute))
attribute => .filter(attribute => ['boolean'].includes(model._attributes[attribute].type));
attribute !== model.primaryKey && !associations.includes(attribute)
)
.filter(attribute =>
['boolean'].includes(model._attributes[attribute].type)
);
if (!_.isNaN(_.toNumber(query))) { if (!_.isNaN(_.toNumber(query))) {
searchInt.forEach(attribute => { searchInt.forEach(attribute => {
@ -768,10 +695,7 @@ const buildSearchQuery = (qb, model, params) => {
// Search in columns with text using index. // Search in columns with text using index.
switch (model.client) { switch (model.client) {
case 'mysql': case 'mysql':
qb.orWhereRaw( qb.orWhereRaw(`MATCH(${searchText.join(',')}) AGAINST(? IN BOOLEAN MODE)`, `*${query}*`);
`MATCH(${searchText.join(',')}) AGAINST(? IN BOOLEAN MODE)`,
`*${query}*`
);
break; break;
case 'pg': { case 'pg': {
const searchQuery = searchText.map(attribute => const searchQuery = searchText.map(attribute =>
@ -803,13 +727,8 @@ function validateRepeatableInput(value, { key, min, max, required }) {
} }
}); });
if ( if ((required === true || (required !== true && value.length > 0)) && min && value.length < min) {
(required === true || (required !== true && value.length > 0)) && const err = new Error(`Component ${key} must contain at least ${min} items`);
(min && value.length < min)
) {
const err = new Error(
`Component ${key} must contain at least ${min} items`
);
err.status = 400; err.status = 400;
throw err; throw err;
} }
@ -835,10 +754,7 @@ function validateNonRepeatableInput(value, { key, required }) {
} }
} }
function validateDynamiczoneInput( function validateDynamiczoneInput(value, { key, min, max, components, required }) {
value,
{ key, min, max, components, required }
) {
if (!Array.isArray(value)) { if (!Array.isArray(value)) {
const err = new Error(`Dynamiczone ${key} is invalid. Expected an array`); const err = new Error(`Dynamiczone ${key} is invalid. Expected an array`);
err.status = 400; err.status = 400;
@ -869,20 +785,13 @@ function validateDynamiczoneInput(
} }
}); });
if ( if ((required === true || (required !== true && value.length > 0)) && min && value.length < min) {
(required === true || (required !== true && value.length > 0)) && const err = new Error(`Dynamiczone ${key} must contain at least ${min} items`);
(min && value.length < min)
) {
const err = new Error(
`Dynamiczone ${key} must contain at least ${min} items`
);
err.status = 400; err.status = 400;
throw err; throw err;
} }
if (max && value.length > max) { if (max && value.length > max) {
const err = new Error( const err = new Error(`Dynamiczone ${key} must contain at most ${max} items`);
`Dynamiczone ${key} must contain at most ${max} items`
);
err.status = 400; err.status = 400;
throw err; throw err;
} }

View File

@ -4,17 +4,12 @@
*/ */
const _ = require('lodash'); const _ = require('lodash');
const { const { convertRestQueryParams, buildQuery, models: modelUtils } = require('strapi-utils');
convertRestQueryParams,
buildQuery,
models: modelUtils,
} = require('strapi-utils');
const { findComponentByGlobalId } = require('./utils/helpers'); const { findComponentByGlobalId } = require('./utils/helpers');
const hasPK = (obj, model) => _.has(obj, model.primaryKey) || _.has(obj, 'id'); const hasPK = (obj, model) => _.has(obj, model.primaryKey) || _.has(obj, 'id');
const getPK = (obj, model) => const getPK = (obj, model) => (_.has(obj, model.primaryKey) ? obj[model.primaryKey] : obj.id);
_.has(obj, model.primaryKey) ? obj[model.primaryKey] : obj.id;
module.exports = ({ model, modelKey, strapi }) => { module.exports = ({ model, modelKey, strapi }) => {
const assocKeys = model.associations.map(ast => ast.alias); const assocKeys = model.associations.map(ast => ast.alias);
@ -77,9 +72,7 @@ module.exports = ({ model, modelKey, strapi }) => {
validateNonRepeatableInput(componentValue, { key, ...attr }); validateNonRepeatableInput(componentValue, { key, ...attr });
if (componentValue === null) continue; if (componentValue === null) continue;
const componentEntry = await strapi const componentEntry = await strapi.query(component).create(componentValue);
.query(component)
.create(componentValue);
entry[key] = [ entry[key] = [
{ {
kind: componentModel.globalId, kind: componentModel.globalId,
@ -174,9 +167,7 @@ module.exports = ({ model, modelKey, strapi }) => {
}); });
const components = await Promise.all( const components = await Promise.all(
componentValue.map(value => componentValue.map(value => updateOrCreateComponent({ componentUID, value }))
updateOrCreateComponent({ componentUID, value })
)
); );
const componentsArr = components.map(component => ({ const componentsArr = components.map(component => ({
kind: componentModel.globalId, kind: componentModel.globalId,
@ -222,14 +213,12 @@ module.exports = ({ model, modelKey, strapi }) => {
const dynamiczones = await Promise.all( const dynamiczones = await Promise.all(
dynamiczoneValues.map(value => { dynamiczoneValues.map(value => {
const componentUID = value.__component; const componentUID = value.__component;
return updateOrCreateComponent({ componentUID, value }).then( return updateOrCreateComponent({ componentUID, value }).then(entity => {
entity => { return {
return { componentUID,
componentUID, entity,
entity, };
}; });
}
);
}) })
); );
@ -273,9 +262,7 @@ module.exports = ({ model, modelKey, strapi }) => {
// verify the provided ids are realted to this entity. // verify the provided ids are realted to this entity.
idsToKeep.forEach(({ id, componentUID }) => { idsToKeep.forEach(({ id, componentUID }) => {
if ( if (!allIds.find(el => el.id === id && el.componentUID === componentUID)) {
!allIds.find(el => el.id === id && el.componentUID === componentUID)
) {
const err = new Error( const err = new Error(
`Some of the provided components in ${key} are not related to the entity` `Some of the provided components in ${key} are not related to the entity`
); );
@ -285,9 +272,7 @@ module.exports = ({ model, modelKey, strapi }) => {
}); });
const idsToDelete = allIds.reduce((acc, { id, componentUID }) => { const idsToDelete = allIds.reduce((acc, { id, componentUID }) => {
if ( if (!idsToKeep.find(el => el.id === id && el.componentUID === componentUID)) {
!idsToKeep.find(el => el.id === id && el.componentUID === componentUID)
) {
acc.push({ acc.push({
id, id,
componentUID, componentUID,
@ -317,14 +302,8 @@ module.exports = ({ model, modelKey, strapi }) => {
} }
} }
async function deleteOldComponents( async function deleteOldComponents(entry, componentValue, { key, componentModel }) {
entry, const componentArr = Array.isArray(componentValue) ? componentValue : [componentValue];
componentValue,
{ key, componentModel }
) {
const componentArr = Array.isArray(componentValue)
? componentValue
: [componentValue];
const idsToKeep = componentArr const idsToKeep = componentArr
.filter(val => hasPK(val, componentModel)) .filter(val => hasPK(val, componentModel))
@ -335,7 +314,7 @@ module.exports = ({ model, modelKey, strapi }) => {
.filter(el => el.ref) .filter(el => el.ref)
.map(el => el.ref._id); .map(el => el.ref._id);
// verify the provided ids are realted to this entity. // verify the provided ids are related to this entity.
idsToKeep.forEach(id => { idsToKeep.forEach(id => {
if (allIds.findIndex(currentId => currentId.toString() === id) === -1) { if (allIds.findIndex(currentId => currentId.toString() === id) === -1) {
const err = new Error( const err = new Error(
@ -352,9 +331,7 @@ module.exports = ({ model, modelKey, strapi }) => {
}, []); }, []);
if (idsToDelete.length > 0) { if (idsToDelete.length > 0) {
await strapi await strapi.query(componentModel.uid).delete({ [`${model.primaryKey}_in`]: idsToDelete });
.query(componentModel.uid)
.delete({ [`${model.primaryKey}_in`]: idsToDelete });
} }
} }
@ -415,25 +392,12 @@ module.exports = ({ model, modelKey, strapi }) => {
model, model,
filters, filters,
populate: populateOpt, populate: populateOpt,
}).then(results => }).then(results => results.map(result => (result ? result.toObject() : null)));
results.map(result => (result ? result.toObject() : null))
);
} }
async function findOne(params, populate) { async function findOne(params, populate) {
const primaryKey = getPK(params, model); const entries = await find({ ...params, _limit: 1 }, populate);
return entries[0] || null;
if (primaryKey) {
params = {
[model.primaryKey]: primaryKey,
};
}
const entry = await model
.findOne(params)
.populate(populate || defaultPopulate);
return entry ? entry.toObject() : null;
} }
function count(params) { function count(params) {
@ -463,14 +427,6 @@ module.exports = ({ model, modelKey, strapi }) => {
} }
async function update(params, values) { async function update(params, values) {
const primaryKey = getPK(params, model);
if (primaryKey) {
params = {
[model.primaryKey]: primaryKey,
};
}
const entry = await model.findOne(params); const entry = await model.findOne(params);
if (!entry) { if (!entry) {
@ -493,17 +449,21 @@ module.exports = ({ model, modelKey, strapi }) => {
} }
async function deleteMany(params) { async function deleteMany(params) {
const primaryKey = getPK(params, model); if (params[model.primaryKey]) {
const entries = await find({ ...params, _limit: 1 });
if (primaryKey) return deleteOne(params); if (entries.length > 0) {
return deleteOne(entries[0][model.primaryKey]);
}
return null;
}
const entries = await find(params); const entries = await find(params);
return await Promise.all(entries.map(entry => deleteOne({ id: entry.id }))); return Promise.all(entries.map(entry => deleteOne(entry[model.primaryKey])));
} }
async function deleteOne(params) { async function deleteOne(id) {
const entry = await model const entry = await model
.findOneAndRemove({ [model.primaryKey]: getPK(params, model) }) .findOneAndRemove({ [model.primaryKey]: id })
.populate(defaultPopulate); .populate(defaultPopulate);
if (!entry) { if (!entry) {
@ -521,21 +481,17 @@ module.exports = ({ model, modelKey, strapi }) => {
} }
const search = const search =
_.endsWith(association.nature, 'One') || _.endsWith(association.nature, 'One') || association.nature === 'oneToMany'
association.nature === 'oneToMany'
? { [association.via]: entry._id } ? { [association.via]: entry._id }
: { [association.via]: { $in: [entry._id] } }; : { [association.via]: { $in: [entry._id] } };
const update = const update =
_.endsWith(association.nature, 'One') || _.endsWith(association.nature, 'One') || association.nature === 'oneToMany'
association.nature === 'oneToMany'
? { [association.via]: null } ? { [association.via]: null }
: { $pull: { [association.via]: entry._id } }; : { $pull: { [association.via]: entry._id } };
// Retrieve model. // Retrieve model.
const model = association.plugin const model = association.plugin
? strapi.plugins[association.plugin].models[ ? strapi.plugins[association.plugin].models[association.model || association.collection]
association.model || association.collection
]
: strapi.models[association.model || association.collection]; : strapi.models[association.model || association.collection];
return model.updateMany(search, update); return model.updateMany(search, update);
@ -557,9 +513,7 @@ module.exports = ({ model, modelKey, strapi }) => {
.skip(filters.start) .skip(filters.start)
.limit(filters.limit) .limit(filters.limit)
.populate(populate || defaultPopulate) .populate(populate || defaultPopulate)
.then(results => .then(results => results.map(result => (result ? result.toObject() : null)));
results.map(result => (result ? result.toObject() : null))
);
} }
function countSearch(params) { function countSearch(params) {
@ -623,13 +577,8 @@ function validateRepeatableInput(value, { key, min, max, required }) {
} }
}); });
if ( if ((required === true || (required !== true && value.length > 0)) && min && value.length < min) {
(required === true || (required !== true && value.length > 0)) && const err = new Error(`Component ${key} must contain at least ${min} items`);
(min && value.length < min)
) {
const err = new Error(
`Component ${key} must contain at least ${min} items`
);
err.status = 400; err.status = 400;
throw err; throw err;
} }
@ -655,10 +604,7 @@ function validateNonRepeatableInput(value, { key, required }) {
} }
} }
function validateDynamiczoneInput( function validateDynamiczoneInput(value, { key, min, max, components, required }) {
value,
{ key, min, max, components, required }
) {
if (!Array.isArray(value)) { if (!Array.isArray(value)) {
const err = new Error(`Dynamiczone ${key} is invalid. Expected an array`); const err = new Error(`Dynamiczone ${key} is invalid. Expected an array`);
err.status = 400; err.status = 400;
@ -689,20 +635,13 @@ function validateDynamiczoneInput(
} }
}); });
if ( if ((required === true || (required !== true && value.length > 0)) && min && value.length < min) {
(required === true || (required !== true && value.length > 0)) && const err = new Error(`Dynamiczone ${key} must contain at least ${min} items`);
(min && value.length < min)
) {
const err = new Error(
`Dynamiczone ${key} must contain at least ${min} items`
);
err.status = 400; err.status = 400;
throw err; throw err;
} }
if (max && value.length > max) { if (max && value.length > max) {
const err = new Error( const err = new Error(`Dynamiczone ${key} must contain at most ${max} items`);
`Dynamiczone ${key} must contain at most ${max} items`
);
err.status = 400; err.status = 400;
throw err; throw err;
} }

View File

@ -1,5 +1,7 @@
'use strict'; 'use strict';
const { replaceIdByPrimaryKey } = require('../utils/primary-key');
module.exports = function createQuery(opts) { module.exports = function createQuery(opts) {
return new Query(opts); return new Query(opts);
}; };
@ -35,43 +37,49 @@ class Query {
} }
if (typeof mapping[this.orm] !== 'function') { if (typeof mapping[this.orm] !== 'function') {
throw new Error( throw new Error(`Custom queries must be functions received ${typeof mapping[this.orm]}`);
`Custom queries must be functions received ${typeof mapping[this.orm]}`
);
} }
return mapping[this.model.orm].call(this, { model: this.model }); return mapping[this.model.orm].call(this, { model: this.model });
} }
find(...args) { find(params = {}, ...args) {
return this.connectorQuery.find(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.find(newParams, ...args);
} }
findOne(...args) { findOne(params = {}, ...args) {
return this.connectorQuery.findOne(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.findOne(newParams, ...args);
} }
create(...args) { create(params = {}, ...args) {
return this.connectorQuery.create(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.create(newParams, ...args);
} }
update(...args) { update(params = {}, ...args) {
return this.connectorQuery.update(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.update(newParams, ...args);
} }
delete(...args) { delete(params = {}, ...args) {
return this.connectorQuery.delete(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.delete(newParams, ...args);
} }
count(...args) { count(params = {}, ...args) {
return this.connectorQuery.count(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.count(newParams, ...args);
} }
search(...args) { search(params = {}, ...args) {
return this.connectorQuery.search(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.search(newParams, ...args);
} }
countSearch(...args) { countSearch(params = {}, ...args) {
return this.connectorQuery.countSearch(...args); const newParams = replaceIdByPrimaryKey(params, this.model);
return this.connectorQuery.countSearch(newParams, ...args);
} }
} }

View File

@ -0,0 +1,53 @@
const { replaceIdByPrimaryKey } = require('../primary-key');
describe('Primary Key', () => {
describe('replaceIdByPrimaryKey', () => {
const defaultPostgresModel = { primaryKey: 'id' };
const defaultMongooseModel = { primaryKey: '_id' };
const customModel = { primaryKey: 'aRandomPrimaryKey' };
describe('Model primary key is "id"', () => {
test('Params has "id"', () => {
const result = replaceIdByPrimaryKey({ id: '123', color: 'red' }, defaultPostgresModel);
expect(result).toEqual({ id: '123', color: 'red' });
});
test(`Params doesn't have "id"`, () => {
const result = replaceIdByPrimaryKey({ color: 'red' }, defaultPostgresModel);
expect(result).toEqual({ color: 'red' });
});
});
describe('Model primary key is "_id"', () => {
test('Params has "_id"', () => {
const result = replaceIdByPrimaryKey({ _id: '123', color: 'red' }, defaultMongooseModel);
expect(result).toEqual({ _id: '123', color: 'red' });
});
test('Params has "id"', () => {
const result = replaceIdByPrimaryKey({ id: '123', color: 'red' }, defaultMongooseModel);
expect(result).toEqual({ _id: '123', color: 'red' });
});
test(`Params doesn't have "id" nor "_id"`, () => {
const result = replaceIdByPrimaryKey({ color: 'red' }, defaultMongooseModel);
expect(result).toEqual({ color: 'red' });
});
});
describe('Model primary key is "aRandomPrimaryKey"', () => {
test('Params has "id"', () => {
const result = replaceIdByPrimaryKey({ id: '123', color: 'red' }, customModel);
expect(result).toEqual({ aRandomPrimaryKey: '123', color: 'red' });
});
test('Params has "aRandomPrimaryKey"', () => {
const result = replaceIdByPrimaryKey(
{ aRandomPrimaryKey: '123', color: 'red' },
customModel
);
expect(result).toEqual({ aRandomPrimaryKey: '123', color: 'red' });
});
test(`Params doesn't have "id" nor "aRandomPrimaryKey"`, () => {
const result = replaceIdByPrimaryKey({ color: 'red' }, customModel);
expect(result).toEqual({ color: 'red' });
});
});
});
});

View File

@ -0,0 +1,19 @@
'use strict';
const _ = require('lodash');
/**
* If exists, rename the key "id" by the primary key name of the model ("_id" by default for mongoose).
*/
const replaceIdByPrimaryKey = (params, model) => {
const newParams = { ...params };
if (_.has(params, 'id')) {
delete newParams.id;
newParams[model.primaryKey] = params[model.primaryKey] || params.id;
}
return newParams;
};
module.exports = {
replaceIdByPrimaryKey,
};

View File

@ -45,13 +45,14 @@ module.exports = {
* Returns a list of entities of a content-type matching the query parameters * Returns a list of entities of a content-type matching the query parameters
*/ */
async find(ctx) { async find(ctx) {
const { model } = ctx.params;
const contentManagerService = strapi.plugins['content-manager'].services.contentmanager; const contentManagerService = strapi.plugins['content-manager'].services.contentmanager;
let entities = []; let entities = [];
if (_.has(ctx.request.query, '_q')) { if (_.has(ctx.request.query, '_q')) {
entities = await contentManagerService.search(ctx.params, ctx.request.query); entities = await contentManagerService.search({ model }, ctx.request.query);
} else { } else {
entities = await contentManagerService.fetchAll(ctx.params, ctx.request.query); entities = await contentManagerService.fetchAll({ model }, ctx.request.query);
} }
ctx.body = entities; ctx.body = entities;
@ -61,9 +62,10 @@ module.exports = {
* Returns an entity of a content type by id * Returns an entity of a content type by id
*/ */
async findOne(ctx) { async findOne(ctx) {
const { model, id } = ctx.params;
const contentManagerService = strapi.plugins['content-manager'].services.contentmanager; const contentManagerService = strapi.plugins['content-manager'].services.contentmanager;
const entry = await contentManagerService.fetch(ctx.params); const entry = await contentManagerService.fetch({ model, id });
// Entry not found // Entry not found
if (!entry) { if (!entry) {
@ -77,13 +79,14 @@ module.exports = {
* Returns a count of entities of a content type matching query parameters * Returns a count of entities of a content type matching query parameters
*/ */
async count(ctx) { async count(ctx) {
const { model } = ctx.params;
const contentManagerService = strapi.plugins['content-manager'].services.contentmanager; const contentManagerService = strapi.plugins['content-manager'].services.contentmanager;
let count; let count;
if (_.has(ctx.request.query, '_q')) { if (_.has(ctx.request.query, '_q')) {
count = await contentManagerService.countSearch(ctx.params, ctx.request.query); count = await contentManagerService.countSearch({ model }, ctx.request.query);
} else { } else {
count = await contentManagerService.count(ctx.params, ctx.request.query); count = await contentManagerService.count({ model }, ctx.request.query);
} }
ctx.body = { ctx.body = {
@ -102,18 +105,13 @@ module.exports = {
try { try {
if (ctx.is('multipart')) { if (ctx.is('multipart')) {
const { data, files } = parseMultipartBody(ctx); const { data, files } = parseMultipartBody(ctx);
ctx.body = await contentManagerService.create(data, { ctx.body = await contentManagerService.create(data, { files, model });
files,
model,
});
} else { } else {
// Create an entry using `queries` system // Create an entry using `queries` system
ctx.body = await contentManagerService.create(ctx.request.body, { ctx.body = await contentManagerService.create(ctx.request.body, { model });
model,
});
} }
strapi.emit('didCreateFirstContentTypeEntry', ctx.params); strapi.emit('didCreateFirstContentTypeEntry', { model });
} catch (error) { } catch (error) {
strapi.log.error(error); strapi.log.error(error);
ctx.badRequest(null, [ ctx.badRequest(null, [
@ -161,17 +159,19 @@ module.exports = {
* Deletes one entity of a content type matching a query * Deletes one entity of a content type matching a query
*/ */
async delete(ctx) { async delete(ctx) {
const { id, model } = ctx.params;
const contentManagerService = strapi.plugins['content-manager'].services.contentmanager; const contentManagerService = strapi.plugins['content-manager'].services.contentmanager;
ctx.body = await contentManagerService.delete(ctx.params); ctx.body = await contentManagerService.delete({ id, model });
}, },
/** /**
* Deletes multiple entities of a content type matching a query * Deletes multiple entities of a content type matching a query
*/ */
async deleteMany(ctx) { async deleteMany(ctx) {
const { model } = ctx.params;
const contentManagerService = strapi.plugins['content-manager'].services.contentmanager; const contentManagerService = strapi.plugins['content-manager'].services.contentmanager;
ctx.body = await contentManagerService.deleteMany(ctx.params, ctx.request.query); ctx.body = await contentManagerService.deleteMany({ model }, ctx.request.query);
}, },
}; };

View File

@ -6,10 +6,7 @@ let modelsUtils;
let rq; let rq;
describe.each([ describe.each([
[ ['CONTENT MANAGER', '/content-manager/explorer/application::withcomponent.withcomponent'],
'CONTENT MANAGER',
'/content-manager/explorer/application::withcomponent.withcomponent',
],
['GENERATED API', '/withcomponents'], ['GENERATED API', '/withcomponents'],
])('[%s] => Non repeatable and Not required component', (_, path) => { ])('[%s] => Non repeatable and Not required component', (_, path) => {
beforeAll(async () => { beforeAll(async () => {

View File

@ -96,7 +96,8 @@ module.exports = {
}, },
async findOne(ctx) { async findOne(ctx) {
const data = await strapi.plugins['upload'].services.upload.fetch(ctx.params); const { id } = ctx.params;
const data = await strapi.plugins['upload'].services.upload.fetch({ id });
if (!data) { if (!data) {
return ctx.notFound('file.notFound'); return ctx.notFound('file.notFound');

View File

@ -70,9 +70,7 @@ module.exports = {
} }
// Check if the user exists. // Check if the user exists.
const user = await strapi const user = await strapi.query('user', 'users-permissions').findOne(query);
.query('user', 'users-permissions')
.findOne(query);
if (!user) { if (!user) {
return ctx.badRequest( return ctx.badRequest(
@ -119,9 +117,10 @@ module.exports = {
); );
} }
const validPassword = strapi.plugins[ const validPassword = strapi.plugins['users-permissions'].services.user.validatePassword(
'users-permissions' params.password,
].services.user.validatePassword(params.password, user.password); user.password
);
if (!validPassword) { if (!validPassword) {
return ctx.badRequest( return ctx.badRequest(
@ -155,9 +154,10 @@ module.exports = {
// Connect the user with the third-party provider. // Connect the user with the third-party provider.
let user, error; let user, error;
try { try {
[user, error] = await strapi.plugins[ [user, error] = await strapi.plugins['users-permissions'].services.providers.connect(
'users-permissions' provider,
].services.providers.connect(provider, ctx.query); ctx.query
);
} catch ([user, error]) { } catch ([user, error]) {
return ctx.badRequest(null, error === 'array' ? error[0] : error); return ctx.badRequest(null, error === 'array' ? error[0] : error);
} }
@ -203,14 +203,12 @@ module.exports = {
// Delete the current code // Delete the current code
user.resetPasswordToken = null; user.resetPasswordToken = null;
user.password = await strapi.plugins[ user.password = await strapi.plugins['users-permissions'].services.user.hashPassword({
'users-permissions' password: params.password,
].services.user.hashPassword(params); });
// Update the user. // Update the user.
await strapi await strapi.query('user', 'users-permissions').update({ id: user.id }, user);
.query('user', 'users-permissions')
.update({ id: user.id }, user);
ctx.send({ ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue({ jwt: strapi.plugins['users-permissions'].services.jwt.issue({
@ -258,9 +256,7 @@ module.exports = {
const [requestPath] = ctx.request.url.split('?'); const [requestPath] = ctx.request.url.split('?');
const provider = const provider =
process.platform === 'win32' process.platform === 'win32' ? requestPath.split('\\')[2] : requestPath.split('/')[2];
? requestPath.split('\\')[2]
: requestPath.split('/')[2];
const config = grantConfig[provider]; const config = grantConfig[provider];
if (!_.get(config, 'enabled')) { if (!_.get(config, 'enabled')) {
@ -268,9 +264,7 @@ module.exports = {
} }
// Ability to pass OAuth callback dynamically // Ability to pass OAuth callback dynamically
grantConfig[provider].callback = grantConfig[provider].callback =
ctx.query && ctx.query.callback ctx.query && ctx.query.callback ? ctx.query.callback : grantConfig[provider].callback;
? ctx.query.callback
: grantConfig[provider].callback;
return grant(grantConfig)(ctx, next); return grant(grantConfig)(ctx, next);
}, },
@ -299,9 +293,7 @@ module.exports = {
}); });
// Find the user by email. // Find the user by email.
const user = await strapi const user = await strapi.query('user', 'users-permissions').findOne({ email });
.query('user', 'users-permissions')
.findOne({ email });
// User not found. // User not found.
if (!user) { if (!user) {
@ -320,43 +312,43 @@ module.exports = {
// Set the property code. // Set the property code.
user.resetPasswordToken = resetPasswordToken; user.resetPasswordToken = resetPasswordToken;
const settings = await pluginStore const settings = await pluginStore.get({ key: 'email' }).then(storeEmail => {
.get({ key: 'email' }) try {
.then(storeEmail => { return storeEmail['reset_password'].options;
try { } catch (error) {
return storeEmail['reset_password'].options; return {};
} catch (error) { }
return {}; });
}
});
const advanced = await pluginStore.get({ const advanced = await pluginStore.get({
key: 'advanced', key: 'advanced',
}); });
settings.message = await strapi.plugins[ settings.message = await strapi.plugins['users-permissions'].services.userspermissions.template(
'users-permissions' settings.message,
].services.userspermissions.template(settings.message, { {
URL: advanced.email_reset_password, URL: advanced.email_reset_password,
USER: _.omit(user.toJSON ? user.toJSON() : user, [ USER: _.omit(user.toJSON ? user.toJSON() : user, [
'password', 'password',
'resetPasswordToken', 'resetPasswordToken',
'role', 'role',
'provider', 'provider',
]), ]),
TOKEN: resetPasswordToken, TOKEN: resetPasswordToken,
}); }
);
settings.object = await strapi.plugins[ settings.object = await strapi.plugins['users-permissions'].services.userspermissions.template(
'users-permissions' settings.object,
].services.userspermissions.template(settings.object, { {
USER: _.omit(user.toJSON ? user.toJSON() : user, [ USER: _.omit(user.toJSON ? user.toJSON() : user, [
'password', 'password',
'resetPasswordToken', 'resetPasswordToken',
'role', 'role',
'provider', 'provider',
]), ]),
}); }
);
try { try {
// Send an email to the user. // Send an email to the user.
@ -376,9 +368,7 @@ module.exports = {
} }
// Update the user. // Update the user.
await strapi await strapi.query('user', 'users-permissions').update({ id: user.id }, user);
.query('user', 'users-permissions')
.update({ id: user.id }, user);
ctx.send({ ok: true }); ctx.send({ ok: true });
}, },
@ -432,17 +422,12 @@ module.exports = {
// Throw an error if the password selected by the user // Throw an error if the password selected by the user
// contains more than two times the symbol '$'. // contains more than two times the symbol '$'.
if ( if (strapi.plugins['users-permissions'].services.user.isHashed(params.password)) {
strapi.plugins['users-permissions'].services.user.isHashed(
params.password
)
) {
return ctx.badRequest( return ctx.badRequest(
null, null,
formatError({ formatError({
id: 'Auth.form.error.password.format', id: 'Auth.form.error.password.format',
message: message: 'Your password cannot contain more than three times the symbol `$`.',
'Your password cannot contain more than three times the symbol `$`.',
}) })
); );
} }
@ -477,9 +462,7 @@ module.exports = {
} }
params.role = role.id; params.role = role.id;
params.password = await strapi.plugins[ params.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
'users-permissions'
].services.user.hashPassword(params);
const user = await strapi.query('user', 'users-permissions').findOne({ const user = await strapi.query('user', 'users-permissions').findOne({
email: params.email, email: params.email,
@ -510,32 +493,25 @@ module.exports = {
params.confirmed = true; params.confirmed = true;
} }
const user = await strapi const user = await strapi.query('user', 'users-permissions').create(params);
.query('user', 'users-permissions')
.create(params);
const jwt = strapi.plugins['users-permissions'].services.jwt.issue( const jwt = strapi.plugins['users-permissions'].services.jwt.issue(
_.pick(user.toJSON ? user.toJSON() : user, ['id']) _.pick(user.toJSON ? user.toJSON() : user, ['id'])
); );
if (settings.email_confirmation) { if (settings.email_confirmation) {
const settings = await pluginStore const settings = await pluginStore.get({ key: 'email' }).then(storeEmail => {
.get({ key: 'email' }) try {
.then(storeEmail => { return storeEmail['email_confirmation'].options;
try { } catch (error) {
return storeEmail['email_confirmation'].options; return {};
} catch (error) { }
return {}; });
}
});
settings.message = await strapi.plugins[ settings.message = await strapi.plugins[
'users-permissions' 'users-permissions'
].services.userspermissions.template(settings.message, { ].services.userspermissions.template(settings.message, {
URL: new URL( URL: new URL('/auth/email-confirmation', strapi.config.url).toString(),
'/auth/email-confirmation',
strapi.config.url
).toString(),
USER: _.omit(user.toJSON ? user.toJSON() : user, [ USER: _.omit(user.toJSON ? user.toJSON() : user, [
'password', 'password',
'resetPasswordToken', 'resetPasswordToken',
@ -595,9 +571,9 @@ module.exports = {
async emailConfirmation(ctx) { async emailConfirmation(ctx) {
const params = ctx.query; const params = ctx.query;
const decodedToken = await strapi.plugins[ const decodedToken = await strapi.plugins['users-permissions'].services.jwt.verify(
'users-permissions' params.confirmation
].services.jwt.verify(params.confirmation); );
await strapi.plugins['users-permissions'].services.user.edit( await strapi.plugins['users-permissions'].services.user.edit(
{ id: decodedToken.id }, { id: decodedToken.id },
@ -653,39 +629,39 @@ module.exports = {
_.pick(user.toJSON ? user.toJSON() : user, ['id']) _.pick(user.toJSON ? user.toJSON() : user, ['id'])
); );
const settings = await pluginStore const settings = await pluginStore.get({ key: 'email' }).then(storeEmail => {
.get({ key: 'email' }) try {
.then(storeEmail => { return storeEmail['email_confirmation'].options;
try { } catch (err) {
return storeEmail['email_confirmation'].options; return {};
} catch (err) { }
return {};
}
});
settings.message = await strapi.plugins[
'users-permissions'
].services.userspermissions.template(settings.message, {
URL: new URL('/auth/email-confirmation', strapi.config.url).toString(),
USER: _.omit(user.toJSON ? user.toJSON() : user, [
'password',
'resetPasswordToken',
'role',
'provider',
]),
CODE: jwt,
}); });
settings.object = await strapi.plugins[ settings.message = await strapi.plugins['users-permissions'].services.userspermissions.template(
'users-permissions' settings.message,
].services.userspermissions.template(settings.object, { {
USER: _.omit(user.toJSON ? user.toJSON() : user, [ URL: new URL('/auth/email-confirmation', strapi.config.url).toString(),
'password', USER: _.omit(user.toJSON ? user.toJSON() : user, [
'resetPasswordToken', 'password',
'role', 'resetPasswordToken',
'provider', 'role',
]), 'provider',
}); ]),
CODE: jwt,
}
);
settings.object = await strapi.plugins['users-permissions'].services.userspermissions.template(
settings.object,
{
USER: _.omit(user.toJSON ? user.toJSON() : user, [
'password',
'resetPasswordToken',
'role',
'provider',
]),
}
);
try { try {
await strapi.plugins['email'].services.email.send({ await strapi.plugins['email'].services.email.send({

View File

@ -28,14 +28,9 @@ module.exports = {
if (_.has(ctx.query, '_q')) { if (_.has(ctx.query, '_q')) {
// use core strapi query to search for users // use core strapi query to search for users
users = await strapi users = await strapi.query('user', 'users-permissions').search(ctx.query, populate);
.query('user', 'users-permissions')
.search(ctx.query, populate);
} else { } else {
users = await strapi.plugins['users-permissions'].services.user.fetchAll( users = await strapi.plugins['users-permissions'].services.user.fetchAll(ctx.query, populate);
ctx.query,
populate
);
} }
const data = users.map(sanitizeUser); const data = users.map(sanitizeUser);
@ -50,9 +45,7 @@ module.exports = {
const user = ctx.state.user; const user = ctx.state.user;
if (!user) { if (!user) {
return ctx.badRequest(null, [ return ctx.badRequest(null, [{ messages: [{ id: 'No authorization header was found' }] }]);
{ messages: [{ id: 'No authorization header was found' }] },
]);
} }
const data = sanitizeUser(user); const data = sanitizeUser(user);
@ -113,9 +106,7 @@ module.exports = {
} }
if (advanced.unique_email) { if (advanced.unique_email) {
const userWithSameEmail = await strapi const userWithSameEmail = await strapi.query('user', 'users-permissions').findOne({ email });
.query('user', 'users-permissions')
.findOne({ email });
if (userWithSameEmail) { if (userWithSameEmail) {
return ctx.badRequest( return ctx.badRequest(
@ -144,9 +135,7 @@ module.exports = {
} }
try { try {
const data = await strapi.plugins['users-permissions'].services.user.add( const data = await strapi.plugins['users-permissions'].services.user.add(user);
user
);
ctx.created(data); ctx.created(data);
} catch (error) { } catch (error) {
@ -183,11 +172,7 @@ module.exports = {
return ctx.badRequest('username.notNull'); return ctx.badRequest('username.notNull');
} }
if ( if (_.has(ctx.request.body, 'password') && !password && user.provider === 'local') {
_.has(ctx.request.body, 'password') &&
!password &&
user.provider === 'local'
) {
return ctx.badRequest('password.notNull'); return ctx.badRequest('password.notNull');
} }
@ -209,9 +194,7 @@ module.exports = {
} }
if (_.has(ctx.request.body, 'email') && advancedConfigs.unique_email) { if (_.has(ctx.request.body, 'email') && advancedConfigs.unique_email) {
const userWithSameEmail = await strapi const userWithSameEmail = await strapi.query('user', 'users-permissions').findOne({ email });
.query('user', 'users-permissions')
.findOne({ email });
if (userWithSameEmail && userWithSameEmail.id != id) { if (userWithSameEmail && userWithSameEmail.id != id) {
return ctx.badRequest( return ctx.badRequest(
@ -233,10 +216,7 @@ module.exports = {
delete updateData.password; delete updateData.password;
} }
const data = await strapi.plugins['users-permissions'].services.user.edit( const data = await strapi.plugins['users-permissions'].services.user.edit({ id }, updateData);
{ id },
updateData
);
ctx.send(data); ctx.send(data);
}, },
@ -247,16 +227,15 @@ module.exports = {
*/ */
async destroy(ctx) { async destroy(ctx) {
const { id } = ctx.params; const { id } = ctx.params;
const data = await strapi.plugins['users-permissions'].services.user.remove( const data = await strapi.plugins['users-permissions'].services.user.remove({ id });
{ id }
);
ctx.send(data); ctx.send(data);
}, },
async destroyAll(ctx) { async destroyAll(ctx) {
const data = await strapi.plugins[ const data = await strapi.plugins['users-permissions'].services.user.removeAll(
'users-permissions' {},
].services.user.removeAll(ctx.params, ctx.request.query); ctx.request.query
);
ctx.send(data); ctx.send(data);
}, },

View File

@ -81,7 +81,7 @@ const createCollectionTypeController = ({ model, service }) => {
* @return {Object} * @return {Object}
*/ */
async findOne(ctx) { async findOne(ctx) {
const entity = await service.findOne(ctx.params); const entity = await service.findOne({ id: ctx.params.id });
return sanitizeEntity(entity, { model }); return sanitizeEntity(entity, { model });
}, },
@ -122,9 +122,9 @@ const createCollectionTypeController = ({ model, service }) => {
let entity; let entity;
if (ctx.is('multipart')) { if (ctx.is('multipart')) {
const { data, files } = parseMultipartData(ctx); const { data, files } = parseMultipartData(ctx);
entity = await service.update(ctx.params, data, { files }); entity = await service.update({ id: ctx.params.id }, data, { files });
} else { } else {
entity = await service.update(ctx.params, ctx.request.body); entity = await service.update({ id: ctx.params.id }, ctx.request.body);
} }
return sanitizeEntity(entity, { model }); return sanitizeEntity(entity, { model });
@ -136,7 +136,7 @@ const createCollectionTypeController = ({ model, service }) => {
* @return {Object} * @return {Object}
*/ */
async delete(ctx) { async delete(ctx) {
const entity = await service.delete(ctx.params); const entity = await service.delete({ id: ctx.params.id });
return sanitizeEntity(entity, { model }); return sanitizeEntity(entity, { model });
}, },
}; };