5475 - Autenticación de doble factor por email #1429
Labels
No Milestone
No Assignees
5 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: verdnatura/salix#1429
Loading…
Reference in New Issue
No description provided.
Delete Branch "5475-email_2fa"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Refs #5475
5475 - Autenticación de doble factor por emailto WIP: 5475 - Autenticación de doble factor por emailLo veo bien, pero estaría bien hacer una llamada para que nos explicaras en detalle lo que hace
@ -0,0 +1,24 @@
alter table `vn`.`department`
add `twoFactor` ENUM ('email') null comment 'Default user tow-factor auth type';
two
@ -278,1 +276,3 @@
}
"Added observation": "{{user}} añadió esta observacion: {{text}}",
"Comment added to client": "Observación añadida al cliente {{clientFk}}",
"Invalid auth code": "Invalid auth code",
traduir
WIP: 5475 - Autenticación de doble factor por emailto 5475 - Autenticación de doble factor por emailHe tenido que crear una función común en el modelo (validateLogin()) para poder utilizarla desde /login y desde /validate-auth.
El método no se puede llamar login, si no "signin" porque entra en conflicto con el método login predeterminado del modelo VnUser
@ -0,0 +38,4 @@
where
});
if (vnUser && vnUser.twoFactor === 'email') {
i si no te el twoDactor?
@ -0,0 +1,73 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('validateAuth', {
Aço quan es gasta?
@ -0,0 +1,63 @@
const ForbiddenError = require('vn-loopback/util/forbiddenError');
module.exports = Self => {
Self.remoteMethodCtx('signin', {
Esta ruta no se llama nunca
@ -0,0 +1,24 @@
alter table `vn`.`department`
Este codi el va fer Joan, el aprofitem?
@ -16,6 +16,7 @@ describe('ChangePassword path', async() => {
await browser.close();
});
const badPassword = 'badpass';
badPassword podría ser útil si estás validando la fuerza de una contraseña, donde "mala" puede implicar que la contraseña es débil, demasiado corta, no tiene suficiente variedad de caracteres, etc.
wrongPassword, por otro lado, sugiere que se ha ingresado una contraseña incorrecta, como en un sistema de inicio de sesión, donde el usuario ha proporcionado una contraseña que no coincide con la almacenada para ese nombre de usuario.
Por lo tanto, la elección entre estos dos nombres depende de la situación exacta en la que estés trabajando. Como buena práctica de programación, debes tratar de usar identificadores que sean lo más descriptivos posible y que describan claramente la funcionalidad o el propósito de la variable en cuestión.
@ -2,3 +2,3 @@
import getBrowser from '../../helpers/puppeteer';
describe('Account Alias create and basic data path', () => {
fdescribe('Account Alias create and basic data path', () => {
es un descuido?
@ -38,2 +38,4 @@
"principalId": "$authenticated",
"permission": "ALLOW"
},
{
A modo de curiositat, si gastes ScopeAccess has de possarli ACL sino sempre diu Acceso no permitido. Pero igualment soles funciona si tenen el token en scope
@ -10,16 +10,17 @@ module.exports = {
async send(options) {
options.from = `${config.app.senderName} <${config.app.senderEmail}>`;
if (!process.env.NODE_ENV)
Revisam esta part que es delica
Esta bè
@ -0,0 +2,4 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('signin', {
Poner la i mayúscula:
signIn
@ -0,0 +29,4 @@
Self.signin = async function(ctx, user, password, options) {
const usesEmail = user.indexOf('@') !== -1;
const myOptions = {...(options || {})};
Comprobar si options es un objeto, podría ser el callback
@ -0,0 +33,4 @@
const where = usesEmail
? {email: user}
: {name: user};
Código duplicado con
Self.validateLogin()
, extraer a una función@ -0,0 +50,4 @@
await Self.passExpired(vnUser, myOptions);
if (vnUser.twoFactor)
throw new ForbiddenError('REQUIRES_2FA');
El primer parámetro al instanciar un error es el mensaje, el código va en el segundo parámetro
@ -0,0 +87,4 @@
const headers = ctx.req.headers;
let platform = headers['sec-ch-ua-platform']?.replace(/['"=]+/g, '');
let browser = headers['sec-ch-ua']?.replace(/['"=]+/g, '');
platform y browser son
const
@ -0,0 +33,4 @@
Self.validateAuth = async(username, password, code, options) => {
const myOptions = {...(options || {})};
Validar credenciales antes del código
@ -80,1 +80,3 @@
SELECT id FROM `account`.`user`;
SELECT id
FROM `account`.`user`
WHERE role <> 2;
Es mas claro hacer join con role y usar el nombre del rol
@ -34,2 +36,4 @@
if (newPassword != this.repeatPassword)
throw new UserError(`Passwords don't match`);
if (newPassword == oldPassword)
throw new UserError(`You can not use the same password`);
Esta validación está duplicada con back, quitar del front
@ -27,3 +27,1 @@
this.loading = false;
this.password = '';
this.focusUser();
if (req.message === 'Forbidden') {
Comprobar errores por código, nombre del error o código de respuesta HTTP
@ -32,0 +31,4 @@
Self.changePassword = async function(ctx, oldPassword, newPassword, code, options) {
const userId = ctx.req.accessToken.userId;
const myOptions = {...(options || {})};
Comprobar que options es un objeto, puede ser el callback
@ -32,0 +35,4 @@
const {VnUser} = Self.app.models;
if (oldPassword == newPassword)
throw new UserError(`You can not use the same password`);
Validar contraseña antigua y credenciales del usuario antes de hacer cualquier comprobación/modificación
@ -24,3 +24,3 @@
});
Self.login = async(user, password) => Self.app.models.VnUser.signIn(user, password);
Self.login = async(ctx, user, password, options) => Self.app.models.VnUser.signin(ctx, user, password, options);
Self.login = Self.app.models.VnUser.signin
Unhandled rejection TypeError: Cannot read properties of undefined (reading 'models')
@ -25,1 +24,3 @@
await Self.app.models.VnUser.setPassword(id, newPassword);
Self.setPassword = async function(id, newPassword, options) {
options = typeof options == 'object' ? options : {};
await Self.app.models.VnUser.setPassword(id, newPassword, options);
Self.setPassword = Self.app.models.VnUser.setPassword
Unhandled rejection TypeError: Cannot read properties of undefined (reading 'models')
@ -0,0 +4,4 @@
<h1>{{ $t('title') }}</h1>
<p v-html="$t('description')"></p>
<p v-html="$t('device', [device])"></p>
<p v-html="$t('ip', [ip])"></p>
El uso de la directiva
v-html
no es necesario, dar el estilo con CSS@ -0,0 +47,4 @@
await Self.passExpired(vnUser, myOptions);
if (vnUser.twoFactor)
throw new ForbiddenError(null, 'REQUIRES_2FA');
Revisar que si el parámetro message es null, se utiliza el valor por defecto, si lo tiene.
Revisar que si el parámetro message es null, se utiliza el valor por defecto, si lo tiene.
@ -0,0 +37,4 @@
Object.assign(myOptions, options);
const token = Self.validateLogin(username, password);
await Self.validateCode(username, code, myOptions);
Antes de validar el código, validar las credenciales pero sin generar el token. Despues de validar las credenciales, generar el token.
Hacerlo todo en una transacción.
@ -32,0 +45,4 @@
if (user.twoFactor)
await VnUser.validateCode(user.name, code, myOptions);
await VnUser.changePassword(userId, oldPassword, newPassword, myOptions);
Hacerlo todo en una transacción.