require authentication on every login
gitea/salix/pipeline/head There was a failure building this commit Details

This commit is contained in:
Joan Sanchez 2023-04-18 07:38:40 +02:00
parent 9aaea7e8ed
commit ef87dcc0f5
6 changed files with 72 additions and 35 deletions

View File

@ -1,9 +1,8 @@
const md5 = require('md5');
const UserError = require('vn-loopback/util/user-error');
const ForbiddenError = require('vn-loopback/util/forbiddenError');
module.exports = Self => {
Self.remoteMethodCtx('login', {
Self.remoteMethod('login', {
description: 'Login a user with username/email and password',
accepts: [
{
@ -27,11 +26,13 @@ module.exports = Self => {
}
});
Self.login = async function(ctx, user, password) {
Self.login = async function(user, password) {
let $ = Self.app.models;
let token;
let usesEmail = user.indexOf('@') !== -1;
console.log(user, password);
let userInfo = usesEmail
? {email: user}
: {username: user};
@ -44,7 +45,7 @@ module.exports = Self => {
? {email: user}
: {name: user};
let account = await Self.findOne({
fields: ['id', 'active', 'email', 'password', 'twoFactor'],
fields: ['id', 'active', 'password'],
where
});
@ -64,34 +65,6 @@ module.exports = Self => {
}
}
if (account && account.twoFactor === 'email') {
const authAccess = await $.UserAccess.findOne({
where: {
userFk: account.id,
ip: ctx.req.connection.remoteAddress
}
});
if (!authAccess) {
const code = String(Math.floor(Math.random() * 999999));
const maxTTL = ((60 * 1000) * 5); // 5 min
await $.AuthCode.upsertWithWhere({userFk: account.id}, {
userFk: account.id,
code: code,
expires: Date.now() + maxTTL
});
const params = {
recipientId: account.id,
recipient: account.email,
code: code
};
ctx.args = {...ctx.args, ...params};
await Self.sendTemplate(ctx, 'auth-code');
throw new ForbiddenError('REQUIRES_2FA');
}
}
let loginInfo = Object.assign({password}, userInfo);
token = await $.User.login(loginInfo, 'user');
return {token: token.id};

View File

@ -0,0 +1,63 @@
const ForbiddenError = require('vn-loopback/util/forbiddenError');
module.exports = Self => {
Self.remoteMethodCtx('signin', {
description: 'Login a user with username/email and password',
accepts: [
{
arg: 'user',
type: 'String',
description: 'The user name or email',
required: true
}, {
arg: 'password',
type: 'String',
description: 'The password'
}
],
returns: {
type: 'object',
root: true
},
http: {
path: `/signin`,
verb: 'POST'
}
});
Self.signin = async function(ctx, user, password) {
const $ = Self.app.models;
const usesEmail = user.indexOf('@') !== -1;
const where = usesEmail
? {email: user}
: {name: user};
const account = await Self.findOne({
fields: ['id', 'active', 'email', 'password', 'twoFactor'],
where
});
if (account && account.twoFactor === 'email') {
const code = String(Math.floor(Math.random() * 999999));
const maxTTL = ((60 * 1000) * 5); // 5 min
await $.AuthCode.upsertWithWhere({userFk: account.id}, {
userFk: account.id,
code: code,
expires: Date.now() + maxTTL
});
const params = {
recipientId: account.id,
recipient: account.email,
code: code
};
ctx.args = {...ctx.args, ...params};
await Self.sendTemplate(ctx, 'auth-code');
throw new ForbiddenError('REQUIRES_2FA');
}
return $.models.login(user, password);
};
};

View File

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

View File

@ -4,6 +4,7 @@ const LoopBackContext = require('loopback-context');
const {Email} = require('vn-print');
module.exports = Self => {
require('../methods/account/sign-in')(Self);
require('../methods/account/login')(Self);
require('../methods/account/logout')(Self);
require('../methods/account/acl')(Self);

View File

@ -89,7 +89,7 @@
},
"acls": [
{
"property": "login",
"property": "signin",
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$everyone",

View File

@ -59,7 +59,7 @@ export default class Auth {
password: password || undefined
};
return this.$http.post('Accounts/login', params).then(
return this.$http.post('Accounts/signin', params).then(
json => this.onLoginOk(json, remember));
}