191 lines
7.1 KiB
JavaScript
Raw Normal View History

2017-11-14 11:49:19 +01:00
'use strict';
/**
* Auth.js controller
*
* @description: A set of functions called "actions" for managing `Auth`.
*/
2017-11-16 14:12:03 +01:00
const _ = require('lodash');
2017-11-16 18:00:15 +01:00
const crypto = require('crypto');
2017-11-16 14:12:03 +01:00
2017-11-14 11:49:19 +01:00
module.exports = {
callback: async (ctx) => {
const provider = ctx.params.provider || 'local';
const params = ctx.request.body;
const access_token = ctx.query.access_token;
if (provider === 'local') {
// The identifier is required.
if (!params.identifier) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.email.provide' }] }] : 'Please provide your username or your e-mail.');
2017-11-14 11:49:19 +01:00
}
// The password is required.
if (!params.password) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.password.provide' }] }] : 'Please provide your password.');
2017-11-14 11:49:19 +01:00
}
const query = {};
// Check if the provided identifier is an email or not.
2017-11-16 14:29:49 +01:00
const isEmail = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(params.identifier);
2017-11-14 11:49:19 +01:00
// Set the identifier to the appropriate query field.
if (isEmail) {
query.email = params.identifier;
} else {
query.username = params.identifier;
}
// Check if the user exists.
2017-11-20 16:28:50 +01:00
const user = await strapi.query('user', 'users-permissions').findOne(query);
if (!user) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.invalid' }] }] : 'Identifier or password invalid.');
2017-11-20 16:28:50 +01:00
}
// The user never registered with the `local` provider.
if (!user.password) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.password.local' }] }] : 'This user never set a local password, please login thanks to the provider used during account creation.');
2017-11-20 16:28:50 +01:00
}
const validPassword = strapi.plugins['users-permissions'].services.user.validatePassword(params.password, user.password);
if (!validPassword) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.invalid' }] }] : 'Identifier or password invalid.');
2017-11-20 16:28:50 +01:00
} else {
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
2017-12-07 14:56:25 +01:00
user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken'])
2017-11-20 16:28:50 +01:00
});
2017-11-14 11:49:19 +01:00
}
} else {
// Connect the user thanks to the third-party provider.
2018-01-12 15:20:13 +01:00
const user = await strapi.plugins['users-permissions'].services.providers.connect(provider, access_token);
2017-11-20 16:28:50 +01:00
2018-01-12 15:20:13 +01:00
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken'])
});
2017-11-14 11:49:19 +01:00
}
2017-11-16 14:12:03 +01:00
},
changePassword: async (ctx) => {
const params = _.assign({}, ctx.request.body, ctx.params);
2017-11-16 14:12:03 +01:00
if (params.password && params.passwordConfirmation && params.password === params.passwordConfirmation && params.code) {
const user = await strapi.query('user', 'users-permissions').findOne({ resetPasswordToken: params.code });
2017-11-16 14:12:03 +01:00
if (!user) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.code.provide' }] }] : 'Incorrect code provided.');
}
2017-11-16 14:12:03 +01:00
// Delete the current code
user.resetPasswordToken = null;
2017-11-16 14:12:03 +01:00
user.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
2017-11-16 14:29:49 +01:00
// Update the user.
await strapi.query('user', 'users-permissions').update(user);
2017-12-06 11:47:39 +01:00
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
2017-12-07 14:56:25 +01:00
user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken'])
2017-12-06 11:47:39 +01:00
});
} else if (params.password && params.passwordConfirmation && params.password !== params.passwordConfirmation) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.password.matching' }] }] : 'Passwords do not match.');
} else {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.params.provide' }] }] : 'Incorrect params provided.');
2017-12-06 11:47:39 +01:00
}
2017-11-16 18:00:15 +01:00
},
forgotPassword: async (ctx) => {
2017-12-07 18:16:15 +01:00
const { email, url } = ctx.request.body;
2017-11-16 18:00:15 +01:00
// Find the user user thanks to his email.
const user = await strapi.query('user', 'users-permissions').findOne({ email });
// User not found.
if (!user) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.user.not-exist' }] }] : 'This email does not exist.');
2017-11-16 18:00:15 +01:00
}
// Generate random token.
const resetPasswordToken = crypto.randomBytes(64).toString('hex');
2017-11-17 11:41:23 +01:00
// Set the property code.
2017-11-16 18:00:15 +01:00
user.resetPasswordToken = resetPasswordToken;
2017-12-04 14:00:09 +01:00
// Send an email to the user.
2017-12-04 14:11:00 +01:00
const template = `
<p>We heard that you lost your password. Sorry about that!</p>
<p>But dont worry! You can use the following link to reset your password:</p>
<p>${url}?code=${resetPasswordToken}</p>
<p>Thanks.</p>
`;
2017-12-04 14:00:09 +01:00
try {
await strapi.plugins['email'].services.email.send({
to: user.email,
subject: '­Reset password 🔑 ',
2017-12-04 14:11:00 +01:00
text: template,
html: template
2017-12-04 14:00:09 +01:00
});
} catch (err) {
return ctx.badRequest(null, err);
}
2017-11-16 18:00:15 +01:00
// Update the user.
2017-11-30 11:07:54 +01:00
await strapi.query('user', 'users-permissions').update(user);
2017-11-16 18:00:15 +01:00
ctx.send({ ok: true });
2017-11-17 11:41:23 +01:00
},
register: async (ctx) => {
const params = _.assign(ctx.request.body, {
provider: 'local'
});
2017-11-17 11:41:23 +01:00
// Password is required.
if (!params.password) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.password.provide' }] }] : 'Please provide your password.');
}
2017-11-17 11:41:23 +01:00
// Throw an error if the password selected by the user
// contains more than two times the symbol '$'.
if (strapi.plugins['users-permissions'].services.user.isHashed(params.password)) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.password.format' }] }] : 'Your password cannot contain more than three times the symbol `$`.');
}
2017-11-17 11:41:23 +01:00
// First, check if the user is the first one to register as admin.
const adminUsers = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { role: '0' }));
2017-11-17 11:41:23 +01:00
// Check if the user is the first to register
if (adminUsers.length === 0) {
params.role = '0';
} else {
params.role = '1';
}
2017-11-17 11:41:23 +01:00
params.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
try {
const user = await strapi.query('user', 'users-permissions').create(params);
2017-11-17 11:41:23 +01:00
2017-11-20 16:28:50 +01:00
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
2017-12-07 14:56:25 +01:00
user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken'])
2017-11-20 16:28:50 +01:00
});
} catch(err) {
const adminError = _.includes(err.message, 'username') ? 'Auth.form.error.username.taken' : 'Auth.form.error.email.taken';
ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: adminError }] }] : err.message);
2017-11-17 11:41:23 +01:00
}
2017-11-14 11:49:19 +01:00
}
};