Merge branch 'dev' into fix-fixtures_test
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Carlos Satorres 2023-08-10 08:00:07 +00:00
commit a11905ee63
15 changed files with 63 additions and 43 deletions

View File

@ -7,6 +7,11 @@ module.exports = Self => {
type: 'string',
description: 'The user name or email',
required: true
},
{
arg: 'app',
type: 'string',
description: 'The directory for mail'
}
],
http: {
@ -15,7 +20,7 @@ module.exports = Self => {
}
});
Self.recoverPassword = async function(user) {
Self.recoverPassword = async function(user, app) {
const models = Self.app.models;
const usesEmail = user.indexOf('@') !== -1;
@ -29,7 +34,7 @@ module.exports = Self => {
}
try {
await Self.resetPassword({email: user, emailTemplate: 'recover-password'});
await Self.resetPassword({email: user, emailTemplate: 'recover-password', app});
} catch (err) {
if (err.code === 'EMAIL_NOT_FOUND')
return;

View File

@ -53,19 +53,13 @@ module.exports = Self => {
return Self.validateLogin(user, password);
};
Self.passExpired = async(vnUser, myOptions) => {
Self.passExpired = async vnUser => {
const today = Date.vnNew();
today.setHours(0, 0, 0, 0);
if (vnUser.passExpired && vnUser.passExpired.getTime() <= today.getTime()) {
const $ = Self.app.models;
const changePasswordToken = await $.AccessToken.create({
scopes: ['changePassword'],
userId: vnUser.id
}, myOptions);
const err = new UserError('Pass expired', 'passExpired');
changePasswordToken.twoFactor = vnUser.twoFactor ? true : false;
err.details = {token: changePasswordToken};
err.details = {userId: vnUser.id, twoFactor: vnUser.twoFactor ? true : false};
throw err;
}
};

View File

@ -96,11 +96,21 @@ module.exports = function(Self) {
const headers = httpRequest.headers;
const origin = headers.origin;
const defaultHash = '/reset-password?access_token=$token$';
const recoverHashes = {
hedera: 'verificationToken=$token$'
};
const app = info.options?.app;
let recoverHash = app ? recoverHashes[app] : defaultHash;
recoverHash = recoverHash.replace('$token$', info.accessToken.id);
const user = await Self.app.models.VnUser.findById(info.user.id);
const params = {
recipient: info.email,
lang: user.lang,
url: `${origin}/#!/reset-password?access_token=${info.accessToken.id}`
url: origin + '/#!' + recoverHash
};
const options = Object.assign({}, info.options);

View File

@ -0,0 +1,6 @@
UPDATE `salix`.`ACL`
SET principalId='salesPerson'
WHERE
model='Ticket'
AND property='setDeleted'
AND accessType='WRITE';

View File

@ -10,7 +10,7 @@ describe('Ticket create path', () => {
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.loginAndModule('salesPerson', 'ticket');
});
afterAll(async() => {

View File

@ -15,9 +15,6 @@ export default class Controller {
}
$onInit() {
if (!this.$state.params.id)
this.$state.go('login');
this.$http.get('UserPasswords/findOne')
.then(res => {
this.passRequirements = res.data;
@ -25,7 +22,7 @@ export default class Controller {
}
submit() {
const userId = this.$state.params.userId;
const userId = parseInt(this.$state.params.userId);
const oldPassword = this.oldPassword;
const newPassword = this.newPassword;
const repeatPassword = this.repeatPassword;
@ -36,18 +33,13 @@ export default class Controller {
if (newPassword != this.repeatPassword)
throw new UserError(`Passwords don't match`);
const headers = {
Authorization: this.$state.params.id
};
this.$http.patch('Accounts/change-password',
{
id: userId,
userId,
oldPassword,
newPassword,
code
},
{headers}
}
).then(() => {
this.vnApp.showSuccess(this.$translate.instant('Password updated!'));
this.$state.go('login');

View File

@ -36,7 +36,7 @@ export default class Controller {
const err = req.data?.error;
if (err?.code == 'passExpired')
this.$state.go('change-password', err.details.token);
this.$state.go('change-password', err.details);
this.loading = false;
this.password = '';

View File

@ -45,7 +45,7 @@ function config($stateProvider, $urlRouterProvider) {
})
.state('change-password', {
parent: 'outLayout',
url: '/change-password?id&userId&twoFactor',
url: '/change-password?userId&twoFactor',
description: 'Change password',
template: '<vn-change-password></vn-change-password>'
})

View File

@ -179,6 +179,7 @@
"You can not use the same password": "You can not use the same password",
"Valid priorities": "Valid priorities: %d",
"Negative basis of tickets": "Negative basis of tickets: {{ticketsIds}}",
"This ticket cannot be left empty.": "This ticket cannot be left empty. %s",
"Social name should be uppercase": "Social name should be uppercase",
"Street should be uppercase": "Street should be uppercase",
"You don't have enough privileges.": "You don't have enough privileges.",

View File

@ -306,6 +306,7 @@
"Valid priorities": "Prioridades válidas: %d",
"Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}",
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado",

View File

@ -1,12 +1,15 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('changePassword', {
Self.remoteMethod('changePassword', {
description: 'Changes the user password',
accessType: 'WRITE',
accessScopes: ['changePassword'],
accepts: [
{
arg: 'userId',
type: 'integer',
description: 'The user id',
required: true
}, {
arg: 'oldPassword',
type: 'string',
description: 'The old password',
@ -28,9 +31,7 @@ module.exports = Self => {
}
});
Self.changePassword = async function(ctx, oldPassword, newPassword, code, options) {
const userId = ctx.req.accessToken.userId;
Self.changePassword = async function(userId, oldPassword, newPassword, code, options) {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -1,7 +1,7 @@
const {models} = require('vn-loopback/server/server');
describe('account changePassword()', () => {
const ctx = {req: {accessToken: {userId: 70}}};
const userId = 70;
const unauthCtx = {
req: {
headers: {},
@ -20,7 +20,7 @@ describe('account changePassword()', () => {
try {
const options = {transaction: tx};
await models.Account.changePassword(ctx, 'wrongPassword', 'nightmare.9999', null, options);
await models.Account.changePassword(userId, 'wrongPassword', 'nightmare.9999', null, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
@ -37,8 +37,8 @@ describe('account changePassword()', () => {
try {
const options = {transaction: tx};
await models.Account.changePassword(ctx, 'nightmare', 'nightmare.9999', null, options);
await models.Account.changePassword(ctx, 'nightmare.9999', 'nightmare.9999', null, options);
await models.Account.changePassword(userId, 'nightmare', 'nightmare.9999', null, options);
await models.Account.changePassword(userId, 'nightmare.9999', 'nightmare.9999', null, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
@ -54,7 +54,7 @@ describe('account changePassword()', () => {
try {
const options = {transaction: tx};
await models.Account.changePassword(ctx, 'nightmare', 'nightmare.9999', null, options);
await models.Account.changePassword(userId, 'nightmare', 'nightmare.9999', null, options);
await tx.rollback();
} catch (e) {
await tx.rollback();
@ -86,8 +86,8 @@ describe('account changePassword()', () => {
}
try {
const authCode = await models.AuthCode.findOne({where: {userFk: 70}}, options);
await models.Account.changePassword(ctx, 'nightmare', 'nightmare.9999', authCode.code, options);
const authCode = await models.AuthCode.findOne({where: {userFk: userId}}, options);
await models.Account.changePassword(userId, 'nightmare', 'nightmare.9999', authCode.code, options);
await tx.rollback();
} catch (e) {
await tx.rollback();

View File

@ -46,8 +46,6 @@ class Controller extends Section {
}
deleteRoadmaps() {
console.log(this.checked);
for (const roadmap of this.checked) {
this.$http.delete(`Roadmaps/${roadmap.id}`)
.then(() => this.$.model.refresh())

View File

@ -5,6 +5,8 @@ describe('sale transferSales()', () => {
const userId = 1101;
const activeCtx = {
accessToken: {userId: userId},
headers: {origin: ''},
__: value => value
};
const ctx = {req: activeCtx};

View File

@ -37,6 +37,7 @@ module.exports = Self => {
const userId = ctx.req.accessToken.userId;
const models = Self.app.models;
const myOptions = {userId};
const $t = ctx.req.__; // $translate
let tx;
if (typeof options == 'object')
@ -95,9 +96,18 @@ module.exports = Self => {
const isTicketEmpty = await models.Ticket.isEmpty(id, myOptions);
if (isTicketEmpty) {
await originalTicket.updateAttributes({
isDeleted: true
}, myOptions);
try {
await models.Ticket.setDeleted(ctx, id, myOptions);
} catch (e) {
if (e.statusCode === 400) {
throw new UserError(
`This ticket cannot be left empty.`,
'TRANSFER_SET_DELETED',
$t(e.message, ...e.translateArgs)
);
}
throw e;
}
}
if (tx) await tx.commit();