From 956b3e05f8ea81ad653a823b62f9fa12d9a768ce Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 27 Jan 2023 07:56:51 +0100 Subject: [PATCH 01/11] hotfix delete saleChecked from vnClean --- db/changes/230201/00-kkearSaleChecked.sql | 171 ++++++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/db/changes/230201/00-kkearSaleChecked.sql b/db/changes/230201/00-kkearSaleChecked.sql index 03e854bbd..3ea107da5 100644 --- a/db/changes/230201/00-kkearSaleChecked.sql +++ b/db/changes/230201/00-kkearSaleChecked.sql @@ -1,2 +1,173 @@ DELETE FROM `salix`.`ACL` WHERE model="SaleChecked"; DROP TABLE IF EXISTS `vn`.`saleChecked`; +DROP PROCEDURE IF EXISTS `vn`.`clean`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clean`() +BEGIN + DECLARE vDateShort DATETIME; + DECLARE vOneYearAgo DATE; + DECLARE vFourYearsAgo DATE; + DECLARE v18Month DATE; + DECLARE v26Month DATE; + DECLARE v3Month DATE; + DECLARE vTrashId VARCHAR(15); + + SET vDateShort = util.VN_CURDATE() - INTERVAL 2 MONTH; + SET vOneYearAgo = util.VN_CURDATE() - INTERVAL 1 YEAR; + SET vFourYearsAgo = util.VN_CURDATE() - INTERVAL 4 YEAR; + SET v18Month = util.VN_CURDATE() - INTERVAL 18 MONTH; + SET v26Month = util.VN_CURDATE() - INTERVAL 26 MONTH; + SET v3Month = util.VN_CURDATE() - INTERVAL 3 MONTH; + + DELETE FROM ticketParking WHERE created < vDateShort; + DELETE FROM routesMonitor WHERE dated < vDateShort; + DELETE FROM workerTimeControlLog WHERE created < vDateShort; + DELETE FROM `message` WHERE sendDate < vDateShort; + DELETE FROM messageInbox WHERE sendDate < vDateShort; + DELETE FROM messageInbox WHERE sendDate < vDateShort; + DELETE FROM workerTimeControl WHERE timed < vFourYearsAgo; + DELETE FROM itemShelving WHERE created < util.VN_CURDATE() AND visible = 0; + DELETE FROM ticketDown WHERE created < TIMESTAMPADD(DAY,-1,util.VN_CURDATE()); + DELETE FROM entryLog WHERE creationDate < vDateShort; + DELETE IGNORE FROM expedition WHERE created < v26Month; + DELETE FROM sms WHERE created < v18Month; + DELETE FROM saleTracking WHERE created < vOneYearAgo; + DELETE FROM ticketTracking WHERE created < v18Month; + DELETE tobs FROM ticketObservation tobs + JOIN ticket t ON tobs.ticketFk = t.id WHERE t.shipped < TIMESTAMPADD(YEAR,-2,util.VN_CURDATE()); + DELETE sc.* FROM saleCloned sc JOIN sale s ON s.id = sc.saleClonedFk JOIN ticket t ON t.id = s.ticketFk WHERE t.shipped < vOneYearAgo; + DELETE FROM sharingCart where ended < vDateShort; + DELETE FROM sharingClient where ended < vDateShort; + DELETE tw.* FROM ticketWeekly tw + LEFT JOIN sale s ON s.ticketFk = tw.ticketFk WHERE s.itemFk IS NULL; + DELETE FROM claim WHERE ticketCreated < vFourYearsAgo; + DELETE FROM message WHERE sendDate < vDateShort; + -- Robert ubicacion anterior de trevelLog comentario para debug + DELETE FROM zoneEvent WHERE `type` = 'day' AND dated < v3Month; + DELETE bm + FROM buyMark bm + JOIN buy b ON b.id = bm.id + JOIN entry e ON e.id = b.entryFk + JOIN travel t ON t.id = e.travelFk + WHERE t.landed <= vDateShort; + DELETE FROM vn.buy WHERE created < vDateShort AND entryFk = 9200; + DELETE FROM vn.itemShelvingLog WHERE created < vDateShort; + DELETE FROM vn.stockBuyed WHERE creationDate < vDateShort; + DELETE FROM vn.itemCleanLog WHERE created < util.VN_NOW() - INTERVAL 1 YEAR; + DELETE FROM printQueue WHERE statusCode = 'printed' AND created < vDateShort; + + -- Equipos duplicados + DELETE w.* + FROM workerTeam w + JOIN (SELECT id, team, workerFk, COUNT(*) - 1 as duplicated + FROM workerTeam + GROUP BY team,workerFk + HAVING duplicated + ) d ON d.team = w.team AND d.workerFk = w.workerFk AND d.id != w.id; + + DELETE sc + FROM saleComponent sc + JOIN sale s ON s.id= sc.saleFk + JOIN ticket t ON t.id= s.ticketFk + WHERE t.shipped < v18Month; + + DELETE c + FROM vn.claim c + JOIN vn.claimState cs ON cs.id = c.claimStateFk + WHERE cs.description = "Anulado" AND + c.created < vDateShort; + DELETE + FROM vn.expeditionTruck + WHERE ETD < v3Month; + + -- borrar travels sin entradas + DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete; + CREATE TEMPORARY TABLE tmp.thermographToDelete + SELECT th.id,th.dmsFk + FROM vn.travel t + LEFT JOIN vn.entry e ON e.travelFk = t.id + JOIN vn.travelThermograph th ON th.travelFk = t.id + WHERE t.shipped < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND e.travelFk IS NULL; + + SELECT dt.id INTO vTrashId + FROM vn.dmsType dt + WHERE dt.code = 'trash'; + + UPDATE tmp.thermographToDelete th + JOIN vn.dms d ON d.id = th.dmsFk + SET d.dmsTypeFk = vTrashId; + + DELETE th + FROM tmp.thermographToDelete tmp + JOIN vn.travelThermograph th ON th.id = tmp.id; + + DELETE t + FROM vn.travel t + LEFT JOIN vn.entry e ON e.travelFk = t.id + WHERE t.shipped < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND e.travelFk IS NULL; + + UPDATE dms d + JOIN dmsType dt ON dt.id = d.dmsTypeFk + SET d.dmsTypeFk = vTrashId + WHERE created < TIMESTAMPADD(MONTH, -dt.monthToDelete, util.VN_CURDATE()); + + -- borrar entradas sin compras + DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; + CREATE TEMPORARY TABLE tmp.entryToDelete + SELECT e.* + FROM vn.entry e + LEFT JOIN vn.buy b ON b.entryFk = e.id + JOIN vn.entryConfig ec ON e.id != ec.defaultEntry + WHERE e.dated < TIMESTAMPADD(MONTH, -3, util.VN_CURDATE()) AND b.entryFK IS NULL; + + DELETE e + FROM vn.entry e + JOIN tmp.entryToDelete tmp ON tmp.id = e.id; + + -- borrar de route registros menores a 4 años + DROP TEMPORARY TABLE IF EXISTS tmp.routeToDelete; + CREATE TEMPORARY TABLE tmp.routeToDelete + SELECT * + FROM vn.route r + WHERE created < TIMESTAMPADD(YEAR,-4,util.VN_CURDATE()); + + UPDATE tmp.routeToDelete tmp + JOIN vn.dms d ON d.id = tmp.gestdocFk + SET d.dmsTypeFk = vTrashId; + + DELETE r + FROM tmp.routeToDelete tmp + JOIN vn.route r ON r.id = tmp.id; + + -- borrar registros de dua y awb menores a 2 años + DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete; + CREATE TEMPORARY TABLE tmp.duaToDelete + SELECT * + FROM vn.dua + WHERE operated < TIMESTAMPADD(YEAR,-2,util.VN_CURDATE()); + + UPDATE tmp.duaToDelete tm + JOIN vn.dms d ON d.id = tm.gestdocFk + SET d.dmsTypeFk = vTrashId; + + DELETE d + FROM tmp.duaToDelete tmp + JOIN vn.dua d ON d.id = tmp.id; + + DELETE FROM vn.awb WHERE created < TIMESTAMPADD(YEAR,-2,util.VN_CURDATE()); + + -- Borra los registros de collection y ticketcollection + DELETE FROM vn.collection WHERE created < vDateShort; + + DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete; + DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete; + DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete; + + DELETE FROM travelLog WHERE creationDate < v3Month; + + CALL shelving_clean; + +END$$ +DELIMITER ; From fccfabdcd1389c1f6a72d7c9f02b1fc215fb8a43 Mon Sep 17 00:00:00 2001 From: alexandre Date: Fri, 27 Jan 2023 08:31:14 +0100 Subject: [PATCH 02/11] hotfix viewReceipt clientBalance --- modules/client/front/balance/create/index.js | 2 +- modules/client/front/balance/create/index.spec.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/client/front/balance/create/index.js b/modules/client/front/balance/create/index.js index 35b2e0b38..236834263 100644 --- a/modules/client/front/balance/create/index.js +++ b/modules/client/front/balance/create/index.js @@ -4,7 +4,6 @@ import Dialog from 'core/components/dialog'; class Controller extends Dialog { constructor($element, $, $transclude, vnReport) { super($element, $, $transclude); - this.viewReceipt = true; this.vnReport = vnReport; this.receipt = {}; } @@ -59,6 +58,7 @@ class Controller extends Dialog { if (value) { const accountingType = value.accountingType; + this.viewReceipt = accountingType.code == 'cash'; if (this.originalDescription) { this.receipt.description = `${accountingType && accountingType.receiptDescription}, ${this.originalDescription}`; diff --git a/modules/client/front/balance/create/index.spec.js b/modules/client/front/balance/create/index.spec.js index 2c4ed1940..fa6b48ea4 100644 --- a/modules/client/front/balance/create/index.spec.js +++ b/modules/client/front/balance/create/index.spec.js @@ -75,7 +75,6 @@ describe('Client', () => { jest.spyOn(controller.vnReport, 'show'); controller.$params = {id: 1101}; - controller.viewReceipt = false; $httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1}); controller.responseHandler('accept'); From 788ebd413347d181ecb18e9e4d11de1b1d2d3d88 Mon Sep 17 00:00:00 2001 From: alexm Date: Mon, 30 Jan 2023 07:50:37 +0100 Subject: [PATCH 03/11] refactor(recover-password): recovery password label --- front/salix/components/recover-password/index.html | 2 +- front/salix/components/recover-password/locale/es.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/front/salix/components/recover-password/index.html b/front/salix/components/recover-password/index.html index 73f5401d9..b7587148b 100644 --- a/front/salix/components/recover-password/index.html +++ b/front/salix/components/recover-password/index.html @@ -1,6 +1,6 @@
Recover password
diff --git a/front/salix/components/recover-password/locale/es.yml b/front/salix/components/recover-password/locale/es.yml index b71c71415..f53ed937e 100644 --- a/front/salix/components/recover-password/locale/es.yml +++ b/front/salix/components/recover-password/locale/es.yml @@ -1,3 +1,4 @@ Recover password: Recuperar contraseña We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña Notification sent!: ¡Notificación enviada! +Recovery email: Correo de recuperación From 109556ae2eb647efb2e688305e4d69bc0cf2ea70 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 12:39:47 +0100 Subject: [PATCH 04/11] refs #5122 Hotfix: Basic implementation for payment confirmation --- .../back/methods/tpv-transaction/confirm.js | 47 +++++++++++++++++++ modules/client/back/models/tpv-transaction.js | 3 ++ 2 files changed, 50 insertions(+) create mode 100644 modules/client/back/methods/tpv-transaction/confirm.js create mode 100644 modules/client/back/models/tpv-transaction.js diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js new file mode 100644 index 000000000..21484b220 --- /dev/null +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -0,0 +1,47 @@ + +module.exports = Self => { + Self.remoteMethod('confirm', { + description: 'Confirms electronic payment transaction', + accessType: 'WRITE', + accepts: [ + { + arg: 'Ds_SignatureVersion', + type: 'string', + required: true, + }, { + arg: 'Ds_MerchantParameters', + type: 'string', + required: true, + }, { + arg: 'Ds_Signature', + type: 'string', + required: true, + } + ], + returns: { + type: 'Boolean', + root: true + }, + http: { + path: `/confirm`, + verb: 'POST' + } + }); + + Self.confirm = async(signatureVersion, merchantParameters, signature) => { + const buffer = Buffer.from(merchantParameters, 'base64'); + const params = JSON.parse(buffer.toString()); + console.debug('Payment confirmation received:', params); + await Self.rawSql( + 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ + params['Ds_Amount'], + params['Ds_Order'], + params['Ds_MerchantCode'], + params['Ds_Currency'], + params['Ds_Response'], + params['Ds_ErrorCode'] + ] + ); + return true; + }; +}; diff --git a/modules/client/back/models/tpv-transaction.js b/modules/client/back/models/tpv-transaction.js new file mode 100644 index 000000000..b511ae52e --- /dev/null +++ b/modules/client/back/models/tpv-transaction.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/tpv-transaction/confirm')(Self); +}; From 5744759d53da3f8d38b336b06d6737c2fd3b9e6f Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 17:33:15 +0100 Subject: [PATCH 05/11] refs #5122 Hotfix: Signature verification --- .../back/methods/tpv-transaction/confirm.js | 74 +++++++++++++++++-- package-lock.json | 18 ++++- package.json | 1 + 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 21484b220..8c7d10558 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -1,3 +1,6 @@ +const crypto = require('crypto'); +const UserError = require('vn-loopback/util/user-error'); +const base64url = require('base64url'); module.exports = Self => { Self.remoteMethod('confirm', { @@ -7,7 +10,7 @@ module.exports = Self => { { arg: 'Ds_SignatureVersion', type: 'string', - required: true, + required: false, }, { arg: 'Ds_MerchantParameters', type: 'string', @@ -28,15 +31,64 @@ module.exports = Self => { } }); + /* + * Source: https://github.com/santiperez/node-redsys-api + */ Self.confirm = async(signatureVersion, merchantParameters, signature) => { - const buffer = Buffer.from(merchantParameters, 'base64'); - const params = JSON.parse(buffer.toString()); - console.debug('Payment confirmation received:', params); + const $ = Self.app.models; + + const decodedParams = JSON.parse( + base64url.decode(merchantParameters, 'utf8')); + const params = {}; + + for (const param in decodedParams) + params[param] = decodeURIComponent(decodedParams[param]); + + console.debug('Payment confirmation received:', { + signatureVersion, + merchantParameters, + signature, + params + }); + + const orderId = params['Ds_Order']; + const merchantId = parseInt(params['Ds_MerchantCode']); + + if (!orderId) + throw new UserError('Order id not found'); + if (!merchantId) + throw new UserError('Mechant id not found'); + + const merchant = await $.TpvMerchant.findById(merchantId, { + fields: ['id', 'secretKey'] + }); + + const secretKey = Buffer.from(merchant.secretKey, 'base64'); + const iv = Buffer.alloc(8, 0); + + const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); + cipher.setAutoPadding(false); + const orderKey = cipher.update(zeroPad(str, 8), 'utf8', 'base64') + + cipher.final('utf8'); + + const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) + .update(merchantParameters) + .digest('base64'); + const base64Res = base64url.encode(res, 'base64'); + + // if (base64Res !== signature) + // throw new UserError('Invalid signature'); + + console.debug('Payment signature:', { + res, + base64Res + }); + await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ params['Ds_Amount'], - params['Ds_Order'], - params['Ds_MerchantCode'], + orderId, + merchantId, params['Ds_Currency'], params['Ds_Response'], params['Ds_ErrorCode'] @@ -44,4 +96,14 @@ module.exports = Self => { ); return true; }; + + function zeroPad(buf, blocksize) { + const buffer = typeof buf === 'string' ? Buffer.from(buf, 'utf8') : buf; + const pad = Buffer.alloc((blocksize - (buffer.length % blocksize)) % blocksize, 0); + return Buffer.concat([buffer, pad]); + } + + function base64UrlDecode() { + + } }; diff --git a/package-lock.json b/package-lock.json index 31820196f..61180fa3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "salix-back", - "version": "9.0.0", + "version": "23.02.03", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "salix-back", - "version": "9.0.0", + "version": "23.02.03", "license": "GPL-3.0", "dependencies": { "axios": "^1.2.2", + "base64url": "^3.0.1", "bcrypt": "^5.0.1", "bmp-js": "^0.1.0", "compression": "^1.7.3", @@ -4200,6 +4201,14 @@ "node": ">= 0.4" } }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/batch": { "version": "0.6.1", "dev": true, @@ -29057,6 +29066,11 @@ "base64-js": { "version": "1.0.2" }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, "batch": { "version": "0.6.1", "dev": true diff --git a/package.json b/package.json index 2031da475..85f8feb13 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "axios": "^1.2.2", + "base64url": "^3.0.1", "bcrypt": "^5.0.1", "bmp-js": "^0.1.0", "compression": "^1.7.3", From b20194b6d08f46b1c256f88134777e4fcc9a7c51 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 17:45:36 +0100 Subject: [PATCH 06/11] #5174 Hotfix --- modules/client/back/methods/tpv-transaction/confirm.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 8c7d10558..8099475d7 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -68,7 +68,7 @@ module.exports = Self => { const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); - const orderKey = cipher.update(zeroPad(str, 8), 'utf8', 'base64') + const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') + cipher.final('utf8'); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) @@ -102,8 +102,4 @@ module.exports = Self => { const pad = Buffer.alloc((blocksize - (buffer.length % blocksize)) % blocksize, 0); return Buffer.concat([buffer, pad]); } - - function base64UrlDecode() { - - } }; From d6794cb4c8fdbc88d716b9272812a60c583cab31 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 19:51:01 +0100 Subject: [PATCH 07/11] #5174 Hotfix --- .../back/methods/tpv-transaction/confirm.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 8099475d7..5d04f8a81 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -44,13 +44,6 @@ module.exports = Self => { for (const param in decodedParams) params[param] = decodeURIComponent(decodedParams[param]); - console.debug('Payment confirmation received:', { - signatureVersion, - merchantParameters, - signature, - params - }); - const orderId = params['Ds_Order']; const merchantId = parseInt(params['Ds_MerchantCode']); @@ -69,20 +62,15 @@ module.exports = Self => { const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final('utf8'); + + cipher.final(); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) .update(merchantParameters) .digest('base64'); const base64Res = base64url.encode(res, 'base64'); - // if (base64Res !== signature) - // throw new UserError('Invalid signature'); - - console.debug('Payment signature:', { - res, - base64Res - }); + if (base64Res !== signature) + throw new UserError('Invalid signature'); await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ From 339cdab3c42090011d1388836810be4e3cfaef28 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 19:59:46 +0100 Subject: [PATCH 08/11] refs #5174 Debug enabled --- .../back/methods/tpv-transaction/confirm.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 5d04f8a81..1ca2265a6 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -44,6 +44,13 @@ module.exports = Self => { for (const param in decodedParams) params[param] = decodeURIComponent(decodedParams[param]); + console.debug('Payment confirmation received:', { + signatureVersion, + merchantParameters, + signature, + params + }); + const orderId = params['Ds_Order']; const merchantId = parseInt(params['Ds_MerchantCode']); @@ -69,8 +76,13 @@ module.exports = Self => { .digest('base64'); const base64Res = base64url.encode(res, 'base64'); - if (base64Res !== signature) - throw new UserError('Invalid signature'); + // if (base64Res !== signature) + // throw new UserError('Invalid signature'); + + console.debug('Payment signature:', { + res, + base64Res + }); await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [ From 64d8ae1f4948fbfb16cf71c0ea137d8856e4f041 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 20:22:52 +0100 Subject: [PATCH 09/11] refs #5174 Hotfix --- modules/client/back/methods/tpv-transaction/confirm.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 1ca2265a6..6c8ecebaf 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -66,17 +66,17 @@ module.exports = Self => { const secretKey = Buffer.from(merchant.secretKey, 'base64'); const iv = Buffer.alloc(8, 0); - const cipher = crypto.createDecipheriv('des-ede3-cbc', secretKey, iv); + const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final(); + + cipher.final('base64'); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) .update(merchantParameters) .digest('base64'); const base64Res = base64url.encode(res, 'base64'); - // if (base64Res !== signature) + // if (res !== signature) // throw new UserError('Invalid signature'); console.debug('Payment signature:', { From 424dcb954c96e83e02910e63ccbc1b8ad7e56312 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Mon, 30 Jan 2023 20:23:52 +0100 Subject: [PATCH 10/11] refs #5174 Hotfix --- modules/client/back/methods/tpv-transaction/confirm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 6c8ecebaf..74eb9510c 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -69,7 +69,7 @@ module.exports = Self => { const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final('base64'); + + cipher.final(); const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) .update(merchantParameters) From 82bc7307f052d1a10c1445dfe4ef0378b3a8f856 Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Tue, 31 Jan 2023 00:41:36 +0100 Subject: [PATCH 11/11] #5174 Signature verification fixed & enabled --- .../back/methods/tpv-transaction/confirm.js | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/modules/client/back/methods/tpv-transaction/confirm.js b/modules/client/back/methods/tpv-transaction/confirm.js index 74eb9510c..bec818bc9 100644 --- a/modules/client/back/methods/tpv-transaction/confirm.js +++ b/modules/client/back/methods/tpv-transaction/confirm.js @@ -44,13 +44,6 @@ module.exports = Self => { for (const param in decodedParams) params[param] = decodeURIComponent(decodedParams[param]); - console.debug('Payment confirmation received:', { - signatureVersion, - merchantParameters, - signature, - params - }); - const orderId = params['Ds_Order']; const merchantId = parseInt(params['Ds_MerchantCode']); @@ -68,21 +61,17 @@ module.exports = Self => { const cipher = crypto.createCipheriv('des-ede3-cbc', secretKey, iv); cipher.setAutoPadding(false); - const orderKey = cipher.update(zeroPad(orderId, 8), 'utf8', 'base64') - + cipher.final(); + const orderKey = Buffer.concat([ + cipher.update(zeroPad(orderId, 8)), + cipher.final() + ]); - const res = crypto.createHmac('sha256', Buffer.from(orderKey, 'base64')) + const base64hmac = crypto.createHmac('sha256', orderKey) .update(merchantParameters) .digest('base64'); - const base64Res = base64url.encode(res, 'base64'); - // if (res !== signature) - // throw new UserError('Invalid signature'); - - console.debug('Payment signature:', { - res, - base64Res - }); + if (base64hmac !== base64url.toBase64(signature)) + throw new UserError('Invalid signature'); await Self.rawSql( 'CALL hedera.tpvTransaction_confirm(?, ?, ?, ?, ?, ?)', [