2018-01-23 18:54:17 +01:00

191 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
/**
* Auth.js controller
*
* @description: A set of functions called "actions" for managing `Auth`.
*/
const _ = require('lodash');
const crypto = require('crypto');
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.');
}
// 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.');
}
const query = {};
// Check if the provided identifier is an email or not.
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);
// Set the identifier to the appropriate query field.
if (isEmail) {
query.email = params.identifier;
} else {
query.username = params.identifier;
}
// Check if the user exists.
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.');
}
// 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.');
}
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.');
} else {
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken'])
});
}
} else {
// Connect the user thanks to the third-party provider.
const user = await strapi.api.user.services.grant.connect(provider, access_token);
ctx.redirect(strapi.config.frontendUrl || strapi.config.url + '?jwt=' + strapi.api.user.services.jwt.issue(user) + '&user=' + JSON.stringify(user));
}
},
changePassword: async (ctx) => {
const params = _.assign({}, ctx.request.body, ctx.params);
if (params.password && params.passwordConfirmation && params.password === params.passwordConfirmation && params.code) {
const user = await strapi.query('user', 'users-permissions').findOne({ resetPasswordToken: params.code });
if (!user) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.code.provide' }] }] : 'Incorrect code provided.');
}
// Delete the current code
user.resetPasswordToken = null;
user.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
// Update the user.
await strapi.query('user', 'users-permissions').update(user);
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken'])
});
} 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.');
}
},
forgotPassword: async (ctx) => {
const { email, url } = ctx.request.body;
// 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.');
}
// Generate random token.
const resetPasswordToken = crypto.randomBytes(64).toString('hex');
// Set the property code.
user.resetPasswordToken = resetPasswordToken;
// Send an email to the user.
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>
`;
try {
await strapi.plugins['email'].services.email.send({
to: user.email,
subject: '­Reset password 🔑 ',
text: template,
html: template
});
} catch (err) {
return ctx.badRequest(null, err);
}
// Update the user.
await strapi.query('user', 'users-permissions').update(user);
ctx.send({ ok: true });
},
register: async (ctx) => {
const params = _.assign(ctx.request.body, {
provider: 'local'
});
// Password is required.
if (!params.password) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.password.provide' }] }] : 'Please provide your password.');
}
// 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 `$`.');
}
// Retrieve root role.
const root = await strapi.query('role', 'users-permissions').findOne({ type: 'root' }, ['users']);
// First, check if the user is the first one to register as admin.
const hasAdmin = root.users.length > 0;
// Check if the user is the first to register
const role = hasAdmin === false ? root : await strapi.query('role', 'users-permissions').findOne({ type: 'guest' }, []);
if (!role) {
return ctx.badRequest(null, ctx.request.admin ? [{ messages: [{ id: 'Auth.form.error.role.notFound' }] }] : 'Impossible to find the root role.');
}
params.role = role._id || role.id;
params.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
try {
const user = await strapi.query('user', 'users-permissions').create(params);
ctx.send({
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
user: _.omit(user.toJSON ? user.toJSON() : user, ['password', 'resetPasswordToken'])
});
} 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);
}
}
};