6067-vnUser_privileges_and_verifyEmail #1764

Merged
alexm merged 15 commits from 6067-vnUser_privileges_and_verifyEmail into dev 2023-10-19 12:13:20 +00:00
8 changed files with 43 additions and 22 deletions
Showing only changes of commit 4545a63214 - Show all commits

View File

@ -32,10 +32,8 @@ module.exports = Self => {
} }
}); });
Self.updateUser = async(ctx, id) => { Self.updateUser = async(ctx, id, name, nickname, email, lang) => {
await Self.userSecurity(ctx, id); await Self.userSecurity(ctx, id);
const user = await Self.app.models.VnUser.findById(id, await Self.upsertWithWhere({id}, {name, nickname, email, lang});
{fields: ['id', 'name', 'nickname', 'email', 'lang', 'password']});
await user.updateAttributes(ctx.args);
}; };
alexm marked this conversation as resolved
Review

En lugar de hacer findById y luego updateAttributes, utilizar upsert.

En lugar de hacer `findById` y luego `updateAttributes`, utilizar `upsert`.
}; };
alexm marked this conversation as resolved
Review

En lugar de utilizar ctx.args listar parámetros en la definición de la función y pasarlos todos excepto el id.

En lugar de utilizar `ctx.args` listar parámetros en la definición de la función y pasarlos todos excepto el `id`.

View File

@ -1,4 +1,5 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const ForbiddenError = require('vn-loopback/util/forbiddenError');
describe('loopback model VnUser', () => { describe('loopback model VnUser', () => {
it('should return true if the user has the given role', async() => { it('should return true if the user has the given role', async() => {
@ -46,7 +47,7 @@ describe('loopback model VnUser', () => {
} catch (error) { } catch (error) {
await tx.rollback(); await tx.rollback();
expect(error.message).toEqual(`You don't have enough privileges`); expect(error).toEqual(new ForbiddenError());
} }
}); });
}); });

View File

@ -1,7 +1,7 @@
const vnModel = require('vn-loopback/common/models/vn-model'); const vnModel = require('vn-loopback/common/models/vn-model');
const LoopBackContext = require('loopback-context'); const LoopBackContext = require('loopback-context');
const {Email} = require('vn-print'); const {Email} = require('vn-print');
const UserError = require('vn-loopback/util/user-error'); const ForbiddenError = require('vn-loopback/util/forbiddenError');
module.exports = function(Self) { module.exports = function(Self) {
vnModel(Self); vnModel(Self);
@ -198,11 +198,12 @@ module.exports = function(Self) {
const user = await models.VnUser.findById(userId, {fields: ['id', 'emailVerified']}, myOptions); const user = await models.VnUser.findById(userId, {fields: ['id', 'emailVerified']}, myOptions);
if (!user.emailVerified && hasMediumPrivileges) return; if (!user.emailVerified && hasMediumPrivileges) return;
throw new UserError(`You don't have enough privileges`); throw new ForbiddenError();
}; };
Self.observe('after save', async ctx => { Self.observe('after save', async ctx => {
const newEmail = ctx?.instance?.email; const instance = ctx?.instance;
const newEmail = instance?.email;
const oldEmail = ctx?.hookState?.oldInstance?.email; const oldEmail = ctx?.hookState?.oldInstance?.email;
alexm marked this conversation as resolved
Review

Sobre isNewInstance.
Mirar la nota https://redmine.verdnatura.es/issues/5761#note-8

Sobre isNewInstance. Mirar la nota https://redmine.verdnatura.es/issues/5761#note-8
if (!ctx.isNewInstance && (!newEmail || !oldEmail || newEmail == oldEmail)) return; if (!ctx.isNewInstance && (!newEmail || !oldEmail || newEmail == oldEmail)) return;
@ -213,6 +214,21 @@ module.exports = function(Self) {
const origin = headers.origin; const origin = headers.origin;
const url = origin.split(':'); const url = origin.split(':');
const env = process.env.NODE_ENV;
const liliumUrl = await Self.app.models.Url.findOne({
where: {and: [
{appName: 'lilium'},
{environment: env}
]}
});
const hederaUrl = await Self.app.models.Url.findOne({
where: {and: [
{appName: 'hedera'},
{environment: env}
]}
});
const isWorker = instance.isWorker || await Self.app.models.Account.findById(instance.id, null, ctx.options);
class Mailer { class Mailer {
async send(verifyOptions, cb) { async send(verifyOptions, cb) {
const params = { const params = {
@ -226,12 +242,11 @@ module.exports = function(Self) {
cb(null, verifyOptions.to); cb(null, verifyOptions.to);
} }
} }
const options = { const options = {
type: 'email', type: 'email',
to: newEmail, to: newEmail,
from: {}, from: {},
redirect: `${origin}/#!/account/${ctx.instance.id}/basic-data?emailConfirmed`, redirect: `${liliumUrl.url}verifyEmail?isWorker=${!!isWorker}&url=${hederaUrl.url}`,
template: false, template: false,
mailer: new Mailer, mailer: new Mailer,
host: url[1].split('/')[2], host: url[1].split('/')[2],
@ -240,6 +255,6 @@ module.exports = function(Self) {
user: Self user: Self
}; };
await ctx.instance.verify(options, ctx.options); await instance.verify(options, ctx.options);
}); });
}; };

View File

@ -0,0 +1,4 @@
INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
VALUES
('hedera', 'test', 'https://test-shop.verdnatura.es/'),
('hedera', 'production', 'https://shop.verdnatura.es/');

View File

@ -2869,6 +2869,7 @@ INSERT INTO `vn`.`profileType` (`id`, `name`)
INSERT INTO `salix`.`url` (`appName`, `environment`, `url`) INSERT INTO `salix`.`url` (`appName`, `environment`, `url`)
VALUES VALUES
('lilium', 'development', 'http://localhost:9000/#/'), ('lilium', 'development', 'http://localhost:9000/#/'),
('hedera', 'development', 'http://localhost:9090/'),
('salix', 'development', 'http://localhost:5000/#!/'); ('salix', 'development', 'http://localhost:5000/#!/');
INSERT INTO `vn`.`report` (`id`, `name`, `paperSizeFk`, `method`) INSERT INTO `vn`.`report` (`id`, `name`, `paperSizeFk`, `method`)

View File

@ -1,10 +0,0 @@
module.exports = Self => {
Self.observe('before save', async ctx => {
const instance = ctx.currentInstance || ctx.instance;
await Self.app.models.VnUser.userSecurity(ctx, instance.account);
});
Self.observe('before delete', async ctx => {
await Self.app.models.VnUser.userSecurity(ctx, ctx.where.account);
});
};

View File

@ -21,5 +21,16 @@
"model": "VnUser", "model": "VnUser",
"foreignKey": "account" "foreignKey": "account"
} }
} },
"acls": [{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW"
}, {
"accessType": "WRITE",
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW"
}]
} }

View File

@ -155,6 +155,7 @@ module.exports = Self => {
password: randomPassword.password, password: randomPassword.password,
email: args.email, email: args.email,
roleFk: workerConfig.roleFk, roleFk: workerConfig.roleFk,
isWorker: true // to verifyEmail
}, },
myOptions myOptions
); );