This commit is contained in:
Joan Sanchez 2023-04-18 13:15:04 +02:00
parent d5ea45e36f
commit c2af40edb5
7 changed files with 55 additions and 82 deletions

View File

@ -33,23 +33,23 @@ module.exports = Self => {
? {email: user} ? {email: user}
: {name: user}; : {name: user};
const account = await Self.findOne({ const vnUser = await Self.findOne({
fields: ['id', 'active', 'email', 'password', 'twoFactor'], fields: ['id', 'active', 'email', 'password', 'twoFactor'],
where where
}); });
if (account && account.twoFactor === 'email') { if (vnUser && vnUser.twoFactor === 'email') {
const code = String(Math.floor(Math.random() * 999999)); const code = String(Math.floor(Math.random() * 999999));
const maxTTL = ((60 * 1000) * 5); // 5 min const maxTTL = ((60 * 1000) * 5); // 5 min
await $.AuthCode.upsertWithWhere({userFk: account.id}, { await $.AuthCode.upsertWithWhere({userFk: vnUser.id}, {
userFk: account.id, userFk: vnUser.id,
code: code, code: code,
expires: Date.now() + maxTTL expires: Date.now() + maxTTL
}); });
const params = { const params = {
recipientId: account.id, recipientId: vnUser.id,
recipient: account.email, recipient: vnUser.email,
code: code code: code
}; };
ctx.args = {...ctx.args, ...params}; ctx.args = {...ctx.args, ...params};
@ -58,6 +58,6 @@ module.exports = Self => {
throw new ForbiddenError('REQUIRES_2FA'); throw new ForbiddenError('REQUIRES_2FA');
} }
return $.models.login(user, password); return Self.validateLogin(user, password);
}; };
}; };

View File

@ -1,68 +0,0 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethod('signIn', {
description: 'Login a user with username/email and password',
accepts: [
{
arg: 'user',
type: 'String',
description: 'The user name or email',
http: {source: 'form'},
required: true
}, {
arg: 'password',
type: 'String',
description: 'The password'
}
],
returns: {
type: 'object',
root: true
},
http: {
path: `/signIn`,
verb: 'POST'
}
});
Self.signIn = async function(user, password) {
let models = Self.app.models;
let token;
let usesEmail = user.indexOf('@') !== -1;
let userInfo = usesEmail
? {email: user}
: {username: user};
let instance = await Self.findOne({
fields: ['username', 'password'],
where: userInfo
});
let where = usesEmail
? {email: user}
: {name: user};
const vnUser = await Self.findOne({
fields: ['active'],
where
});
let validCredentials = instance
&& await instance.hasPassword(password);
if (validCredentials) {
if (!vnUser.active)
throw new UserError('User disabled');
try {
await models.Account.sync(instance.username, password);
} catch (err) {
console.warn(err);
}
}
let loginInfo = Object.assign({password}, userInfo);
token = await Self.login(loginInfo, 'user');
return {token: token.id};
};
};

View File

@ -1,6 +1,6 @@
const {models} = require('vn-loopback/server/server'); const {models} = require('vn-loopback/server/server');
fdescribe('account login()', () => { describe('account login()', () => {
const employeeId = 1; const employeeId = 1;
const unauthCtx = { const unauthCtx = {
req: { req: {

View File

@ -1,12 +1,12 @@
const {models} = require('vn-loopback/server/server'); const {models} = require('vn-loopback/server/server');
describe('VnUser signOut()', () => { fdescribe('VnUser signOut()', () => {
it('should logout and remove token after valid login', async() => { it('should logout and remove token after valid login', async() => {
let loginResponse = await app.models.VnUser.validateLogin('buyer', 'nightmare'); let loginResponse = await app.models.VnUser.validateLogin('buyer', 'nightmare');
let accessToken = await app.models.AccessToken.findById(loginResponse.token); let accessToken = await app.models.AccessToken.findById(loginResponse.token);
let ctx = {req: {accessToken: accessToken}}; let ctx = {req: {accessToken: accessToken}};
let logoutResponse = await models.VnUser.signOut(ctx); let logoutResponse = await models.VnUser.logout(ctx);
let tokenAfterLogout = await models.AccessToken.findById(loginResponse.token); let tokenAfterLogout = await models.AccessToken.findById(loginResponse.token);
expect(logoutResponse).toBeTrue(); expect(logoutResponse).toBeTrue();

View File

@ -68,6 +68,6 @@ module.exports = Self => {
await authCode.destroy(); await authCode.destroy();
return Self.login(username, password); return Self.validateLogin(username, password);
}; };
}; };

View File

@ -5,11 +5,12 @@ const {Email} = require('vn-print');
module.exports = function(Self) { module.exports = function(Self) {
vnModel(Self); vnModel(Self);
require('../methods/vn-user/signIn')(Self); require('../methods/vn-user/sign-in')(Self);
require('../methods/vn-user/acl')(Self); require('../methods/vn-user/acl')(Self);
require('../methods/vn-user/recover-password')(Self); require('../methods/vn-user/recover-password')(Self);
require('../methods/vn-user/validate-token')(Self); require('../methods/vn-user/validate-token')(Self);
require('../methods/vn-user/privileges')(Self); require('../methods/vn-user/privileges')(Self);
require('../methods/vn-user/validate-auth')(Self);
// Validations // Validations
@ -107,4 +108,45 @@ module.exports = function(Self) {
return email.send(); return email.send();
}); });
Self.validateLogin = async function(user, password) {
let $ = Self.app.models;
let token;
let usesEmail = user.indexOf('@') !== -1;
let userInfo = usesEmail
? {email: user}
: {username: user};
let instance = await $.VnUser.findOne({
fields: ['username', 'password'],
where: userInfo
});
let where = usesEmail
? {email: user}
: {name: user};
let vnUser = await $.VnUser.findOne({
fields: ['active'],
where
});
let validCredentials = instance && (
await instance.hasPassword(password)
);
if (validCredentials) {
if (!vnUser.active)
throw new UserError('User disabled');
try {
await $.Account.sync(instance.username, password);
} catch (err) {
console.warn(err);
}
}
let loginInfo = Object.assign({password}, userInfo);
token = await $.VnUser.login(loginInfo, 'user');
return {token: token.id};
};
}; };

View File

@ -3,8 +3,7 @@ INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalTyp
('VnUser', '*', '*', 'ALLOW', 'ROLE', 'employee'), ('VnUser', '*', '*', 'ALLOW', 'ROLE', 'employee'),
('VnUser','acl','READ','ALLOW','ROLE','account'), ('VnUser','acl','READ','ALLOW','ROLE','account'),
('VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'), ('VnUser','getCurrentUserData','READ','ALLOW','ROLE','account'),
('VnUser','changePassword', 'WRITE', 'ALLOW', 'ROLE', 'account'), ('VnUser','changePassword', 'WRITE', 'ALLOW', 'ROLE', 'account');
('Account','exists','READ','ALLOW','ROLE','account');
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
VALUES VALUES