From 45f601bd266a4606bbd9b0d9eb8bd177f1d718c2 Mon Sep 17 00:00:00 2001 From: Surya Paolo Date: Thu, 29 Aug 2024 23:30:58 +0200 Subject: [PATCH] - attivita - gestione degli script sul server - creato websocket per interagire con gli script del server. --- .env.dev.pcb | 3 +- .env.prod.pcb | 3 +- admin_scripts/1_GENERALE/inputTest.sh | 17 ++ admin_scripts/1_GENERALE/showLog.sh | 5 + admin_scripts/1_GENERALE/testScript.sh | 7 + admin_scripts/listaScript.sh | 3 + docs/router/admin_router | 0 package.json | 1 + src/server/models/attivita.js | 9 +- src/server/models/mybacheca.js | 4 +- src/server/models/mygood.js | 4 +- src/server/models/mygroup.js | 28 ++- src/server/models/myhosp.js | 4 +- src/server/models/myskill.js | 4 +- src/server/models/user.js | 2 +- src/server/modules/cloudflare.js | 66 +++++++ src/server/populate/goods.js | 11 ++ src/server/populate/sectorgoods.js | 1 + src/server/router/admin_router.js | 37 ++++ src/server/router/users_router.js | 7 +- src/server/server.js | 102 ++++++++++- src/server/telegram/telegrambot.js | 10 +- src/server/tools/general.js | 230 ++++++++++++++++++++++--- src/server/tools/shared_nodejs.js | 9 + yarn.lock | 12 ++ 25 files changed, 534 insertions(+), 45 deletions(-) create mode 100755 admin_scripts/1_GENERALE/inputTest.sh create mode 100755 admin_scripts/1_GENERALE/showLog.sh create mode 100755 admin_scripts/1_GENERALE/testScript.sh create mode 100755 admin_scripts/listaScript.sh create mode 100644 docs/router/admin_router create mode 100644 src/server/modules/cloudflare.js diff --git a/.env.dev.pcb b/.env.dev.pcb index b7b5087..745eee4 100644 --- a/.env.dev.pcb +++ b/.env.dev.pcb @@ -38,4 +38,5 @@ FTPSERVER_HOST=139.162.166.31 FTPSERVER_PORT=21 FTPSERVER_USER=ftpusrsrv_ FTPSERVER_PWD=ftpmypwd@1A_ -AUTH_NEW_SITES=123123123 \ No newline at end of file +AUTH_NEW_SITES=123123123 +SCRIPTS_DIR=admin_scripts \ No newline at end of file diff --git a/.env.prod.pcb b/.env.prod.pcb index 79543a8..5afc249 100644 --- a/.env.prod.pcb +++ b/.env.prod.pcb @@ -33,4 +33,5 @@ SECRTK=jAxKm02emx5SeJvz2IGmtRf6YqCgope TOKEN_LIFE=2h REFRESH_TOKEN_LIFE=14d AUTH_NEW_SITES=B234HDSAOJ734ndcsdKWNVZZ -DOMAINS=[{"hostname": "piuchebuono.app","port": 3000 },{"hostname":"gruppomacro.app","port": 3010}] \ No newline at end of file +DOMAINS=[{"hostname": "piuchebuono.app","port": 3000 },{"hostname":"gruppomacro.app","port": 3010}] +SCRIPTS_DIR=admin_scripts \ No newline at end of file diff --git a/admin_scripts/1_GENERALE/inputTest.sh b/admin_scripts/1_GENERALE/inputTest.sh new file mode 100755 index 0000000..6206b4c --- /dev/null +++ b/admin_scripts/1_GENERALE/inputTest.sh @@ -0,0 +1,17 @@ +#!/bin/bash +#DATA|TITLE|Input Test +#DATA|DESCRIZ|Input Test + +echo "Inizio dello Script... " +echo ".............................................." + + +if [ "$1" = "" ]; then + read -p "Inserisci il parametro 1 " PARAM1 +else + PARAM1=$1 +fi + +echo "Il parametro 1 è " $PARAM1 + +echo "FINEEEE!" diff --git a/admin_scripts/1_GENERALE/showLog.sh b/admin_scripts/1_GENERALE/showLog.sh new file mode 100755 index 0000000..8f14dde --- /dev/null +++ b/admin_scripts/1_GENERALE/showLog.sh @@ -0,0 +1,5 @@ +#!/bin/bash +#DATA|TITLE|Mostra i log +#DATA|DESCRIZ|Mostra i log della cartella principale + +tail -400f logs/combined*.log \ No newline at end of file diff --git a/admin_scripts/1_GENERALE/testScript.sh b/admin_scripts/1_GENERALE/testScript.sh new file mode 100755 index 0000000..ad39b3a --- /dev/null +++ b/admin_scripts/1_GENERALE/testScript.sh @@ -0,0 +1,7 @@ +#!/bin/bash +#DATA|TITLE|lista directory +#DATA|DESCRIZ|Mostra la lista della directory + +sleep 1 + +ls -l \ No newline at end of file diff --git a/admin_scripts/listaScript.sh b/admin_scripts/listaScript.sh new file mode 100755 index 0000000..6275640 --- /dev/null +++ b/admin_scripts/listaScript.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +ls admin_scripts \ No newline at end of file diff --git a/docs/router/admin_router b/docs/router/admin_router new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json index 1022761..68eb923 100755 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "node-emoji": "^1.11.0", "node-image-resizer": "^1.0.0", "node-pre-gyp": "^0.14.0", + "node-pty": "^1.0.0", "node-telegram-bot-api": "^0.65.1", "nodemailer": "^6.7.8", "npm-check-updates": "^16.14.18", diff --git a/src/server/models/attivita.js b/src/server/models/attivita.js index 1444662..bc0eaa7 100755 --- a/src/server/models/attivita.js +++ b/src/server/models/attivita.js @@ -7,6 +7,7 @@ mongoose.level = 'F'; const tools = require('../tools/general'); const { Reaction } = require('./reaction'); +const { MyGroup } = require('./mygroup'); const shared_consts = require('../tools/shared_nodejs'); @@ -84,10 +85,10 @@ const AttivitaSchema = new Schema( type: Number, }, - nome_attivita: { + descr: { type: String, }, - descr: { + note: { type: String, }, @@ -127,7 +128,8 @@ const AttivitaSchema = new Schema( //**ADDFIELD_ATTIVITA }, - ...Reaction.getFieldsForReactions() + ...Reaction.getFieldsForReactions(), + ...MyGroup.getFieldsForAnnunci() }, { strict: false }); AttivitaSchema.index({ 'idapp': 1 }); @@ -362,7 +364,6 @@ AttivitaSchema.statics.getProject = function (proj_add2) { date_created: 1, date_updated: 1, tipodiAttivita: 1, - nome_attivita: 1, coordinate_gps: 1, email: 1, telegram_username: 1, diff --git a/src/server/models/mybacheca.js b/src/server/models/mybacheca.js index fa00061..afa7dd0 100755 --- a/src/server/models/mybacheca.js +++ b/src/server/models/mybacheca.js @@ -10,6 +10,7 @@ const { ObjectID } = require('mongodb'); const shared_consts = require('../tools/shared_nodejs'); const { Reaction } = require('./reaction'); +const { MyGroup } = require('./mygroup'); const tableModel = shared_consts.TABLES_MYBACHECAS; @@ -118,7 +119,8 @@ const MyBachecaSchema = new Schema({ type: Date, }, }, - ...Reaction.getFieldsForReactions() + ...Reaction.getFieldsForReactions(), + ...MyGroup.getFieldsForAnnunci() }); MyBachecaSchema.pre('save', async function (next) { diff --git a/src/server/models/mygood.js b/src/server/models/mygood.js index 8eea39e..0b9717d 100755 --- a/src/server/models/mygood.js +++ b/src/server/models/mygood.js @@ -7,6 +7,7 @@ mongoose.level = 'F'; const tools = require('../tools/general'); const { Reaction } = require('./reaction'); +const { MyGroup } = require('./mygroup'); const shared_consts = require('../tools/shared_nodejs'); @@ -90,7 +91,8 @@ const MyGoodSchema = new Schema({ type: Date, }, }, - ...Reaction.getFieldsForReactions() + ...Reaction.getFieldsForReactions(), + ...MyGroup.getFieldsForAnnunci() }); MyGoodSchema.pre('save', async function (next) { diff --git a/src/server/models/mygroup.js b/src/server/models/mygroup.js index c93b5bd..1097066 100755 --- a/src/server/models/mygroup.js +++ b/src/server/models/mygroup.js @@ -125,6 +125,12 @@ const MyGroupSchema = new Schema({ lastdate_reqRisGroup: { type: Date, }, + + idMyGroup: { + type: String, + }, + // **ADDFIELD_MYGROUPS + }); MyGroupSchema.statics.getFieldsForSearch = function () { @@ -236,7 +242,7 @@ MyGroupSchema.statics.getListAdminsByGroupName = async function (idapp, groupnam MyGroupSchema.statics.getWhatToShow = function (idapp, username) { // FOR ME, PERMIT ALL - return { + let whatToShow = { groupname: 1, title: 1, descr: 1, @@ -260,10 +266,14 @@ MyGroupSchema.statics.getWhatToShow = function (idapp, username) { lastdate_reqRisGroup: 1, }; + whatToShow = { ...whatToShow, ...shared_consts.ANNUNCI_FIELDS }; + + return whatToShow; + }; MyGroupSchema.statics.getWhatToShow_Unknown = function (idapp, username) { - return { + let whatToShow = { groupname: 1, title: 1, descr: 1, @@ -277,6 +287,11 @@ MyGroupSchema.statics.getWhatToShow_Unknown = function (idapp, username) { mycircuits: 1, lastdate_reqRisGroup: 1, }; + + whatToShow = { ...whatToShow, ...shared_consts.ANNUNCI_FIELDS }; + + return whatToShow; + }; MyGroupSchema.statics.getArrUsernameFromFieldByGroupname = async function ( @@ -648,7 +663,16 @@ MyGroupSchema.statics.setReceiveRisGroup = async function (idapp, groupname) { }; +MyGroupSchema.statics.getFieldsForAnnunci = function () { + let annunciFields = { + idMyGroup: { + type: String, + }, + // **ADDFIELD_MYGROUPS + }; + return annunciFields; +}; const MyGroup = mongoose.model('MyGroup', MyGroupSchema); diff --git a/src/server/models/myhosp.js b/src/server/models/myhosp.js index b87c528..aba30ff 100755 --- a/src/server/models/myhosp.js +++ b/src/server/models/myhosp.js @@ -7,6 +7,7 @@ mongoose.level = 'F'; const tools = require('../tools/general'); const { Reaction } = require('./reaction'); +const { MyGroup } = require('./mygroup'); const shared_consts = require('../tools/shared_nodejs'); const { ObjectID } = require('mongodb'); @@ -94,7 +95,8 @@ const MyHospSchema = new Schema({ type: Date, }, }, - ...Reaction.getFieldsForReactions() + ...Reaction.getFieldsForReactions(), + ...MyGroup.getFieldsForAnnunci() }); MyHospSchema.pre('save', async function (next) { diff --git a/src/server/models/myskill.js b/src/server/models/myskill.js index bb9bcb6..4ef1622 100755 --- a/src/server/models/myskill.js +++ b/src/server/models/myskill.js @@ -7,6 +7,7 @@ mongoose.level = 'F'; const tools = require('../tools/general'); const { Reaction } = require('./reaction'); +const { MyGroup } = require('./mygroup'); const shared_consts = require('../tools/shared_nodejs'); @@ -97,7 +98,8 @@ const MySkillSchema = new Schema( type: Date, }, }, - ...Reaction.getFieldsForReactions() + ...Reaction.getFieldsForReactions(), + ...MyGroup.getFieldsForAnnunci() }, { strict: false }); MySkillSchema.index({ 'idapp': 1 }); diff --git a/src/server/models/user.js b/src/server/models/user.js index e4649dd..1be3eba 100755 --- a/src/server/models/user.js +++ b/src/server/models/user.js @@ -4561,7 +4561,7 @@ UserSchema.statics.calculateStat = async function (idapp, username) { const { MySkill } = require('../models/myskill'); const { MyGood } = require('../models/mygood'); const { MyBacheca } = require('../models/mybacheca'); - const { MyGroup } = require('../models/mygroup'); + // const { MyGroup } = require('../models/mygroup'); const globalTables = require('../tools/globalTables'); const numUsersReg = await User.countDocuments( diff --git a/src/server/modules/cloudflare.js b/src/server/modules/cloudflare.js new file mode 100644 index 0000000..b82582b --- /dev/null +++ b/src/server/modules/cloudflare.js @@ -0,0 +1,66 @@ + +const axios = require('axios'); + +const apiUrl = 'https://api.cloudflare.com/client/v4'; // Endpoint + +async function fetchCloudflareZones(apiToken) { + try { + + // Effettua una richiesta GET all'API di Cloudflare + const response = await axios.get(apiUrl + '/zones', { + headers: { + 'Authorization': `Bearer ${apiToken}`, // Autenticazione con token + 'Content-Type': 'application/json' // Tipo di contenuto + } + }); + + // Estrai i dati dalla risposta + const zones = response.data.result; + + // Stampa le zone + // console.log('Zone di Cloudflare:', zones); + } catch (error) { + console.error('Errore durante il recupero delle zone di Cloudflare:', error.message); + } +} + +// Funzione per estrarre i record DNS +async function fetchDNSRecords(apiToken, zoneId) { + const apiUrlDNS = apiUrl + `/zones/${zoneId}/dns_records`; + + try { + const response = await axios.get(apiUrlDNS, { + headers: { + 'Authorization': `Bearer ${apiToken}`, // Autenticazione con token + 'Content-Type': 'application/json' // Tipo di contenuto + } + }); + + const dnsRecords = response.data.result; + + return dnsRecords; + } catch (error) { + console.error('Errore durante il recupero dei record DNS di Cloudflare:', error.message); + } +} + +// Funzione per aggiornare un record DNS +async function updateDNSRecord(apiToken, zoneId, dnsRecordId, newDnsRecordData) { + const apiUrlDNS = apiUrl + `/zones/${zoneId}/dns_records/${dnsRecordId}`; + + try { + const response = await axios.put(apiUrlDNS, newDnsRecordData, { + headers: { + 'Authorization': `Bearer ${apiToken}`, // Autenticazione con token + 'Content-Type': 'application/json' // Tipo di contenuto + } + }); + + const updatedRecord = response.data.result; + + // Stampa il record DNS aggiornato + console.log('Record DNS aggiornato:', updatedRecord); + } catch (error) { + console.error('Errore durante l\'aggiornamento del record DNS:', error.message); + } +} \ No newline at end of file diff --git a/src/server/populate/goods.js b/src/server/populate/goods.js index 15085e2..5af1426 100644 --- a/src/server/populate/goods.js +++ b/src/server/populate/goods.js @@ -70,5 +70,16 @@ module.exports = { {_id: 68, idSectorGood: [7], descr: 'Fermentati'}, {_id: 69, idSectorGood: [7], descr: 'Marmellate'}, {_id: 70, idSectorGood: [7], descr: 'Salse'}, + {_id: 71, idSectorGood: [20], descr: 'Cereali'}, + {_id: 72, idSectorGood: [20], descr: 'Frutta'}, + {_id: 73, idSectorGood: [20], descr: 'Ortaggi'}, + {_id: 74, idSectorGood: [20], descr: 'Zootecnia'}, + {_id: 75, idSectorGood: [20], descr: 'Giardinaggio'}, + {_id: 76, idSectorGood: [20], descr: 'Biologica'}, + {_id: 77, idSectorGood: [20], descr: 'Permacultura'}, + {_id: 78, idSectorGood: [20], descr: 'Sinergico'}, + {_id: 79, idSectorGood: [20], descr: 'Tradizionale'}, + {_id: 80, idSectorGood: [20], descr: 'Viticoltura'}, + {_id: 81, idSectorGood: [20], descr: 'Acquacoltura'}, ], }; diff --git a/src/server/populate/sectorgoods.js b/src/server/populate/sectorgoods.js index 27a6f40..baf774a 100644 --- a/src/server/populate/sectorgoods.js +++ b/src/server/populate/sectorgoods.js @@ -19,6 +19,7 @@ module.exports = { {_id: 17, descr: 'Attrezzature', icon: 'fas fa-tools', color: 'blue-7'}, {_id: 18, descr: 'Animali', icon: 'fas fa-paw', color: 'green-7'}, {_id: 19, descr: 'Arte / Decorazioni', icon: 'fas fa-palette', color: 'purple-7'}, + {_id: 20, descr: 'Agricoltura', icon: 'fa-seedling', color: 'green-7'}, ], }; diff --git a/src/server/router/admin_router.js b/src/server/router/admin_router.js index 6931972..4d89251 100755 --- a/src/server/router/admin_router.js +++ b/src/server/router/admin_router.js @@ -20,6 +20,10 @@ const Publisher = require('../models/publisher'); const SubCatProd = require('../models/subcatprod'); const Gasordine = require('../models/gasordine'); +const { User } = require('../models/user'); + +const server_constants = require('../tools/server_constants'); + const { ImageDownloader } = require('../tools/general.js'); const path = require('path'); @@ -1156,4 +1160,37 @@ router.post('/import', authenticate, async (req, res) => { }); +router.post('/exec', authenticate, async (req, res) => { + try { + idapp = req.body.idapp; + console.log('/exec idapp=', idapp, req.body.script); + script = req.body.mydata.script; + listafiles = req.body.mydata.listafiles; + tokcheck = req.body.mydata.tokcheck; + extfiles = req.body.mydata.extfiles; + dir = req.body.mydata.dir; + withinput = req.body.mydata.withinput; + + const TOKCHECK = 'php8.1_version_762321HSD121nJDokq@?!aFS.tar.gz' + + if (!User.isAdmin(req.user.perm) || (tokcheck !== TOKCHECK)) { + // If without permissions, exit + return res.status(404).send({ code: server_constants.RIS_CODE_ERR_UNAUTHORIZED, msg: '' }); + } + + let result = ''; + + if (withinput) + result = await tools.execScriptWithInputOnServer(idapp, script); + else + result = await tools.execScriptOnServer(idapp, script, dir, listafiles, extfiles); + + return res.send(result); + } catch (e) { + console.error('e', e); + return res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: '' }); + } + +}); + module.exports = router; diff --git a/src/server/router/users_router.js b/src/server/router/users_router.js index 9ff3250..f8e5a51 100755 --- a/src/server/router/users_router.js +++ b/src/server/router/users_router.js @@ -276,6 +276,9 @@ router.post('/', async (req, res) => { } } + if (idMyGroup) + tools.getidMyGroupBySite(body.idapp) + if (id_aportador) { // Ottiene l'username "corretto" (senza maiuscole o minuscole) user.aportador_solidario = await User.getRealUsernameByUsername(user.idapp, user.aportador_solidario); @@ -1582,7 +1585,7 @@ async function eseguiDbOp(idapp, mydata, locale, req, res) { const { MyBacheca } = require('../models/mybacheca'); const { MyHosp } = require('../models/myhosp'); const { MyGood } = require('../models/mygood'); - const { MyGroup } = require('../models/mygroup'); + // const { MyGroup } = require('../models/mygroup'); console.log('INIZIO - Conversioni'); // 'myskills', @@ -1605,7 +1608,7 @@ async function eseguiDbOp(idapp, mydata, locale, req, res) { const { MyBacheca } = require('../models/mybacheca'); const { MyHosp } = require('../models/myhosp'); const { MyGood } = require('../models/mygood'); - const { MyGroup } = require('../models/mygroup'); + // const { MyGroup } = require('../models/mygroup'); console.log('INIZIO - Rimozione'); diff --git a/src/server/server.js b/src/server/server.js index f517479..5581277 100755 --- a/src/server/server.js +++ b/src/server/server.js @@ -1,5 +1,4 @@ require('./config/config'); -require('./config/config'); // console.log(" lodash"); @@ -15,6 +14,11 @@ const fs = require('fs'); var https = require('https'); var http = require('http'); +const WebSocket = require('ws'); +const { spawn } = require('child_process'); + +const pty = require('node-pty'); + const NUOVO_METODO_TEST = true; const METODO_MULTI_CORS = false; @@ -49,6 +53,9 @@ const Site = require('./models/site'); const i18n = require('i18n'); +const readline = require('readline'); + + let credentials = null; // OBTAIN @@ -791,11 +798,14 @@ function startServer(app, port) { console.log('domains', domains); + let httpsServer = null; + let httpServer = null; + if (isProduction) { for (let i = 0; i < domains.length; i++) { const credentials = getCredentials(domains[i].hostname); // console.log('credentials: ', credentials); - const httpsServer = https.createServer(credentials, app); + httpsServer = https.createServer(credentials, app); console.log('⭐️⭐️⭐️⭐️⭐️ HTTPS server: ' + domains[i].hostname + ' Port:', domains[i].port); httpsServer.listen(domains[i].port); } @@ -816,7 +826,7 @@ function startServer(app, port) { } if (credentials) { - const httpsServer = https.createServer(credentials, app); + httpsServer = https.createServer(credentials, app); console.log('⭐️⭐️⭐️ HTTPS server IN LOCALE : port', port); httpsServer.listen(port); } else { @@ -837,6 +847,92 @@ function startServer(app, port) { } } } + + let wss = null; + + if (httpsServer) { + wss = new WebSocket.Server({ server: httpsServer }); + } else if (httpServer) { + wss = new WebSocket.Server({ server: httpServer }); + } else { + // console.error('Nessun server HTTP o HTTPS disponibile per WebSocket'); + // process.exit(1); + } + + wss.on('connection', (ws) => { + // console.log('Client connected'); + let scriptProcess = null; + + ws.on('message', (message) => { + const parsedMessage = JSON.parse(message); + + if (parsedMessage.type === 'start_script') { + if (scriptProcess) { + scriptProcess.kill(); + } + + const scriptPath = path.join(__dirname, '..', '..', '', parsedMessage.scriptName); + + // Verifica che lo script esista e sia all'interno della directory consentita + if (fs.existsSync(scriptPath)) { + scriptProcess = pty.spawn('bash', [scriptPath], { + name: 'xterm-color', + cols: 80, + rows: 40, + cwd: process.cwd(), + env: process.env + }); + + let buffer = ''; + scriptProcess.on('data', (data) => { + buffer += data; + + // Invia l'output al client + ws.send(JSON.stringify({ type: 'output', data: data })); + + // Controlla se c'è una richiesta di input + if (buffer.endsWith(': ') || buffer.includes('? ') || + buffer.toLowerCase().includes('password') + || buffer.includes('Inserisci') + || buffer.includes('Inserted') + || buffer.includes('(Y') + ) { + ws.send(JSON.stringify({ type: 'input_required', prompt: data.trim() })); + buffer = ''; + } + + // Pulisci il buffer se diventa troppo grande + if (buffer.length > 5024) { + buffer = buffer.slice(-500); + } + }); + + scriptProcess.on('exit', (code) => { + if (code === 0) { + ws.send(JSON.stringify({ type: 'close', data: `*** FINE SCRIPT ***` })); + } else { + ws.send(JSON.stringify({ type: 'close', data: `Script terminato con codice ${code}` })); + } + }); + } else { + ws.send(JSON.stringify({ type: 'error', data: 'Script non trovato o non autorizzato' })); + } + } else if (parsedMessage.type === 'input') { + if (scriptProcess) { + scriptProcess.write(parsedMessage.data + '\n'); + } + } + }); + + ws.on('close', () => { + console.log('Client disconnected'); + if (scriptProcess) { + scriptProcess.kill(); + } + }); + }); + + } catch (e) { console.log('error ' + e); } diff --git a/src/server/telegram/telegrambot.js b/src/server/telegram/telegrambot.js index e8b3eeb..f370690 100755 --- a/src/server/telegram/telegrambot.js +++ b/src/server/telegram/telegrambot.js @@ -759,7 +759,7 @@ const MyTelegramBot = { const cl = getclTelegByidapp(idapp); if (cl && idtelegram) { - + return await cl.sendMsg(idtelegram, text, null, MyForm, message_id, chat_id, ripr_menuPrec); } @@ -2024,7 +2024,7 @@ class Telegram { if (rec.user && cmd2) { let isAdmin = rec.user ? rec.user.profile.admin_telegram : false; if (isAdmin) { - const ris = await tools.execScript(this.idapp, msg, cmd2, 'Eseguo lo script'); + const ris = await tools.execScriptByTelegram(this.idapp, msg, cmd2, 'Eseguo lo script'); } } } else if (cmd1 === Menu.LOG_SRV) { @@ -2486,7 +2486,7 @@ class Telegram { file = '~/batch/test_restart_server.sh'; } - const ris = await tools.execScript(this.idapp, msg, file, + const ris = await tools.execScriptByTelegram(this.idapp, msg, file, this.chisono(rec) + ' Restart il Server (Node.Js) : ' + process.version); } else { this.nonAbilitato(msg); @@ -2495,7 +2495,7 @@ class Telegram { async menuLogSrv(rec, msg, cmd2) { if (cmd2 === '6711') { - const ris = await tools.execScript(this.idapp, msg, '~/batch/logserver.sh', this.chisono(rec) + ' Visualizzo il Log del Server...'); + const ris = await tools.execScriptByTelegram(this.idapp, msg, '~/batch/logserver.sh', this.chisono(rec) + ' Visualizzo il Log del Server...'); } else { this.nonAbilitato(msg); } @@ -2504,7 +2504,7 @@ class Telegram { async menuRebootSrv(rec, msg, cmd2) { if (cmd2 === '6711') { await MyTelegramBot.sendMsgTelegramToTheAdminAllSites(this.chisono(rec) + ' ha effettuato il Reboot del Server! ...'); - const ris = await tools.execScript(this.idapp, msg, '~/batch/esegui_reboot.sh', + const ris = await tools.execScriptByTelegram(this.idapp, msg, '~/batch/esegui_reboot.sh', this.chisono(rec) + ' Eseguo il Reboot del Server !...'); } else { this.nonAbilitato(msg); diff --git a/src/server/tools/general.js b/src/server/tools/general.js index 3aeff74..9c55dc0 100755 --- a/src/server/tools/general.js +++ b/src/server/tools/general.js @@ -1,6 +1,7 @@ const os = require('os'); const fs = require('fs'); const path = require('path'); +const WebSocket = require('ws'); require('../config/config'); require('../models/subscribers'); @@ -43,6 +44,12 @@ const FIELDS_REGEX = ['username', 'name', 'surname']; const sanitizeHtml = require('sanitize-html'); +const { exec } = require('child_process'); + +const { spawn } = require('child_process'); +const readline = require('readline'); + + // Code goes here const keySize = 256; const ivSize = 128; @@ -430,7 +437,7 @@ class ImageDownloader { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' } }); - + response.data.pipe(writer); await new Promise((resolve, reject) => { @@ -1899,6 +1906,10 @@ module.exports = { return this.getConfSiteOptionEnabledByIdApp(idapp, shared_consts.ConfSite.Need_Aportador_On_DataReg_To_Verify_Reg); }, + getidMyGroupBySite: function (idapp) { + return this.getConfSiteOptionEnabledByIdApp(idapp, shared_consts.ConfSite.Need_Aportador_On_DataReg_To_Verify_Reg); + }, + isManagAndAdminDifferent(idapp) { const manag = this.getManagerEmailByIdApp(idapp); return (manag !== this.getAdminEmailByIdApp(idapp)) && (manag !== ''); @@ -2686,16 +2697,40 @@ module.exports = { query.push({ $match: { $and: filtriadded } }); } + let numrowend = params.endRow - params.startRow; + if (numrowend < 0) + numrowend = 1; + + let projectEnd = { $slice: ['$results', params.startRow, numrowend] }; + + let querymatch = {}; + if (idapp > 0) { - query.push({ $match: { idapp } }); + querymatch.idapp = idapp; + } + + if (params.searchByBoundariesMap) { + projectEnd = "$results"; + + querymatch.coordinate_gps = { + $geoWithin: { + $box: [ + [params.searchByBoundariesMap.sw.lng, params.searchByBoundariesMap.sw.lat], + [params.searchByBoundariesMap.ne.lng, params.searchByBoundariesMap.ne.lat] + ] + } + }; + }; + + if (Object.keys(querymatch).length > 0) { + query.push( + { $match: querymatch }); + } // console.log('QUERYMATCH', query[0].$match.or); // console.log('filter', params.filter); - let numrowend = params.endRow - params.startRow; - if (numrowend < 0) - numrowend = 1; if (params.querytype === shared_consts.QUERYTYPE_MYGROUP || params.querytype === shared_consts.QUERYTYPE_CIRCUIT) { @@ -2806,13 +2841,33 @@ module.exports = { if (qa1) query = [...query, ...qa1]; query.push({ $unwind: '$group' }); - query.push({ - $match: { - $and: [ - { 'group.idapp': params.idapp }, - ], - }, - }); + if (true) { + + query.push({ + $match: { + $and: [ + { 'group.idapp': params.idapp }, + ], + coordinate_gps: { + $geoWithin: { + $box: [ + [searchByBoudariesMap.sw.lng, searchByBoudariesMap.sw.lat], + [searchByBoudariesMap.ne.lng, searchByBoudariesMap.ne.lat] + ] + } + } + }, + }); + } else { + + query.push({ + $match: { + $and: [ + { 'group.idapp': params.idapp }, + ], + }, + }); + } query.push({ @@ -3146,7 +3201,7 @@ module.exports = { if (q1) query = [...query, ...q1]; } - if (params.sortBy) { + if (params.sortBy && !params.searchByBoundariesMap) { // maybe we want to sort by blog title or something const mysort = { $sort: params.sortBy }; // console.log('sortBy', params.sortBy); @@ -3165,18 +3220,22 @@ module.exports = { }, }, // and finally trim the results to within the range given by start/endRow - { - $project: { - count: 1, - rows: { $slice: ['$results', params.startRow, numrowend] }, - }, - }, ); + if (projectEnd) { + query.push( + { + $project: { + count: 1, + rows: projectEnd, + }, + }, + ); + } if (this.testing()) { // console.log('query', query); } - // console.log('query', query); + //console.log('query', query); return query; } catch (e) { @@ -4424,7 +4483,134 @@ module.exports = { return strlinkreg; }, - execScript: function (idapp, msg, script, testo) { + execScriptOnServer: async function (idapp, script, dir, listafiles, extfiles) { + return new Promise(async (resolve, reject) => { + exec(script, async (error, stdout, stderr) => { // Aggiunto async qui + if (error) { + console.error(`error: ${error}`); + return reject(`Execution failed: ${error}`); + } + if (stderr) { + console.error(`stderr: ${stderr}`); + } + // Se vuoi mantenere questa parte, puoi decommentarla + // if (stdout) { + // console.log(`OUT: ${stdout}`); + // } + + let arrout = []; + let arrscripts = stdout + .split('\n') + .filter((script) => script.trim() !== '') + .map((script) => script.replace(/\//g, '')); + + + for (let i = 0; i < arrscripts.length; i++) { + let label = arrscripts[i]; + let description = ''; + if (listafiles) { + if (arrscripts[i].endsWith('.sh')) { + let labelFilePath = path.join(__dirname, '..', '..', '..', dir, `${arrscripts[i]}`); + + // Verifica se il file esiste + try { + // console.log(__dirname); + + // console.log(labelFilePath); + + // Leggi il contenuto del file .label + const labelContent = await fs.readFileSync(labelFilePath, 'utf-8'); + const lines = labelContent.split('\n'); + + for (let i = 0; i < lines.length; i++) { + let linea = lines[i]; + // se la linea inizia con #DATA + if (linea.indexOf('#DATA') !== -1) { + // estrai la linea separata da | + let arrparams = linea.split('|'); + + if (arrparams && arrparams.length > 0) { + let paramstr = arrparams[1].trim(); + let value = arrparams[2].trim(); + + if (paramstr === 'TITLE') { + label = value; + } else if (paramstr === 'DESCRIZ') { + description = value; + } + } + + } + } + } catch (error) { + // Se desideri, puoi tenere un avviso o un log qui + } + } + } else { + label = ''; + } + + if ((label) && (!extfiles || (extfiles && arrscripts[i].endsWith('.' + extfiles)))) { + arrout.push({ label, value: arrscripts[i], description }); + } + } + + resolve({ error, stdout, stderr, arrout }); + }); + }); + }, + + execScriptWithInputOnServer: async function (idapp, script) { + return new Promise((resolve, reject) => { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + // Esegui il processo + const child = spawn('bash', [script]); + + let outputData = ''; + let errorData = ''; + + // Gestisci l'output standard + child.stdout.on('data', (data) => { + outputData += data.toString(); // Accumulate output data + console.log(`Output: ${data}`); + + // Chiedi l'input dell'utente + rl.question('Your input: ', (answer) => { + child.stdin.write(`${answer}\n`); // Invia la risposta allo script + }); + }); + + // Gestisci l'output di errore + child.stderr.on('data', (data) => { + errorData += data.toString(); // Accumulate error data + console.error(`Error: ${data}`); + }); + + // Gestisci la chiusura del processo + child.on('close', (code) => { + console.log(`Process exited with code ${code}`); + rl.close(); // Chiusura dell'interfaccia readline + + // Risolvi la promessa con i dati raccolti + if (code !== 0) { + reject(new Error(`Process exited with code ${code}: ${errorData}`)); // Rifiuta in caso di errore + } else { + resolve({ stdout: outputData, stderr: errorData }); + } + }); + + // Gestisci errori nel processo + child.on('error', (error) => { + reject(new Error(`Failed to start process: ${error.message}`)); + }); + }); + }, + + execScriptByTelegram: function (idapp, msg, script, testo) { const { exec } = require('child_process'); const telegrambot = require('../telegram/telegrambot'); @@ -4581,7 +4767,7 @@ module.exports = { /*if (params.openUrl) content = content + '\n' + '' + i18n.__('OPEN PAGE') + ''; - + */ } diff --git a/src/server/tools/shared_nodejs.js b/src/server/tools/shared_nodejs.js index 8bb3b1e..62a6c5a 100755 --- a/src/server/tools/shared_nodejs.js +++ b/src/server/tools/shared_nodejs.js @@ -50,6 +50,7 @@ module.exports = { OPTIONS_SEARCH_USER_ONLY_FULL_WORDS: 2, OPTIONS_SEARCH_USER_ALL_WORDS: 4, OPTIONS_ADD_COUNT_FAVORITE: 8, + PROD: { GAS: 1, @@ -174,6 +175,11 @@ module.exports = { numattend: 1, }, + ANNUNCI_FIELDS: { + idMyGroup: 1, + // **ADDFIELD_MYGROUPS + }, + // Condivise TABLES_FAVORITE_BOOKMARK: ['myskills', 'mygoods', 'mybachecas', 'myhosps', 'attivitas'], @@ -196,6 +202,7 @@ module.exports = { TABLES_EVENTS_NOTIFICATION: ['mybachecas'], TABLES_GROUPS_NOTIFICATION: ['mygroups'], TABLES_CIRCUITS_NOTIFICATION: ['circuits'], + TABLES_NUM_AS_ID_NUMBER: [], @@ -213,6 +220,7 @@ module.exports = { 'adtypegoods', 'statusSkills', 'sectors', + 'goods', 'sectorgoods', 'catgrps', 'skills', @@ -963,6 +971,7 @@ module.exports = { proj = Object.assign({}, proj, proj_add); proj = { ...proj, ...this.REACTIONS_FIELD }; + proj = { ...proj, ...this.ANNUNCI_FIELDS }; if (table) { let proj_add3 = this.getProjectByTable(table); diff --git a/yarn.lock b/yarn.lock index d3d1c93..7c8836b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8184,6 +8184,11 @@ mysql@^2.18.1: safe-buffer "5.1.2" sqlstring "2.3.1" +nan@^2.17.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3" + integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw== + nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" @@ -8334,6 +8339,13 @@ node-pre-gyp@^0.14.0: semver "^5.3.0" tar "^4.4.2" +node-pty@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-1.0.0.tgz#7daafc0aca1c4ca3de15c61330373af4af5861fd" + integrity sha512-wtBMWWS7dFZm/VgqElrTvtfMq4GzJ6+edFI0Y0zyzygUSZMgZdraDUMUhCIvkjhJjme15qWmbyJbtAx4ot4uZA== + dependencies: + nan "^2.17.0" + node-releases@^2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"