diff --git a/.env.dev.pcb b/.env.dev.pcb
index 86c5b99..076722d 100644
--- a/.env.dev.pcb
+++ b/.env.dev.pcb
@@ -42,5 +42,5 @@ MIAB_HOST=box.lamiaposta.org
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
DS_API_KEY="sk-222e3addb3d8455d8b0516d93906eec7"
-API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
-SERVER_A_URL="http://51.77.156.69:3000"
\ No newline at end of file
+SERVER_A_URL="http://51.77.156.69:3000"
+API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
\ No newline at end of file
diff --git a/.env.prod.pcb b/.env.prod.pcb
index 342e5db..c030678 100644
--- a/.env.prod.pcb
+++ b/.env.prod.pcb
@@ -40,9 +40,5 @@ CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpY
MIAB_HOST=box.lamiaposta.org
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
MIAB_ADMIN_PASSWORD=passpao1pabox@1A
-#DB_CONNECTION=sqlsrv
-DB_HOST_SQLSRVTEST=31.3.180.50
-DB_PORT_SQLSRVTEST=14338
-DB_DATABASE_SQLSRVTEST=ANAG_MACRO
-DB_USERNAME_SQLSRVTEST=woo
-DB_PASSWORD_SQLSRVTEST=4n4traPe@
+SERVER_A_URL="http://51.77.156.69:3000"
+API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
\ No newline at end of file
diff --git a/.env.test.pcb b/.env.test.pcb
index e146916..a64124a 100644
--- a/.env.test.pcb
+++ b/.env.test.pcb
@@ -40,4 +40,6 @@ SCRIPTS_DIR=admin_scripts
CLOUDFLARE_TOKENS=[{"label":"Paolo.arena77@gmail.com","value":"M9EM309v8WFquJKpYgZCw-TViM2wX6vB3wlK6GD0"},{"label":"gruppomacro.com","value":"bqmzGShoX7WqOBzkXocoECyBkPq3GfqcM5t6VFd8"}]
MIAB_HOST=box.lamiaposta.org
MIAB_ADMIN_EMAIL=admin@lamiaposta.org
-MIAB_ADMIN_PASSWORD=passpao1pabox@1A
\ No newline at end of file
+MIAB_ADMIN_PASSWORD=passpao1pabox@1A
+SERVER_A_URL="http://51.77.156.69:3000"
+API_KEY_MSSQL="m68yADSr123MIVIDA@154$DSAGVOK"
\ No newline at end of file
diff --git a/src/server/controllers/articleController.js b/src/server/controllers/articleController.js
index db34661..0e95820 100644
--- a/src/server/controllers/articleController.js
+++ b/src/server/controllers/articleController.js
@@ -4,6 +4,8 @@ const server_constants = require('../tools/server_constants');
const shared_consts = require('../tools/shared_nodejs');
+const tools = require('../tools/general');
+
const SERVER_A_URL = process.env.SERVER_A_URL || "http://IP_DI_SERVER_A:3000";
const API_KEY = process.env.API_KEY_MSSQL;
@@ -18,7 +20,9 @@ const getArticlesSales = async () => {
COALESCE(o.totVen, 0) as totVen, COALESCE(u.totFat, 0) as totFat,
COALESCE(p.rank3M, 0) as rank3M, COALESCE(t.fatrank3M, 0) as fatrank3M,
COALESCE(q.rank6M, 0) as rank6M, COALESCE(r.rank1Y, 0) as rank1Y,
- COALESCE(t.fat3mesi, 0) as fatLast3M, COALESCE(p.venduti3mesi, 0) as vLast3M,
+ COALESCE(t.fat3mesi, 0) as fatLast3M,
+ COALESCE(t.fat6mesi, 0) as fatLast6M,
+ COALESCE(p.venduti3mesi, 0) as vLast3M,
COALESCE(q.venduti6mesi, 0) as vLast6M, COALESCE(r.venduti1anno, 0) as vLastY,
s.ultimoOrdine as dataUltimoOrdine
FROM T_WEB_Articoli a
@@ -82,7 +86,7 @@ const getTableContent = async (options) => {
const checkResponse = await axios.post(SERVER_A_URL + '/query', { query: checkTableQuery }, {
headers: { 'x-api-key': API_KEY }
});
- if (!checkResponse.data || checkResponse.data.length === 0 || checkResponse.data[0].tableExists === 0) {
+ if (!checkResponse?.data || checkResponse?.data.length === 0 || checkResponse?.data[0].tableExists === 0) {
return `La tabella '${options.nameTable}' non esiste.`;
}
@@ -115,7 +119,7 @@ const getTableContent = async (options) => {
if (options.nameTable.toLowerCase() === 't_web_articoli') {
if (true) {
dataQuery = `
- SELECT TOP ${options.numrec}
+ SELECT TOP ${options.numrec || 10000}
${columnsToShow}
` + (options.campispeciali ? `
,f.DescrizioneStatoProdotto
@@ -236,18 +240,20 @@ const getTableContent = async (options) => {
`;
}
} else {
- dataQuery = `SELECT TOP ${options.numrec} * FROM ${options.nameTable} `;
+ dataQuery = `SELECT TOP ${options.numrec || 10000} * FROM ${options.nameTable} `;
}
if (options.where && options.where.trim() !== "") {
dataQuery += ` WHERE ${options.where} `;
}
+ console.log('dataQuery', dataQuery);
+
// Esegue la query per recuperare i dati
// console.log('dataQuery', dataQuery);
const dataResponse = await axios.post(SERVER_A_URL + '/query', { query: dataQuery }, {
headers: { 'x-api-key': API_KEY }
});
- const records = dataResponse.data;
+ const records = dataResponse?.data;
if (!records || records.length === 0) {
return `Nessun record trovato nella tabella '${options.nameTable}'.`;
}
@@ -355,6 +361,7 @@ const getTableContent = async (options) => {
return output;
} catch (error) {
+ output = error.message;
console.error("Errore nel recupero della tabella: ", error.message);
if (options.outhtml) {
output = `
@@ -409,6 +416,200 @@ const getTableContent = async (options) => {
}
};
+const setTableContent = async (options) => {
+ try {
+ // checkPermissions()
+
+ const esegui = true
+
+ if (esegui) {
+
+ // Verifica se la tabella esiste
+ const checkTableQuery = `SELECT COUNT(*) as tableExists FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '${options.nameTable}'`;
+ const checkResponse = await axios.post(SERVER_A_URL + '/query', { query: checkTableQuery }, {
+ headers: { 'x-api-key': API_KEY }
+ });
+
+ if (!checkResponse.data || checkResponse.data.length === 0 || checkResponse.data[0].tableExists === 0) {
+ return `La tabella '${options.nameTable}' non esiste.`;
+ }
+
+ // Costruisce la query per inserire o aggiornare i record
+ let dataQuery = "";
+ if (options.insertMode) {
+ // Modalità INSERT
+ const columns = Object.keys(options.data);
+ const values = columns.map(col => `'${options.data[col]}'`).join(", ");
+ dataQuery = `
+ INSERT INTO ${options.nameTable} (${columns.join(", ")})
+ VALUES (${values});
+ `;
+ } else {
+ // Modalità UPDATE
+ const updateFields = Object.keys(options.data)
+ .map(col => `${col} = '${options.data[col]}'`)
+ .join(", ");
+ const whereClause = options.where ? `WHERE ${options.where}` : "";
+ dataQuery = `
+ UPDATE ${options.nameTable}
+ SET ${updateFields}
+ ${whereClause};
+ `;
+ }
+
+ console.log('dataQuery', dataQuery);
+
+ // Esegue la query per inserire o aggiornare i dati
+ const dataResponse = await axios.post(SERVER_A_URL + '/query', { query: dataQuery }, {
+ headers: { 'x-api-key': API_KEY }
+ });
+
+ if (dataResponse.data && dataResponse.data.affectedRows > 0) {
+ return `Operazione completata con successo su '${options.nameTable}'.`;
+ } else {
+ return `Nessun record modificato nella tabella '${options.nameTable}'.`;
+ }
+ }
+ } catch (error) {
+ console.error("Errore nell'inserimento o aggiornamento della tabella: ", error.message);
+ if (options.outhtml) {
+ output = `
+
+
+ Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}
+
+
+
+
+
Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}
+
+ ${error.response.data.error || error.stack || error.message}
+
+
+
+ `;
+ return output;
+ }
+ return "Errore nell'inserimento o aggiornamento della tabella.";
+ }
+};
+const checkPermissions = async (options) => {
+ try {
+ const dataQuery = `
+ SELECT
+ dp.name AS UserName,
+ dp.type_desc AS UserType,
+ o.name AS ObjectName,
+ p.permission_name,
+ p.state_desc AS PermissionState
+ FROM
+ sys.database_permissions p
+ JOIN
+ sys.objects o ON p.major_id = o.object_id
+ JOIN
+ sys.database_principals dp ON p.grantee_principal_id = dp.principal_id
+ WHERE
+ o.name = 'T_WEB_Articoli';
+ `;
+
+ console.log('checkPermissions query:', dataQuery);
+
+ // Esegue la query per inserire o aggiornare i dati
+ const dataResponse = await axios.post(SERVER_A_URL + '/query', { query: dataQuery }, {
+ headers: { 'x-api-key': API_KEY }
+ });
+
+ console.log('checkPermissions result:', dataResponse.data);
+
+ if (dataResponse.data && dataResponse.data.affectedRows > 0) {
+ return `Operazione completata con successo.`;
+ } else {
+ return `Nessun permesso.`;
+ }
+ } catch (error) {
+ console.error("Errore nel check dei Permessi: ", error.message);
+ if (options.outhtml) {
+ output = `
+
+
+ Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}
+
+
+
+
+
Errore nell'inserimento o aggiornamento della Tabella ${options.nameTable}
+
+ ${error.response.data.error || error.stack || error.message}
+
+
+
+ `;
+ return output;
+ }
+ return "Errore nell'inserimento o aggiornamento della tabella.";
+ }
+};
+
// Endpoint per mostrare i dati della tabella
exports.viewTable = async (req, res) => {
try {
@@ -429,6 +630,12 @@ exports.viewTable = async (req, res) => {
out = tableContent;
}
+ if (tableContent && tableContent.length > 0) {
+ if (options.updatelocaldb) {
+ this.updateLocalDb(tableContent[0], options)
+ }
+ }
+
return res.send({ code: server_constants.RIS_CODE_OK, data: out });
} catch (error) {
@@ -437,6 +644,82 @@ exports.viewTable = async (req, res) => {
}
};
+exports.updateLocalDb = async (tableContent, options) => {
+ try {
+
+ const ProductInfo = require('../models/productInfo');
+ const CatProd = require('../models/catprod');
+
+ let recproductInfo = {
+ code: tableContent.Ean13.trim(),
+ };
+
+ let risrecUpdated = null;
+
+ const recfound = await ProductInfo.findOne({ code: recproductInfo.code }).lean();
+ if (recfound) {
+
+ ListaArgomenti = tableContent.ListaArgomenti;
+
+ let arrayPulito = ListaArgomenti
+ .trim() // Rimuove gli spazi all'inizio e alla fine
+ .replace(/[\(\)]/g, '') // Rimuove le parentesi tonde
+ .split(','); // Divide la stringa in un array usando la virgola come separatore
+
+ if (arrayPulito && arrayPulito.length > 0) {
+ let aggiornacat = false;
+ const precCatProds = recfound.idCatProds;
+ let reccatprods = [];
+ for (let i = 0; i < arrayPulito.length; i++) {
+ const idArgomento = parseInt(arrayPulito[i]);
+ reccateg = await CatProd.findOne({ idArgomento }).lean();
+
+ if (reccateg) {
+ // aggiungi solo se non esiste già
+ if (!reccatprods.includes(reccateg._id)) {
+ reccatprods.push(reccateg._id);
+ }
+ }
+ }
+
+ // ora controlla se l'array reccatprods e' diverso da precCatProds
+ if (reccatprods.length !== precCatProds.length) {
+ aggiornacat = true;
+ } else {
+ for (let i = 0; i < reccatprods.length; i++) {
+ if (reccatprods[i].toString() !== precCatProds[i].toString()) {
+ aggiornacat = true;
+ break;
+ }
+ }
+ }
+
+ if (aggiornacat) {
+ recproductInfo.idCatProds = reccatprods;
+ aggiorna = true;
+ }
+ }
+
+ if (tableContent.DataPubblicazione.trim()) {
+ recproductInfo.date_pub = new Date(tools.convertiDataItaliana(tableContent.DataPubblicazione.trim()).date);
+ // convert data to timestamp
+ recproductInfo.date_pub_ts = recproductInfo.date_pub.getTime();
+ aggiorna = true;
+ }
+
+ if (aggiorna) {
+ risrecUpdated = await ProductInfo.findOneAndUpdate({ code: recproductInfo.code }, { $set: recproductInfo }, { new: true, upsert: true });
+ }
+
+ return risrecUpdated;
+ }
+
+ } catch (e) {
+ console.error('Error: ', e);
+ return null;
+ }
+}
+
// Endpoint per mostrare i dati della tabella
exports.queryTable = async (req, res) => {
try {
@@ -462,3 +745,30 @@ exports.queryTable = async (req, res) => {
return res.send({ code: server_constants.RIS_CODE_ERR, error });
}
};
+// Endpoint per salvare i dati di una tabella
+exports.saveTable = async (req, res) => {
+ try {
+ const options = req.body.options;
+ const tableContent = await setTableContent(options);
+
+ let out = {};
+
+ if (options.outhtml) {
+ out = `
+ Tabella: ${options.nameTable}
+ Query: ${options.where}
+
+ ${tableContent}
+
+ `
+ } else {
+ out = tableContent;
+ }
+
+ return res.send({ code: server_constants.RIS_CODE_OK, data: out });
+
+ } catch (error) {
+ console.error('Error: ', error);
+ return res.send({ code: server_constants.RIS_CODE_ERR, error });
+ }
+};
diff --git a/src/server/models/product.js b/src/server/models/product.js
index dd1d2fe..6db85af 100755
--- a/src/server/models/product.js
+++ b/src/server/models/product.js
@@ -819,6 +819,7 @@ module.exports.getArrCatProds = async function (idapp, cosa) {
]
}
}]
+
} else {
addquery = [{ $match: { idapp } }];
}
@@ -841,7 +842,23 @@ module.exports.getArrCatProds = async function (idapp, cosa) {
}
},
{ $unwind: "$category" },
- { $group: { _id: "$category._id", name: { $first: "$category.name" } } },
+ {
+ $group: {
+ _id: "$category._id",
+ name: { $first: "$category.name" },
+ idapp: { $first: "$category.idapp" },
+ idArgomento: { $first: "$category.idArgomento" }
+ }
+ },
+ {
+ $match: {
+ $or: [
+ { idapp: { $ne: tools.MACRO } },
+ { idapp: tools.MACRO, idArgomento: { $exists: true, $gt: 0 } }
+ ]
+ }
+ },
+
{ $sort: { name: 1 } }
];
diff --git a/src/server/router/admin_router.js b/src/server/router/admin_router.js
index 436a64c..191cab4 100755
--- a/src/server/router/admin_router.js
+++ b/src/server/router/admin_router.js
@@ -116,7 +116,7 @@ async function findOrCreateCatProd(idapp, idArgomento, DescrArgomento) {
function updateProductInfoCatProds(productInfo, reccatprod) {
if (productInfo) {
// Controllo che nell'array productInfo.idCatProds ci sia esattamente 1 record e che sia uguale a reccatprod._id
- const cond3 = Array.isArray(productInfo.idCatProds) && productInfo.idCatProds[0].toString() !== reccatprod._id.toString();
+ const cond3 = Array.isArray(productInfo.idCatProds) && productInfo.idCatProds.length > 0 && productInfo.idCatProds[0].toString() !== reccatprod._id.toString();
const isChanged =
!Array.isArray(productInfo.idCatProds) || // Assicurati che sia un array
productInfo.idCatProds.length !== 1 || // L'array deve contenere esattamente 1 elemento
@@ -903,6 +903,8 @@ router.post('/import', authenticate, async (req, res) => {
const trovato = await ImportaIsbn.findOne({ isbn: product.code }).lean();
if (trovato) {
+ // togli a recisbn l'_id
+ delete trovato._id;
recisbn = trovato;
}
@@ -916,14 +918,18 @@ router.post('/import', authenticate, async (req, res) => {
recisbn.sottotitolo = productInfo.sottotitolo;
// recisbn.idapp = idapp;
- let risisbn = await ImportaIsbn.findOneAndUpdate({ isbn: product.code }, { $set: recisbn }, { new: true, upsert: true, strict: false });
+ try {
+ let risisbn = await ImportaIsbn.findOneAndUpdate({ isbn: product.code }, { $set: recisbn }, { new: true, upsert: true, strict: false });
- // Update ProductInfo, non crea nuovi record !
- let risrecInfo = await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: productInfo }, { new: true, upsert: false });
+ // Update ProductInfo, non crea nuovi record !
+ let risrecInfo = await ProductInfo.findOneAndUpdate({ code: productInfo.code }, { $set: productInfo }, { new: true, upsert: false });
- indprod++;
- if (indprod % 100 === 0)
- console.log(indprod + '/' + numprod);
+ indprod++;
+ if (indprod % 100 === 0)
+ console.log(indprod + '/' + numprod);
+ } catch (e) {
+ console.error(e);
+ }
}
}
@@ -1052,6 +1058,7 @@ router.post('/import', authenticate, async (req, res) => {
totFat: product.totFat || 0,
vLast3M: product.vLast3M || 0,
fatLast3M: product.fatLast3M || 0,
+ fatLast6M: product.fatLast6M || 0,
vLast6M: product.vLast6M || 0,
vLastY: product.vLastY || 0,
vLast2Y: product.vLast2Y || 0,
@@ -1120,7 +1127,7 @@ router.post('/import', authenticate, async (req, res) => {
let imported = 0;
let errors = 0;
- const ripopola = false; //++MODIFICARE!
+ const ripopola = true; //++MODIFICARE!
if (ripopola) {
dataObjects = null;
@@ -1221,7 +1228,12 @@ router.post('/import', authenticate, async (req, res) => {
// se non esiste l'ISBN, allora me lo cerco in base a sku !
- if (!product.isbn) {
+ let trova = false
+ if (product._id === '30310') {
+ trova = true
+ }
+
+ if (!product.isbn || product.isbn.startsWith('field')) {
const rectrovare = await ImportaIsbn.findOne({ sku: product.sku }).lean();
if (rectrovare) {
// se l'isbn non inizia con 'field' allora è buono
diff --git a/src/server/router/articleRoutes.js b/src/server/router/articleRoutes.js
index 0728444..fa328f9 100644
--- a/src/server/router/articleRoutes.js
+++ b/src/server/router/articleRoutes.js
@@ -1,5 +1,5 @@
const express = require("express");
-const { getArticlesSalesHandler, exportArticlesSalesByJSON, viewTable, queryTable } = require("../controllers/articleController");
+const { getArticlesSalesHandler, exportArticlesSalesByJSON, viewTable, saveTable, queryTable } = require("../controllers/articleController");
const { authenticate } = require("../middleware/authenticate");
const router = express.Router();
@@ -9,6 +9,7 @@ router.post("/articles-sales", authenticate, getArticlesSalesHandler);
router.post("/export-articles-sales-json", authenticate, exportArticlesSalesByJSON);
router.post("/view-table", authenticate, viewTable);
+router.post("/save-table", authenticate, saveTable);
router.post("/query", authenticate, queryTable);
diff --git a/src/server/router/index_router.js b/src/server/router/index_router.js
index a4eb5f4..9a9d8e2 100755
--- a/src/server/router/index_router.js
+++ b/src/server/router/index_router.js
@@ -1160,6 +1160,7 @@ router.post('/duppage', authenticate, async (req, res) => {
}
});
+
router.post('/exppage', authenticate, async (req, res) => {
const params = req.body;
const idapp = req.body.idapp;
diff --git a/src/server/router/products_router.js b/src/server/router/products_router.js
index 069e6c6..673be42 100755
--- a/src/server/router/products_router.js
+++ b/src/server/router/products_router.js
@@ -89,6 +89,8 @@ router.get('/id/:id', async function (req, res) {
var product = await Product.getProductById(id);
+ console.log('Product ID', id, product);
+
if (product) {
return res.send({ code: server_constants.RIS_CODE_OK, product: product });
} else {
diff --git a/src/server/router/users_router.js b/src/server/router/users_router.js
index ebac601..8d35c5e 100755
--- a/src/server/router/users_router.js
+++ b/src/server/router/users_router.js
@@ -789,30 +789,30 @@ router.post('/login', checkBlocked, async (req, res) => {
resalreadysent = true;
}
- res.status(401).send({ code: server_constants.RIS_CODE_LOGIN_ERR });
- resalreadysent = true;
+ return res.status(401).send({ code: server_constants.RIS_CODE_LOGIN_ERR });
+ } else {
+ const myris = await user.generateAuthToken(req);
+
+ const usertosend = new User();
+
+ shared_consts.fieldsUserToChange().forEach((field) => {
+ usertosend[field] = user[field];
+ });
+
+ const subsExistonDb = await existSubScribe(usertosend._id, 'auth', req.get('User-Agent'));
+
+ res
+ .header('x-auth', myris.token)
+ .header('x-refrtok', myris.refreshToken)
+ .send({
+ usertosend,
+ code: server_constants.RIS_CODE_OK,
+ subsExistonDb,
+ });
+
}
- const myris = await user.generateAuthToken(req);
-
- const usertosend = new User();
-
- shared_consts.fieldsUserToChange().forEach((field) => {
- usertosend[field] = user[field];
- });
-
- const subsExistonDb = await existSubScribe(usertosend._id, 'auth', req.get('User-Agent'));
-
- res
- .header('x-auth', myris.token)
- .header('x-refrtok', myris.refreshToken)
- .send({
- usertosend,
- code: server_constants.RIS_CODE_OK,
- subsExistonDb,
- });
-
} catch (e) {
console.error('ERRORE IN LOGIN: ' + e.message);
if (!resalreadysent)
diff --git a/src/server/sendemail.js b/src/server/sendemail.js
index 485be90..f71d8eb 100755
--- a/src/server/sendemail.js
+++ b/src/server/sendemail.js
@@ -57,6 +57,7 @@ module.exports = {
if (to === '')
return false;
+
// console.log('mylocalsconf', mylocalsconf);
// console.log("check EMAIL :" + checkifSendEmail());
@@ -88,7 +89,6 @@ module.exports = {
// transport = this.getTransport(mylocalsconf);
// }
- // console.log('1 . transport', transport);
if (transport) {
paramemail.transport = transport;
@@ -700,6 +700,9 @@ module.exports = {
},
getdataemail: async (idapp, templemail_id) => {
+
+ const pwd_from = await Settings.getValDbSettings(idapp, 'PWD_FROM');
+
// console.log('getdataemail');
const mydata = {
content_after_events: await Settings.getValDbSettings(idapp, 'TEXT_AFTER_EV'),
@@ -718,7 +721,7 @@ module.exports = {
height_logo: await Settings.getValDbSettings(idapp, 'HEIGHT_LOGO'),
from: await Settings.getValDbSettings(idapp, 'EMAIL_FROM'),
email_reply: await Settings.getValDbSettings(idapp, 'EMAIL_REPLY', ''),
- pwd_from: await Settings.getValDbSettings(idapp, 'PWD_FROM'),
+ pwd_from: pwd_from,
email_service: await Settings.getValDbSettings(idapp, 'EMAIL_SERVICE_SEND'),
email_port: await Settings.getValDbSettings(idapp, 'EMAIL_PORT'),
templemail_id: templemail_id ? templemail_id : await Settings.getValDbSettings(idapp, 'TEMPLEMAIL_ID'),
@@ -732,6 +735,8 @@ module.exports = {
},
getTransport: (mylocalsconf) => {
+ console.log('getTransport');
+
// Create Transport
let smtpTransport = null;
diff --git a/src/server/tools/general.js b/src/server/tools/general.js
index 6e3a353..0cc9afc 100755
--- a/src/server/tools/general.js
+++ b/src/server/tools/general.js
@@ -56,8 +56,8 @@ const readline = require('readline');
// Code goes here
const keySize = 256;
-const ivSize = 128;
-const iterations = 100;
+// const ivSize = 128;
+const iterations = 1000;
if (!!process.env.GCM_API_KEY && process.env.GCM_API_KEY !== '') {
webpush.setGCMAPIKey(process.env.GCM_API_KEY);
@@ -585,6 +585,7 @@ module.exports = {
RISO: '13',
FIOREDELLAVITA: '15',
PIUCHEBUONO: '17',
+ MACRO: '18',
IDAPP_BOTONGROUP: '1000',
@@ -3904,47 +3905,79 @@ module.exports = {
},
encrypt(msg, pass) {
- var salt = CryptoJS.lib.WordArray.random(128 / 8);
+ try {
+ // Genera salt e IV casuali
+ const salt = CryptoJS.lib.WordArray.random(128 / 8); // 16 byte
+ const iv = CryptoJS.lib.WordArray.random(128 / 8); // 16 byte
- var key = CryptoJS.PBKDF2(pass, salt, {
- keySize: keySize / 32,
- iterations: iterations,
- });
+ // Deriva la chiave usando PBKDF2
+ const key = CryptoJS.PBKDF2(pass, salt, {
+ keySize: keySize / 32,
+ iterations: iterations,
+ });
- var iv = CryptoJS.lib.WordArray.random(128 / 8);
+ // Critta il messaggio
+ const encrypted = CryptoJS.AES.encrypt(msg, key, {
+ iv: iv,
+ padding: CryptoJS.pad.Pkcs7,
+ mode: CryptoJS.mode.CBC,
+ });
- var encrypted = CryptoJS.AES.encrypt(msg, key, {
- iv: iv,
- padding: CryptoJS.pad.Pkcs7,
- mode: CryptoJS.mode.CBC,
-
- });
-
- // salt, iv will be hex 32 in length
- // append them to the ciphertext for use in decryption
- var transitmessage = salt.toString() + iv.toString() + encrypted.toString();
- return transitmessage;
+ // Concatena salt, IV e ciphertext con un delimitatore
+ const transitmessage = `${salt.toString()}|${iv.toString()}|${encrypted.toString()}`;
+ return transitmessage;
+ } catch (error) {
+ console.error('❌❌❌ Errore durante la crittazione:', error.message);
+ throw error;
+ }
},
decrypt(transitmessage, pass) {
- var salt = CryptoJS.enc.Hex.parse(transitmessage.substr(0, 32));
- var iv = CryptoJS.enc.Hex.parse(transitmessage.substr(32, 32));
- var encrypted = transitmessage.substring(64);
+ try {
+ let saltHex, ivHex, encrypted;
- var key = CryptoJS.PBKDF2(pass, salt, {
- keySize: keySize / 32,
- iterations: iterations,
- });
+ // Controlla se il messaggio è nel nuovo formato (con delimitatore)
+ if (transitmessage.includes('|')) {
+ const parts = transitmessage.split('|');
+ if (parts.length !== 3) {
+ throw new Error('❌❌❌ Formato del messaggio non valido.');
+ }
+ [saltHex, ivHex, encrypted] = parts;
+ } else {
+ // Vecchio formato: salt (32 caratteri), IV (32 caratteri), ciphertext (resto)
+ saltHex = transitmessage.substr(0, 32);
+ ivHex = transitmessage.substr(32, 32);
+ encrypted = transitmessage.substring(64);
+ }
- var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
- iv: iv,
- padding: CryptoJS.pad.Pkcs7,
- mode: CryptoJS.mode.CBC,
+ // Converte salt e IV da esadecimale
+ const salt = CryptoJS.enc.Hex.parse(saltHex);
+ const iv = CryptoJS.enc.Hex.parse(ivHex);
- });
- return decrypted;
+ // Deriva la chiave usando PBKDF2
+ const key = CryptoJS.PBKDF2(pass, salt, {
+ keySize: keySize / 32,
+ iterations: iterations,
+ });
+
+ // Decritta il messaggio
+ const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
+ iv: iv,
+ padding: CryptoJS.pad.Pkcs7,
+ mode: CryptoJS.mode.CBC,
+ });
+
+ // Restituisci il messaggio originale in formato UTF-8
+ let ris = decrypted.toString(CryptoJS.enc.Utf8);
+
+ // console.log('RIS', ris);
+
+ return ris;
+ } catch (error) {
+ console.error('❌❌❌ Errore durante la decrittazione:', error.message);
+ throw error;
+ }
},
-
cryptdata(mydata) {
if (mydata === '')
return '';
@@ -3954,13 +3987,17 @@ module.exports = {
},
decryptdata(mydatacrypted) {
- if (mydatacrypted === '' || mydatacrypted === undefined)
+ if (!mydatacrypted) return '';
+
+ try {
+ // console.log('SECRK', process.env.SECRK);
+ const decr = this.decrypt(mydatacrypted, process.env.SECRK);
+ // console.log('decr:', mydatacrypted, '->', decr);
+ return decr;
+ } catch (error) {
+ console.error('❌❌❌❌❌ Decryption error:', error);
return '';
- // Decrypt
- // const bytes = CryptoJS.AES.decrypt(mydatacrypted.toString(), process.env.SECRK);
- // return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
- return this.decrypt(mydatacrypted, process.env.SECRK).
- toString(CryptoJS.enc.Utf8);
+ }
},
BoolToInt(mybool) {
@@ -6025,6 +6062,44 @@ module.exports = {
// Funzione per implementare il ritardo tra i tentativi
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
+ },
+
+ /**
+ * Converte una data in formato italiano GG/MM/YYYY in un oggetto Date e restituisce il timestamp.
+ * @param {string} dateString - La data in formato GG/MM/YYYY.
+ * @returns {Object} - Un oggetto contenente la data (Date) e il timestamp (number).
+ * Restituisce null se la data non è valida.
+ */
+ convertiDataItaliana(dateString) {
+ // Verifica che la data sia una stringa valida
+ if (!dateString || typeof dateString !== 'string') {
+ console.error("Input non valido: la data deve essere una stringa.");
+ return null;
+ }
+
+ // Rimuovi eventuali spazi bianchi e dividi la data in GG, MM, YYYY
+ const [giorno, mese, anno] = dateString.trim().split('/').map(Number);
+
+ // Controlla che i valori siano stati estratti correttamente
+ if (isNaN(giorno) || isNaN(mese) || isNaN(anno)) {
+ console.error("Formato data non valido:", dateString);
+ return null;
+ }
+
+ // Crea un oggetto Date (mese parte da 0 in JavaScript)
+ const dateObj = new Date(anno, mese - 1, giorno);
+
+ // Verifica che la data sia valida
+ if (isNaN(dateObj.getTime())) {
+ console.error("Data non valida:", dateString);
+ return null;
+ }
+
+ // Restituisci l'oggetto con la data e il timestamp
+ return {
+ date: dateObj,
+ timestamp: dateObj.getTime()
+ };
}
diff --git a/src/server/version.txt b/src/server/version.txt
index 828cb60..7a5b0e5 100644
--- a/src/server/version.txt
+++ b/src/server/version.txt
@@ -1 +1 @@
-1.2.32
\ No newline at end of file
+1.2.33
\ No newline at end of file