Add new POST /admin/users route (controller + related services). Update User model: remove required constraint on password field.

Signed-off-by: Convly <jean-sebastien.herbaux@epitech.eu>
This commit is contained in:
Convly 2020-05-13 12:27:46 +02:00 committed by Alexandre Bodin
parent 517f03d1b4
commit 12953bd6f5
5 changed files with 89 additions and 54 deletions

View File

@ -134,6 +134,14 @@
"config": {
"policies": []
}
},
{
"method": "POST",
"path": "/users",
"handler": "User.create",
"config": {
"policies": []
}
}
]
}

View File

@ -0,0 +1,60 @@
'use strict';
const _ = require('lodash');
const formatError = error => [
{ messages: [{ id: error.id, message: error.message, field: error.field }] },
];
const findNextMissingField = (obj, requiredFields) => {
for (const field of requiredFields) {
if (!obj[field]) {
return field;
}
}
};
module.exports = {
async create(ctx) {
const requiredFields = ['firstname', 'lastname', 'email', 'roles'];
const { body } = ctx.request;
const missingField = findNextMissingField(body, requiredFields);
if (missingField !== undefined) {
return ctx.badRequest(
null,
formatError({
id: `missing.${missingField}`,
message: `Missing ${missingField}`,
field: [missingField],
})
);
}
const requiredAttributes = _.pick(body, requiredFields);
const userAlreadyExists = await strapi.admin.services.user.exists({
email: requiredAttributes.email,
});
if (userAlreadyExists) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.email.taken',
message: 'Email already taken',
field: ['email'],
})
);
}
const createdUser = await strapi.admin.services.user.create({
...requiredAttributes,
registrationToken: strapi.admin.services.token.generate(),
});
// Send 201 created
ctx.created(strapi.admin.services.auth.sanitizeUser(createdUser));
},
};

View File

@ -36,7 +36,7 @@
"minLength": 6,
"configurable": false,
"private": true,
"required": true
"required": false
},
"resetPasswordToken": {
"type": "string",

View File

@ -1,47 +1,9 @@
'use strict';
const _ = require('lodash');
const jwt = require('jsonwebtoken');
const defaultOptions = { expiresIn: '30d' };
const getTokenOptions = () => {
const { options, secret } = strapi.config.get('server.admin.auth', {});
return {
secret,
options: _.merge(defaultOptions, options),
};
};
/**
* Creates a JWT token for an administration user
* @param {object} admon - admin user
*/
const createToken = user => {
const { options, secret } = getTokenOptions();
return jwt.sign({ id: user.id }, secret, options);
};
/**
* Tries to decode a token an return its payload and if it is valid
* @param {string} token - a token to decode
* @return {Object} decodeInfo - the decoded info
*/
const decodeToken = token => {
const { secret } = getTokenOptions();
try {
const payload = jwt.verify(token, secret);
return { payload, isValid: true };
} catch (err) {
return { payload: null, isValid: false };
}
};
const crypto = require('crypto');
module.exports = {
createToken,
getTokenOptions,
decodeToken,
generate() {
return crypto.randomBytes(64).toString('hex');
},
};

View File

@ -1,15 +1,20 @@
'use strict';
const _ = require('lodash');
/**
* Remove private user fields
* @param {Object} user - user to sanitize
*/
const sanitizeUser = user => {
return _.omit(user, ['password', 'resetPasswordToken']);
};
module.exports = {
sanitizeUser,
withDefaults(attributes) {
return {
roles: [],
isActive: false,
...attributes,
};
},
async create(attributes) {
const user = this.withDefaults(attributes);
return strapi.query('user', 'admin').create(user);
},
async exists(attributes) {
return !!(await strapi.query('user', 'admin').findOne(attributes));
},
};