2020-05-11 17:09:48 +02:00
|
|
|
'use strict';
|
|
|
|
|
2019-05-24 14:05:25 +02:00
|
|
|
const bcrypt = require('bcryptjs');
|
2020-06-29 11:27:18 +02:00
|
|
|
const _ = require('lodash');
|
2021-04-29 13:51:12 +02:00
|
|
|
const { getAbsoluteAdminUrl } = require('@strapi/utils');
|
2021-07-28 15:32:21 +02:00
|
|
|
const { getService } = require('../utils');
|
2019-05-24 14:05:25 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* hashes a password
|
|
|
|
* @param {string} password - password to hash
|
|
|
|
* @returns {string} hashed password
|
|
|
|
*/
|
|
|
|
const hashPassword = password => bcrypt.hash(password, 10);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate a password
|
|
|
|
* @param {string} password
|
|
|
|
* @param {string} hash
|
|
|
|
* @returns {boolean} is the password valid
|
|
|
|
*/
|
|
|
|
const validatePassword = (password, hash) => bcrypt.compare(password, hash);
|
|
|
|
|
2020-05-11 17:09:48 +02:00
|
|
|
/**
|
|
|
|
* Check login credentials
|
|
|
|
* @param {Object} options
|
|
|
|
* @param {string} options.email
|
|
|
|
* @param {string} options.password
|
|
|
|
*/
|
|
|
|
const checkCredentials = async ({ email, password }) => {
|
2021-06-22 17:13:11 +02:00
|
|
|
const user = await strapi.query('strapi::user').findOne({ where: { email } });
|
2020-05-11 17:09:48 +02:00
|
|
|
|
2020-05-14 16:29:50 +02:00
|
|
|
if (!user || !user.password) {
|
2020-05-12 14:57:24 +02:00
|
|
|
return [null, false, { message: 'Invalid credentials' }];
|
2020-05-11 17:09:48 +02:00
|
|
|
}
|
|
|
|
|
2020-05-13 11:46:52 +02:00
|
|
|
const isValid = await validatePassword(password, user.password);
|
2020-05-11 17:09:48 +02:00
|
|
|
|
|
|
|
if (!isValid) {
|
2020-05-12 14:57:24 +02:00
|
|
|
return [null, false, { message: 'Invalid credentials' }];
|
2020-05-11 17:09:48 +02:00
|
|
|
}
|
|
|
|
|
2020-05-13 11:46:52 +02:00
|
|
|
if (!(user.isActive === true)) {
|
2020-05-12 14:57:24 +02:00
|
|
|
return [null, false, { message: 'User not active' }];
|
2020-05-11 17:09:48 +02:00
|
|
|
}
|
|
|
|
|
2020-05-13 11:46:52 +02:00
|
|
|
return [null, user];
|
2020-05-12 13:21:26 +02:00
|
|
|
};
|
|
|
|
|
2020-05-22 16:01:34 +02:00
|
|
|
/**
|
|
|
|
* Send an email to the user if it exists or do nothing
|
|
|
|
* @param {Object} param params
|
|
|
|
* @param {string} param.email user email for which to reset the password
|
|
|
|
*/
|
|
|
|
const forgotPassword = async ({ email } = {}) => {
|
2021-06-22 17:13:11 +02:00
|
|
|
const user = await strapi.query('strapi::user').findOne({ where: { email, isActive: true } });
|
2020-05-22 13:45:58 +02:00
|
|
|
|
2020-05-22 16:01:34 +02:00
|
|
|
if (!user) {
|
2020-05-22 13:45:58 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-07-28 15:32:21 +02:00
|
|
|
const resetPasswordToken = getService('token').createToken();
|
|
|
|
await getService('user').updateById(user.id, { resetPasswordToken });
|
2020-05-22 13:45:58 +02:00
|
|
|
|
|
|
|
// Send an email to the admin.
|
2020-06-29 11:27:18 +02:00
|
|
|
const url = `${getAbsoluteAdminUrl(
|
|
|
|
strapi.config
|
|
|
|
)}/auth/reset-password?code=${resetPasswordToken}`;
|
2021-08-19 22:27:00 +02:00
|
|
|
return strapi
|
|
|
|
.plugin('email')
|
|
|
|
.service('email')
|
2020-06-29 11:27:18 +02:00
|
|
|
.sendTemplatedEmail(
|
|
|
|
{
|
|
|
|
to: user.email,
|
2020-06-29 14:36:52 +02:00
|
|
|
from: strapi.config.get('server.admin.forgotPassword.from'),
|
|
|
|
replyTo: strapi.config.get('server.admin.forgotPassword.replyTo'),
|
2020-06-29 11:27:18 +02:00
|
|
|
},
|
2020-06-29 14:36:52 +02:00
|
|
|
strapi.config.get('server.admin.forgotPassword.emailTemplate'),
|
2020-06-29 11:27:18 +02:00
|
|
|
{
|
|
|
|
url,
|
|
|
|
user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),
|
|
|
|
}
|
|
|
|
)
|
2020-05-22 16:01:34 +02:00
|
|
|
.catch(err => {
|
|
|
|
// log error server side but do not disclose it to the user to avoid leaking informations
|
|
|
|
strapi.log.error(err);
|
|
|
|
});
|
2020-05-22 13:45:58 +02:00
|
|
|
};
|
|
|
|
|
2020-05-22 16:01:34 +02:00
|
|
|
/**
|
|
|
|
* Reset a user password
|
|
|
|
* @param {Object} param params
|
|
|
|
* @param {string} param.resetPasswordToken token generated to request a password reset
|
|
|
|
* @param {string} param.password new user password
|
|
|
|
*/
|
|
|
|
const resetPassword = async ({ resetPasswordToken, password } = {}) => {
|
2020-05-22 13:58:58 +02:00
|
|
|
const matchingUser = await strapi
|
2021-06-22 17:13:11 +02:00
|
|
|
.query('strapi::user')
|
|
|
|
.findOne({ where: { resetPasswordToken, isActive: true } });
|
2020-05-22 13:58:58 +02:00
|
|
|
|
|
|
|
if (!matchingUser) {
|
2020-05-22 16:01:34 +02:00
|
|
|
throw strapi.errors.badRequest();
|
2020-05-22 13:58:58 +02:00
|
|
|
}
|
|
|
|
|
2021-07-28 15:32:21 +02:00
|
|
|
return getService('user').updateById(matchingUser.id, {
|
2020-06-18 18:10:12 +02:00
|
|
|
password,
|
|
|
|
resetPasswordToken: null,
|
|
|
|
});
|
2020-05-22 13:58:58 +02:00
|
|
|
};
|
|
|
|
|
2019-05-24 14:05:25 +02:00
|
|
|
module.exports = {
|
2020-05-11 17:09:48 +02:00
|
|
|
checkCredentials,
|
2019-05-24 14:05:25 +02:00
|
|
|
validatePassword,
|
|
|
|
hashPassword,
|
2020-05-22 13:45:58 +02:00
|
|
|
forgotPassword,
|
2020-05-22 13:58:58 +02:00
|
|
|
resetPassword,
|
2019-05-24 14:05:25 +02:00
|
|
|
};
|