mirror of
https://github.com/strapi/strapi.git
synced 2025-07-27 02:44:13 +00:00
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:
parent
517f03d1b4
commit
12953bd6f5
@ -134,6 +134,14 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"policies": []
|
"policies": []
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/users",
|
||||||
|
"handler": "User.create",
|
||||||
|
"config": {
|
||||||
|
"policies": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
60
packages/strapi-admin/controllers/User.js
Normal file
60
packages/strapi-admin/controllers/User.js
Normal 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));
|
||||||
|
},
|
||||||
|
};
|
@ -36,7 +36,7 @@
|
|||||||
"minLength": 6,
|
"minLength": 6,
|
||||||
"configurable": false,
|
"configurable": false,
|
||||||
"private": true,
|
"private": true,
|
||||||
"required": true
|
"required": false
|
||||||
},
|
},
|
||||||
"resetPasswordToken": {
|
"resetPasswordToken": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -1,47 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const _ = require('lodash');
|
const crypto = require('crypto');
|
||||||
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 };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createToken,
|
generate() {
|
||||||
getTokenOptions,
|
return crypto.randomBytes(64).toString('hex');
|
||||||
decodeToken,
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
'use strict';
|
'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 = {
|
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));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user