246 lines
6.9 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) {
ctx.status = 400;
return ctx.body = {
message: 'Please provide your username or your e-mail.'
};
}
// The password is required.
if (!params.password) {
ctx.status = 400;
return ctx.body = {
message: 'Please provide your password.'
};
}
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.
try {
2017-11-16 14:29:49 +01:00
const user = await strapi.query('user', 'users-permissions').findOne(query);
2017-11-14 11:49:19 +01:00
if (!user) {
ctx.status = 403;
return ctx.body = {
message: 'Identifier or password invalid.'
};
}
// The user never registered with the `local` provider.
if (!user.password) {
ctx.status = 400;
return ctx.body = {
message: 'This user never set a local password, please login thanks to the provider used during account creation.'
};
}
2017-11-16 14:29:49 +01:00
const validPassword = strapi.plugins['users-permissions'].services.user.validatePassword(params.password, user.password);
2017-11-14 11:49:19 +01:00
if (!validPassword) {
ctx.status = 403;
return ctx.body = {
message: 'Identifier or password invalid.'
};
} else {
ctx.status = 200;
ctx.body = {
2017-11-16 14:29:49 +01:00
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
2017-11-14 11:49:19 +01:00
user: user
};
}
} catch (err) {
ctx.status = 500;
return ctx.body = {
message: err.message
};
}
} else {
// Connect the user thanks to the third-party provider.
try {
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));
} catch (err) {
ctx.status = 500;
return ctx.body = {
message: err.message
};
}
}
2017-11-16 14:12:03 +01:00
},
register: async (ctx) => {
const params = _.assign(ctx.request.body, {
provider: 'local'
});
// Password is required.
if (!params.password) {
ctx.status = 400;
return ctx.body = {
message: 'Invalid password field.'
};
}
// 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)) {
ctx.status = 400;
return ctx.body = {
message: 'Your password can not contain more than three times the symbol `$`.'
};
}
2017-11-17 12:05:03 +01:00
// First, check if the user is the first one to register as admin.
2017-11-16 14:12:03 +01:00
try {
2017-11-17 16:05:02 +01:00
const adminUsers = await strapi.query('user', 'users-permissions').find({ admin: true });
2017-11-16 14:12:03 +01:00
// Check if the user is the first to register
2017-11-17 12:05:03 +01:00
if (adminUsers.length === 0) {
2017-11-16 14:12:03 +01:00
params.admin = true;
}
2017-11-16 14:29:49 +01:00
params.password = await strapi.plugins['users-permissions'].services.user.hashPassword(params);
2017-11-16 14:12:03 +01:00
const user = await strapi.query('user', 'users-permissions').create({
values: params
});
ctx.status = 200;
ctx.body = {
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
user: user
};
} catch (err) {
ctx.status = 500;
return ctx.body = {
message: err.message
};
}
2017-11-16 18:00:15 +01:00
},
forgotPassword: async (ctx) => {
const email = ctx.request.body.email;
const url = ctx.request.body.url;
// Find the user user thanks to his email.
const user = await strapi.query('user', 'users-permissions').findOne({ email });
// User not found.
if (!user) {
ctx.status = 400;
return ctx.body = {
message: 'This email does not exist.'
};
}
// 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;
// Update the user.
await strapi.query('user', 'users-permissions').update({
id: user.id,
values: user
});
// Send an email to the user.
try {
await strapi.plugins['email'].services.email.send({
to: user.email,
subject: 'Reset password',
text: url + '?code=' + resetPasswordToken,
html: url + '?code=' + resetPasswordToken
});
ctx.status = 200;
ctx.body = {};
} catch (err) {
ctx.status = 500;
ctx.body = {
message: 'Error sending the email'
};
}
2017-11-17 11:41:23 +01:00
},
changePassword: async (ctx) => {
const params = _.assign({}, ctx.request.body, ctx.params);
if (params.password && params.passwordConfirmation && params.password === params.passwordConfirmation && params.code) {
try {
const user = await strapi.query('user', 'users-permissions').findOne({ resetPasswordToken: params.code });
if (!user) {
ctx.status = 400;
return ctx.body = {
message: '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({
id: user.id,
values: user
});
ctx.status = 200;
return ctx.body = {
jwt: strapi.plugins['users-permissions'].services.jwt.issue(user),
user: user
};
} catch (err) {
ctx.status = 500;
return ctx.body = {
message: err.message
};
}
} else if (params.password && params.passwordConfirmation && params.password !== params.passwordConfirmation) {
ctx.status = 400;
return ctx.body = {
message: 'Passwords not matching.'
};
} else {
ctx.status = 400;
return ctx.body = {
status: 'error',
message: 'Incorrect params provided.'
};
}
2017-11-14 11:49:19 +01:00
}
};