From 768d299881788141519d1be25ef0b5c0b7af01f2 Mon Sep 17 00:00:00 2001 From: Surya Paolo Date: Thu, 15 May 2025 14:27:46 +0200 Subject: [PATCH] - sistemato timeout corto - corretto errori sulla generazione del PDF - corretto alcune directory - corretto fs.promise - corretto CORS ! --- plugins/googleapi.js | 2 +- src/server/models/order.js | 2 +- src/server/router/admin_router.js | 4 +- src/server/router/api_router.js | 27 ++ src/server/router/index_router.js | 2 +- src/server/server.js | 693 ++++++++++++++--------------- src/server/telegram/telegrambot.js | 6 +- src/server/tools/general.js | 45 +- src/server/tools/globalTables.js | 2 +- src/server/version.txt | 2 +- 10 files changed, 402 insertions(+), 383 deletions(-) create mode 100644 src/server/router/api_router.js diff --git a/plugins/googleapi.js b/plugins/googleapi.js index ce987a6..d936242 100755 --- a/plugins/googleapi.js +++ b/plugins/googleapi.js @@ -1,4 +1,4 @@ -const fs = require('fs'); +const fs = require('fs'); const readline = require('readline'); const {google} = require('googleapis'); var FILE = require('./file'); diff --git a/src/server/models/order.js b/src/server/models/order.js index e84bf3e..d5a8729 100755 --- a/src/server/models/order.js +++ b/src/server/models/order.js @@ -9,7 +9,7 @@ const { ObjectId } = require('mongodb'); mongoose.Promise = global.Promise; mongoose.level = "F"; -const fs = require('fs'); +const fs = require('fs'); // 👈 Usa il modulo promises // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { diff --git a/src/server/router/admin_router.js b/src/server/router/admin_router.js index fdb9142..3ae395b 100755 --- a/src/server/router/admin_router.js +++ b/src/server/router/admin_router.js @@ -9,7 +9,7 @@ const tools = require('../tools/general'); const Macro = require('../modules/Macro'); // Importa la classe Macro -const fs = require('fs'); +const fs = require('fs'); // 👈 Usa il modulo promises const { City } = require('../models/city'); const Product = require('../models/product'); @@ -140,7 +140,9 @@ async function compressPdf(inputFile, outputFile, compressione) { const hasTempFolder = tools.isFileExists(tempFolder); if (!hasTempFolder) { + console.log('creo directory', tempFolder); await fs.mkdir(tempFolder); // Usa la versione promessa di mkdir + console.log('✅ directory creata', tempFolder); } /* diff --git a/src/server/router/api_router.js b/src/server/router/api_router.js new file mode 100644 index 0000000..e4ceb48 --- /dev/null +++ b/src/server/router/api_router.js @@ -0,0 +1,27 @@ +const express = require("express"); +const { authenticate } = require("../middleware/authenticate"); + +const router = express.Router(); + +router.post('/test-lungo', authenticate, (req, res) => { + const timeout = req.body.timeout; + + console.log(`🕙 Richiesta iniziata con timeout=${timeout}`); + + // Simuliamo un'elaborazione lunga + const durataMs = timeout - 2000; + setTimeout(() => { + console.log(`✅ Elaborazione completata di ${durataMs} ms`); + res.json({ ok: true, message: `✅ Richiesta completata con successo! (${durataMs})` }); + }, durataMs); + + // Verifico se la richiesta va a buon fine + setTimeout(() => { + if (!res.headersSent) { + res.status(500).json({ ok: false, message: '❌ Errore durante l\'elaborazione della richiesta!' }); + } + }, durataMs + 1000); + }); + +module.exports = router; + diff --git a/src/server/router/index_router.js b/src/server/router/index_router.js index 4c68e81..6b5f531 100755 --- a/src/server/router/index_router.js +++ b/src/server/router/index_router.js @@ -2351,7 +2351,7 @@ function uploadFile(req, res, version) { // console.log('mydir', mydir); // Create Dir if doesn't exist: - const rismk = tools.mkdirpath(mydir); + const rismk = await tools.mkdirpath(mydir); let filename = file.originalFilename; let ext = path.extname(filename); diff --git a/src/server/server.js b/src/server/server.js index 360789f..256a6de 100755 --- a/src/server/server.js +++ b/src/server/server.js @@ -13,7 +13,7 @@ const _ = require('lodash'); const cors = require('cors'); // console.log(" 2) fs"); -const fs = require('fs'); +const fs = require('fs'); // 👈 Usa il modulo promises var https = require('https'); var http = require('http'); @@ -136,6 +136,7 @@ connectToDatabase(connectionUrl, options) const mygen_router = require('./router/mygen_router'); const aitools_router = require('./router/aitools_router'); const article_router = require('./router/articleRoutes'); + const api_router = require('./router/api_router'); const { MyEvent } = require('./models/myevent'); @@ -245,6 +246,7 @@ connectToDatabase(connectionUrl, options) app.use('/mygen', mygen_router); app.use('/aitools', aitools_router); app.use('/apisqlsrv', article_router); + app.use('/api', api_router); mystart(); }); @@ -531,16 +533,16 @@ connectToDatabase(connectionUrl, options) try { // console.log('checkdir', folderprof); - if (!fs.existsSync(folderprof)) { + if (!tools.existsSync(folderprof)) { console.log('*** Creadir', folderprof); - fs.mkdirSync(folderprof); + await fs.mkdirSync(folderprof); } folderprof = dir + 'profile/' + myuser.username + '/' + table; // console.log('checkdir', folderprof); - if (!fs.existsSync(folderprof)) { + if (!tools.existsSync(folderprof)) { console.log('creadir', folderprof); - fs.mkdirSync(folderprof); + await fs.mkdirSync(folderprof); } } catch (e) {} } @@ -671,383 +673,352 @@ connectToDatabase(connectionUrl, options) } } + // Funzione migliorata per ottenere chiave e certificato function getCredentials(hostname) { - if (NUOVO_METODO_TEST) { - if (METODO_MULTI_CORS) { - const fileprivkey = `/etc/letsencrypt/live/${hostname}/` + process.env.PATH_CERT_KEY; - const filecert = `/etc/letsencrypt/live/${hostname}/` + process.env.PATH_SERVER_CRT; + try { + let keyPath, certPath; - console.log('fileprivkey: ', fileprivkey, ' filecert: ', filecert); - - /* return { - - SNICallback: function (hostname, callback) { - console.log('hostname: ', hostname); - if (domains.includes(hostname)) { - const fileprivkey = `/etc/letsencrypt/live/${hostname}/privkey.pem`; - const filecert = `/etc/letsencrypt/live/${hostname}/fullchain.pem`; - - // console.log('fileprivkey: ', fileprivkey, ' filecert: ', filecert); - - const domainCert = { - key: fs.readFileSync(fileprivkey, "utf8"), - cert: fs.readFileSync(filecert, "utf8"), - }; - callback(null, domainCert); - } else { - callback(null, { key: privateKey, cert: certificate }); - } - } - - };*/ - - try { - const key = fs.readFileSync(fileprivkey, 'utf8'); - const cert = fs.readFileSync(filecert, 'utf8'); - return { key, cert }; - } catch (error) { - console.error(`Errore nel caricamento delle credenziali per ${hostname}:`, error); - // Gestisci l'errore, per esempio ritorna null o lancia un'eccezione + if (NUOVO_METODO_TEST) { + if (METODO_MULTI_CORS) { + // Percorso basato su hostname (Let's Encrypt) + keyPath = `/etc/letsencrypt/live/${hostname}/${process.env.PATH_CERT_KEY}`; + certPath = `/etc/letsencrypt/live/${hostname}/${process.env.PATH_SERVER_CRT}`; + } else { + // Percorso relativo + keyPath = path.resolve(`./${process.env.PATH_CERT_KEY}`); + certPath = path.resolve(`./${process.env.PATH_SERVER_CRT}`); } + + // Verifica esistenza file + if (!tools.existsSync(keyPath)) { + throw new Error(`Chiave privata non trovata: ${keyPath}`); + } + if (!tools.existsSync(certPath)) { + throw new Error(`Certificato non trovato: ${certPath}`); + } + + // Leggi chiave e certificato + const key = fs.readFileSync(keyPath, 'utf8'); + const cert = fs.readFileSync(certPath, 'utf8'); + + // Restituisci oggetto con credenziali + configurazione TLS avanzata + return { + key, + cert, + ciphers: + 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384', + honorCipherOrder: true, + secureOptions: require('constants').OPENSSL_OPTIONS_TLS_NODELAY, + secureProtocol: 'TLSv1_2_method', // Forza TLS 1.2+ (meglio se usi TLSv1_3) + }; } else { - const keyStream = path.resolve(`./${process.env.PATH_CERT_KEY}`); - const certificateStream = path.resolve(`./${process.env.PATH_SERVER_CRT}`); + // Metodo legacy (opzionale) + throw new Error('Metodo legacy non supportato'); + } + } catch (error) { + console.error(`[getCredentials] Errore per ${hostname}:`, error.message); + throw error; + } + } + // 🔧 Funzione factory per creare e configurare un server HTTPS + function createHttpsServer({ hostname, port, website, app, credentials, timeoutMinutes = 5 }) { + const server = https.createServer(credentials, app); - const privateKey = fs.readFileSync(keyStream, 'utf8'); - const certificate = fs.readFileSync(certificateStream, 'utf8'); + const timeoutMs = 1000 * 60 * timeoutMinutes; - return { key: privateKey, cert: certificate }; + // ⏱️ Timeout globale per la connessione TCP + server.setTimeout(timeoutMs, () => { + console.log(`TCP timeout su server: ${hostname}:${port}`); + }); + + // ⏱️ Timeout per singola richiesta HTTP + server.on('request', (req, res) => { + req.setTimeout(timeoutMs); + res.setTimeout(timeoutMs); + }); + + // 📡 Eventuali altri eventi utili + server.on('clientError', (err, socket) => { + console.error(`Client error su ${hostname}:${port}:`, err.message); + }); + + // Avvia il server + server.listen(port, () => { + console.log( + '⭐️⭐️⭐️⭐️⭐️ HTTPS server: %s Port: %d%s', + hostname, + port, + website ? ' WebSite = ' + website : '' + ); + }); + + return server; + } + + function parseDomains() { + let domains = []; + let domainsAllowed = []; + try { + if (process.env.DOMAINS) domains = JSON.parse(process.env.DOMAINS); + if (process.env.DOMAINS_ALLOWED) domainsAllowed = JSON.parse(process.env.DOMAINS_ALLOWED); + } catch (error) { + console.error('Errore parsing DOMAINS:', error); + } + return { domains, domainsAllowed }; + } + + function buildAllowedOrigins(domains, domainsAllowed, isProduction) { + if (!isProduction) { + return ['https://localhost:3000', 'https://localhost:8089', 'https://localhost:8084', 'https://localhost:8088']; + } + + const baseOrigins = domains.flatMap((domain) => [ + `https://${domain.hostname}`, + `https://api.${domain.hostname}`, + `https://test.${domain.hostname}`, + `https://testapi.${domain.hostname}`, + `http://${domain.hostname}`, + `http://api.${domain.hostname}`, + `http://test.${domain.hostname}`, + `http://testapi.${domain.hostname}`, + ]); + + const allowedExtra = domainsAllowed.flatMap((domain) => [`https://${domain}`, `http://${domain}`]); + + return [...baseOrigins, ...allowedExtra]; + } + + function createCorsOptions(domains, domainsAllowed, isProduction, noCors = false) { + if (noCors) { + console.log('NOCORS mode enabled'); + return { + exposedHeaders: ['x-auth', 'x-refrtok'], + }; + } + + const allowedOrigins = buildAllowedOrigins(domains, domainsAllowed, isProduction); + + const originValidator = (origin, callback) => { + if (!origin) { + console.log('✅ Origin undefined or empty — allowing'); + return callback(null, true); + } + + if (typeof origin !== 'string' || !/^https?:\/\/[^\s/$.?#].[^\s]*$/.test(origin)) { + console.error('❌ Invalid origin:', origin); + return callback(new Error('Origine non valida'), false); + } + + if (allowedOrigins.includes(origin)) { + return callback(null, true); + } + + console.warn('❌ Origin blocked:', origin); + return callback(new Error('CORS non permesso per questa origine'), false); + }; + + return { + origin: originValidator, + credentials: true, + methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'], + allowedHeaders: [ + 'Origin', + 'X-Requested-With', + 'Content-Type', + 'Accept', + 'Authorization', + 'x-auth', + 'x-refrtok', + ], + exposedHeaders: ['x-auth', 'x-refrtok'], + maxAge: 86400, + preflightContinue: false, + optionsSuccessStatus: 204, + }; + } + + function setupMiddleware(app, corsOptions, isDebug = false) { + app.use(cors(corsOptions)); + app.use(express.json()); + app.options('*', cors(corsOptions)); + + if (isDebug) { + app.use((req, res, next) => { + console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`); + console.log('Request Headers:', req.headers); + + const oldSend = res.send; + res.send = function (...args) { + console.log('Response Headers:', res.getHeaders()); + return oldSend.apply(res, args); + }; + + next(); + }); + } + + app.use((err, req, res, next) => { + if (err.message === 'CORS non permesso per questa origine') { + console.error('❌ Errore CORS:', { + origin: req.headers.origin, + method: req.method, + path: req.path, + }); + return res.status(403).json({ + error: `❌ CORS non permesso per questa origine (${req.headers.origin})`, + origin: req.headers.origin, + }); + } + next(err); + }); + } + + function createHttpOrHttpsServer(app, port, isProduction, domains) { + if (isProduction) { + domains.forEach((domain) => { + const credentials = getCredentials(domain.hostname); + createHttpsServer({ + hostname: domain.hostname, + port: domain.port, + website: domain.website, + app, + credentials, + timeoutMinutes: 6, + }); + }); + return null; + } + + if (process.env.HTTPS_LOCALHOST === 'true') { + try { + const key = fs.readFileSync(path.resolve(`./${process.env.PATH_CERT_KEY}`), 'utf8'); + const cert = fs.readFileSync(path.resolve(`./${process.env.PATH_SERVER_CRT}`), 'utf8'); + + const credentials = { + key, + cert, + ciphers: + 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384', + honorCipherOrder: true, + secureProtocol: 'TLSv1_2_method', + }; + + const httpsServer = https.createServer(credentials, app); + httpsServer.listen(port); + console.log('⭐️ HTTPS server running locally on port', port); + return httpsServer; + } catch (error) { + console.error('Errore caricamento certificati HTTPS locali:', error.message); + // fallback HTTP server } } - // Caso di default non specificato, potrebbe essere necessario aggiungere una gestione degli errori qui + + const httpServer = http.createServer(app); + httpServer.listen(port); + console.log('⭐️ HTTP server running on port', port); + return httpServer; + } + + function setupWebSocketServer(httpOrHttpsServer) { + if (!httpOrHttpsServer) { + console.error('Nessun server HTTP o HTTPS disponibile per WebSocket'); + return null; + } + + const wss = new WebSocket.Server({ server: httpOrHttpsServer }); + + wss.on('connection', (ws) => { + console.log('Client socket connected...'); + + const { User } = require('./models/user'); + const pty = require('node-pty'); + let scriptProcess = null; + + ws.on('message', (message) => { + try { + const parsed = JSON.parse(message); + + if (parsed.type === 'start_script' && User.isAdminById(parsed.user_id)) { + if (scriptProcess) scriptProcess.kill(); + + const scriptPath = path.join(__dirname, '..', '..', parsed.scriptName); + if (!tools.existsSync(scriptPath)) { + return ws.send(JSON.stringify({ type: 'error', data: 'Script non trovato o non autorizzato' })); + } + + 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; + ws.send(JSON.stringify({ type: 'output', data })); + + 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 = ''; + } + + if (buffer.length > 5024) buffer = buffer.slice(-500); + }); + + scriptProcess.on('exit', (code) => { + const closeMsg = code === 0 ? '*** FINE SCRIPT ***' : `Script terminato con codice ${code}`; + ws.send(JSON.stringify({ type: 'close', data: closeMsg })); + }); + } else if (parsed.type === 'input') { + if (scriptProcess) { + scriptProcess.write(parsed.data + '\n'); + } + } + } catch (err) { + console.error("Errore durante l'elaborazione del messaggio:", err.message); + } + }); + + ws.on('close', () => { + console.log('*** Client socket disconnected'); + if (scriptProcess) scriptProcess.kill(); + }); + }); + + return wss; } function startServer(app, port) { try { const isProduction = ['production', 'test'].includes(process.env.NODE_ENV); - - let domains = []; - let domains_allowed = []; - - try { - if (process.env.DOMAINS) domains = JSON.parse(process.env.DOMAINS); - if (process.env.DOMAINS_ALLOWED) domains_allowed = JSON.parse(process.env.DOMAINS_ALLOWED); - } catch (error) { - console.error('Errore durante la conversione della stringa DOMAINS:', error); - } - - console.log('domains', domains); - - let httpsServer = null; - let httpServer = null; - - console.log('isProduction', isProduction); - + const ISDEBUG = false; const NOCORS = false; - const ISDEBUG = false; + const { domains, domainsAllowed } = parseDomains(); - let corsOptions = {}; + console.log('domains:', domains); + console.log('isProduction:', isProduction); - if (NOCORS) { - console.log('NOCORS'); - corsOptions = { - exposedHeaders: ['x-auth', 'x-refrtok'], // Intestazioni da esporre al client - }; - } else { - console.log('WITH CORS'); - let credentials = true; + const corsOptions = createCorsOptions(domains, domainsAllowed, isProduction, NOCORS); - let allowedOrigins = null; + setupMiddleware(app, corsOptions, ISDEBUG); - if (!isProduction) { - allowedOrigins = 'https://localhost:3000'; - } else { - allowedOrigins = domains.flatMap((domain) => [ - `https://${domain.hostname}`, - `https://api.${domain.hostname}`, - `https://test.${domain.hostname}`, - `https://testapi.${domain.hostname}`, - `http://${domain.hostname}`, - `http://api.${domain.hostname}`, - `http://test.${domain.hostname}`, - `http://testapi.${domain.hostname}`, - ]); + const server = createHttpOrHttpsServer(app, port, isProduction, domains); - // Aggiungi i domini da DOMAINS_ALLOWED - allowedOrigins = allowedOrigins.concat( - domains_allowed.map((domain) => [`https://${domain}`, `http://${domain}`]).flat() - ); - } + const wss = setupWebSocketServer(server); - console.log('allowedOrigins', allowedOrigins); - - let myorigin = '*'; - - if (domains.length > 0) { - myorigin = (origin, callback) => { - try { - // Validazione dell'input - if (origin === undefined) { - console.log('✅ Origin UNDEFINED... vado avanti lo stesso !'); - return callback(null, true); - } - if (!origin || typeof origin !== 'string' || !/^https?:\/\/[^\s/$.?#].[^\s]*$/.test(origin)) { - console.error('❌ Origine non valida:', origin); - return callback(new Error('Origine non valida'), false); - } - - // Controllo delle origini consentite - if (allowedOrigins.includes(origin)) { - // console.log('✅ Origine consentita:', origin); - return callback(null, true); - } - - // Blocco delle origini non autorizzate - console.warn('❌ Origine bloccata:', origin); - return callback(new Error('CORS non permesso per questa origine'), false); - } catch (error) { - console.error("Errore durante la verifica dell'origine:", error.message); - return callback(error, false); - } - }; - } - - // Configurazione CORS dettagliata - const corsOptions = { - origin: myorigin, - credentials, - methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'PATCH'], - allowedHeaders: [ - 'Origin', - 'X-Requested-With', - 'Content-Type', - 'Accept', - 'Authorization', - 'x-auth', - 'x-refrtok', - ], - exposedHeaders: ['x-auth', 'x-refrtok'], - maxAge: 86400, // Preflight cache 24 ore - preflightContinue: false, - optionsSuccessStatus: 204, - }; - - // Applica CORS come primo middleware - app.use(cors(corsOptions)); - - // HO AGGIUNTO QUESTA RIGA PER IL CORS !!!!!!! - app.use(express.json()); // Middleware per il parsing del corpo JSON - - app.options('*', cors(corsOptions)); // Gestisce tutte le richieste OPTIONS - - // Middleware personalizzato per assicurare gli headers CORS - /*app.use((req, res, next) => { - const origin = req.headers.origin || '*'; - if (allowedOrigins.includes(origin) || corsOptions.origin === '*') { - // console.log(' ... ORIGIN', origin); - res.setHeader('Access-Control-Allow-Origin', origin); - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); - res.setHeader('Access-Control-Allow-Credentials', 'true'); - res.setHeader('Access-Control-Expose-Headers', 'x-auth, x-refrtok'); - } - next(); - });*/ - - // Log middleware per debug - app.use((req, res, next) => { - if (ISDEBUG) { - console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`); - console.log('Request Headers:', req.headers); - } - - // Intercetta la risposta per loggare gli headers - const oldSend = res.send; - res.send = function (...args) { - if (ISDEBUG) { - console.log('Response Headers:', res.getHeaders()); - } - return oldSend.apply(res, args); - }; - - next(); - }); - - // Gestione errori CORS - app.use((err, req, res, next) => { - if (err.message === 'CORS non permesso per questa origine') { - console.error('❌ Errore CORS:', { - origin: req.headers.origin, - method: req.method, - path: req.path, - }); - res.status(403).json({ - error: '❌ CORS non permesso per questa origine (' + req.headers.origin + ')', - origin: req.headers.origin, - }); - } else { - next(err); - } - }); - } - - if (isProduction) { - for (let i = 0; i < domains.length; i++) { - const mycredentials = getCredentials(domains[i].hostname); - // console.log('credentials: ', credentials); - httpsServer = https.createServer(mycredentials, app); - console.log( - '⭐️⭐️⭐️⭐️⭐️ HTTPS server: ' + domains[i].hostname + ' Port:', - domains[i].port + (domains[i].website ? 'WebSite = ' + domains[i].website : '') - ); - httpsServer.listen(domains[i].port); - } - } else { - if (process.env.HTTPS_LOCALHOST === 'true') { - let mycredentials = null; - try { - const keyStream = path.resolve(`./${process.env.PATH_CERT_KEY}`); - const certificateStream = path.resolve(`./${process.env.PATH_SERVER_CRT}`); - - const privateKey = fs.readFileSync(keyStream, 'utf8'); - const certificate = fs.readFileSync(certificateStream, 'utf8'); - - mycredentials = { - key: privateKey, - cert: certificate, - ciphers: - 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384', - honorCipherOrder: true, - secureProtocol: 'TLSv1_2_method', - }; - } catch (error) { - console.error('Errore durante la lettura dei file di certificazione, error:', error.message); - throw error; - } - - if (mycredentials) { - httpsServer = https.createServer(mycredentials, app); - console.log('⭐️⭐️⭐️ HTTPS server IN LOCALE : port', port); - httpsServer.listen(port); - } else { - httpServer = http.createServer(app); - if (httpServer) { - console.log('⭐️⭐️⭐️ HTTP server IN LOCALE : port', port); - httpServer.listen(port); - } - } - - // console.log('credentials', credentials); - } else { - httpServer = http.createServer(app); - if (httpServer) { - console.log('⭐️⭐️⭐️ HTTP server IN LOCALE : port', port); - httpServer.listen(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); - } - - if (wss) { - wss.on('connection', (ws) => { - console.log('Client socket connected...'); - - const { User } = require('./models/user'); - - let scriptProcess = null; - - const pty = require('node-pty'); - - ws.on('message', (message) => { - const parsedMessage = JSON.parse(message); - - try { - if (parsedMessage.type === 'start_script' && User.isAdminById(parsedMessage.user_id)) { - 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 && - (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'); - } - } - } catch (error) { - console.error("Errore durante l'elaborazione del messaggio:", error.message); - } - }); - - ws.on('close', () => { - console.log('*** Client socket disconnected'); - if (scriptProcess) { - scriptProcess.kill(); - } - }); - }); - } else { - console.error('Nessuna Socket Aperta con WebSocket !!'); - } - } catch (e) { - console.log('error startServer: ' + e); + return { server, wss }; + } catch (error) { + console.error('Errore in startServer:', error); } } }) diff --git a/src/server/telegram/telegrambot.js b/src/server/telegram/telegrambot.js index 2c3b64c..1574c97 100755 --- a/src/server/telegram/telegrambot.js +++ b/src/server/telegram/telegrambot.js @@ -4152,7 +4152,7 @@ class Telegram { let myfileprofile = tools.getdirByIdApp(idapp, true) + server_constants.DIR_UPLOAD + '/profile/' + username + '/'; let user_profile = bot.getUserProfilePhotos(telegid); - user_profile.then(function (res) { + user_profile.then( function (res) { if (res.total_count === 0) { // Non ho l'accesso oppure sono davvero senza foto ! @@ -4160,7 +4160,7 @@ class Telegram { if (res.photos[0]) { var file_id = res.photos[0][2].file_id; var file = bot.getFile(file_id); - file.then(function (result) { + file.then(async function (result) { const file_path = result.file_path; const photo_url = 'https://api.telegram.org/file/bot' + token + @@ -4170,7 +4170,7 @@ class Telegram { myfileprofile += filename; const pathfile = tools.extractFilePath(myfileprofile); - tools.mkdirpath(pathfile); + await tools.mkdirpath(pathfile); // console.log('2) myfileprofile', pathfile); return tools.downloadImage(photo_url, myfileprofile). diff --git a/src/server/tools/general.js b/src/server/tools/general.js index c57a7aa..9fd78f2 100755 --- a/src/server/tools/general.js +++ b/src/server/tools/general.js @@ -1,5 +1,5 @@ const os = require('os'); -const fs = require('fs'); +const fs = require('fs'); // 👈 Usa il modulo promises const xml2js = require('xml2js'); const path = require('path'); const WebSocket = require('ws'); @@ -445,7 +445,7 @@ class ImageDownloader { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { // Verifica se il filepath esiste già - if (fs.existsSync(filepath)) { + if (await this.existsSync(filepath)) { fs.unlinkSync(filepath); } @@ -533,7 +533,7 @@ class ImageDownloader { console.error(`❌ Errore nel tentativo ${attempt}/${maxRetries}:`, error.message); // Pulizia del file in caso di errore - if (fs.existsSync(filepath)) { + if (await this.existsSync(filepath)) { fs.unlinkSync(filepath); } @@ -554,6 +554,15 @@ class ImageDownloader { } } + async existsSync(tempFolder) { + try { + await fs.access(tempFolder); + // La directory esiste + } catch { + // La directory NON esiste + } + } + // Funzione per estrarre il nome del file dall'URL extractFileNameFromUrl(url) { const match = url.match(/\/([^/?#]+)(?:[?#]|$)/); @@ -727,6 +736,15 @@ module.exports = { console.log(args); }, + existsSync: async function (tempFolder) { + try { + await fs.access(tempFolder); + // La directory esiste + } catch { + // La directory NON esiste + } + }, + mylogserr: function (...args) { console.error(args); }, @@ -4184,15 +4202,15 @@ module.exports = { }); }, - mkdirpath(dirPath) { + async mkdirpath(dirPath) { try { - if (!fs.existsSync(dirPath)) { + if (!await this.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } } catch (e) { if (dirPath !== path.dirname(dirPath)) { const myname = path.dirname(dirPath); - this.mkdirpath(myname); + await this.mkdirpath(myname); // this.mkdirpath(dirPath); } } @@ -4242,9 +4260,9 @@ module.exports = { return namesurname; }, - isFileExists(filename) { + async isFileExists(filename) { try { - return fs.existsSync(filename); + return await this.existsSync(filename); } catch (e) { return false } @@ -5958,7 +5976,7 @@ module.exports = { img = dir + img; /*if (checkifExist) { - if (!fs.existsSync(img)) { + if (!this.existsSync(img)) { return ''; } }*/ @@ -6132,9 +6150,9 @@ module.exports = { server_constants.DIR_UPLOAD + '/products/' + productInfo.image_link.split('/').pop(); const savePath = path.resolve(__dirname, img); // Sostituisci con il percorso dove salvare l'immagine - let scaricaimg = !productInfo.imagefile || !fs.existsSync(savePath); + let scaricaimg = !productInfo.imagefile || !await this.existsSync(savePath); - if (!productInfo.imagefile && fs.existsSync(savePath)) { + if (!productInfo.imagefile && await this.existsSync(savePath)) { // esiste il file, ma sul DB non è corretto const stats = fs.statSync(savePath); // Ottieni informazioni sul file @@ -6148,7 +6166,7 @@ module.exports = { } - if (productInfo.imagefile && fs.existsSync(savePath)) { + if (productInfo.imagefile && await this.existsSync(savePath)) { // esiste il file, ma sul DB non è corretto const stats = fs.statSync(savePath); // Ottieni informazioni sul file @@ -6191,7 +6209,7 @@ module.exports = { const filecompleto = path.resolve(__dirname, img); // Sostituisci con il percorso dove salvare l'immagine // Se non esiste lo scarico ! - fileesistente = fs.existsSync(filecompleto); + fileesistente = await this.existsSync(filecompleto); } if (!vecchiomodo && (!productInfo.image_link || !fileesistente)) { @@ -6296,4 +6314,5 @@ module.exports = { return filename; }, + }; diff --git a/src/server/tools/globalTables.js b/src/server/tools/globalTables.js index 36bd266..fe659d6 100755 --- a/src/server/tools/globalTables.js +++ b/src/server/tools/globalTables.js @@ -1,6 +1,6 @@ const os = require('os'); -const fs = require('fs'); +const fs = require('fs'); // 👈 Usa il modulo promises const path = require('path'); diff --git a/src/server/version.txt b/src/server/version.txt index f301490..457d1be 100644 --- a/src/server/version.txt +++ b/src/server/version.txt @@ -1 +1 @@ -1.2.42 \ No newline at end of file +1.2.44 \ No newline at end of file