- AbitaregliIblei.it

- Server aggiornamenti agli script.
- Editor HTML corretto un po'.
- Record Mysql per server (appena iniziato)
This commit is contained in:
Surya Paolo
2024-09-06 19:57:09 +02:00
parent 45f601bd26
commit fe4a67c9f1
28 changed files with 638 additions and 567 deletions

View File

@@ -0,0 +1,87 @@
const mongoose = require('mongoose').set('debug', false)
const Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
mongoose.level = "F";
const tools = require('../tools/general');
const { ObjectID } = require('mongodb');
// Resolving error Unknown modifier: $pushAll
mongoose.plugin(schema => {
schema.options.usePushEach = true
});
const SectorActivitiesSchema = new Schema({
_id: {
type: Number,
},
descr: {
type: String,
},
idSectorActivities: {
type: Number
},
icon: {
type: String,
},
img: {
type: String,
},
color: {
type: String,
},
theme: {
type: String,
},
});
SectorActivitiesSchema.pre('save', async function (next) {
if (this.isNew) {
const myrec = await SectorActivities.findOne().limit(1).sort({ _id: -1 });
if (!!myrec) {
if (myrec._doc._id === 0)
this._id = 1;
else
this._id = myrec._doc._id + 1;
} else {
this._id = 1;
}
}
next();
});
SectorActivitiesSchema.statics.findAllIdApp = async function (idapp) {
const SectorActivities = this;
const query = [
{ $sort: { descr: 1 } }
];
return await SectorActivities
.aggregate(query)
.then((arrrec) => {
return arrrec
})
};
SectorActivitiesSchema.statics.getFieldsForSearch = function () {
return [{ field: 'descr', type: tools.FieldType.string }]
};
SectorActivitiesSchema.statics.executeQueryTable = function (idapp, params) {
params.fieldsearch = this.getFieldsForSearch();
return tools.executeQueryTable(this, 0, params);
};
const SectorActivities = mongoose.model('SectorActivities', SectorActivitiesSchema);
SectorActivities.createIndexes((err) => {
if (err) throw err;
});
module.exports = { SectorActivities };

View File

@@ -672,6 +672,16 @@ UserSchema.statics.isManagerById = async function (id) {
}
};
UserSchema.statics.isAdminById = async function (id) {
try {
const ris = await User.findOne({ _id: id }, { perm: 1 }).lean();
return ((ris.perm & shared_consts.Permissions.Admin) ===
shared_consts.Permissions.Admin);
} catch (e) {
return false;
}
};
UserSchema.statics.isEditor = function (perm) {
try {
return ((perm & shared_consts.Permissions.Editor) ===
@@ -3237,7 +3247,7 @@ UserSchema.statics.setCircuitCmd = async function (idapp, usernameOrig, circuitn
}
ris = true;
// } else if ((cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT) || (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE)) {
// } else if ((cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT) || (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE)) {
// Before to accept, I see if it's already set !
/*outres = {
@@ -5742,10 +5752,10 @@ UserSchema.statics.tooManyLoginWrong = async function (idapp, username, set) {
await User.findOneAndUpdate({ _id: user._id }, { $set: { retry_pwd: user.retry_pwd } });
}
return {troppilogin: user.retry_pwd > maxnum, retry_pwd: user.retry_pwd};
return { troppilogin: user.retry_pwd > maxnum, retry_pwd: user.retry_pwd };
}
return {troppilogin: false, retry_pwd: 0};
return { troppilogin: false, retry_pwd: 0 };
};
UserSchema.statics.setLastCircuitOpened = async function (idapp, username, circuitpath) {

View File

@@ -1,66 +1,90 @@
const axios = require('axios');
const apiUrl = 'https://api.cloudflare.com/client/v4'; // Endpoint
async function fetchCloudflareZones(apiToken) {
try {
class CloudFlare {
constructor(config) {
this.config = config ? config : {};
// 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
}
});
if (!this.config.arrTokens) {
this.config.arrTokens = process.env.CLOUDFLARE_TOKENS;
}
}
// Estrai i dati dalla risposta
const zones = response.data.result;
init() {
if (this.config.arrTokens) {
// this.zones = this.fetchCloudflareZones(this.config.apiToken);
this.zones = [];
this.dnsRecords = null;
}
}
// Stampa le zone
// console.log('Zone di Cloudflare:', zones);
} catch (error) {
console.error('Errore durante il recupero delle zone di Cloudflare:', error.message);
async 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
this.zones = response.data.result;
return this.zones;
// 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 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
}
});
this.dnsRecords = response.data.result;
return this.dnsRecords;
} catch (error) {
console.error('Errore durante il recupero dei record DNS di Cloudflare:', error.message);
}
}
// Funzione per aggiornare un record DNS
async 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);
return updatedRecord;
} catch (error) {
console.error('Errore durante l\'aggiornamento del record DNS:', 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);
}
}
module.exports = CloudFlare

View File

@@ -1193,4 +1193,47 @@ router.post('/exec', authenticate, async (req, res) => {
});
router.post('/cloudflare', authenticate, async (req, res) => {
try {
idapp = req.body.idapp;
cmd = req.body.cmd;
tok = req.body.tok;
zoneId = req.body.zoneId;
tokcheck = req.body.tokcheck;
dnsRecordId = req.body.dnsRecordId;
record = req.body.record;
console.log('/cloudflare idapp=', idapp, req.body.script);
const CloudFlareClass = require('../modules/Cloudflare.js');
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 = '';
let cf = new CloudFlareClass(null);
cf.init();
if (cmd === "getzones") {
result = await cf.fetchCloudflareZones(tok);
} else if (cmd === "getDNS") {
result = await cf.fetchDNSRecords(tok, zoneId);
} else if (cmd === "setRecordDNS") {
result = await cf.updateDNSRecord(tok, zoneId, dnsRecordId, record);
} else if (cmd === "gettok") {
result = JSON.parse(process.env.CLOUDFLARE_TOKENS);
}
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;

View File

@@ -662,7 +662,7 @@ router.post('/gettable', authenticate, (req, res) => {
let params = req.body;
params.table = sanitizeHtml(params.table);
let idapp = req.user ? req.user.idapp : sanitizeHtml(params.idapp);
const mytable = globalTables.getTableByTableName(params.table);
//console.log('mytable', mytable);
@@ -1402,7 +1402,7 @@ router.get('/loadsite/:userId/:idapp/:vers', authenticate_noerror,
});
function load(req, res, version) {
const userId = req.params.userId;
const idapp = req.params.idapp;
@@ -1410,7 +1410,7 @@ function load(req, res, version) {
if (req.code === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
status = server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED
}
if (!version) {
version = '0';
@@ -1890,9 +1890,10 @@ function uploadFile(req, res, version) {
// console.log('fromfile', fromfile)
// console.log('tofile', tofile);
if (!tools.sulServer()) {
console.log('Dovresti copiare fromfile', fromfile, 'tofile', tofile);
console.log('cp ', fromfile, tofile);
await tools.execScriptNoOutput('sudo cp -R ' + fromfile + ' ' + tofile)
res.end();
return;
}

View File

@@ -17,8 +17,6 @@ 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;
@@ -283,6 +281,9 @@ async function mystart() {
// await estraiTutteLeImmagini();
console.log('Versione Server: ' + await tools.getVersServer());
await tools.getApps();
if (process.env.PROD !== 1) {
@@ -716,11 +717,6 @@ async function faitest() {
}
}
/*const domains = [
{ hostname: 'piuchebuono.app', port: 3000 },
{ hostname: 'gruppomacro.app', port: 3010 },
];*/
function getCredentials(hostname) {
if (NUOVO_METODO_TEST) {
@@ -801,6 +797,8 @@ function startServer(app, port) {
let httpsServer = null;
let httpServer = null;
console.log('isProduction', isProduction);
if (isProduction) {
for (let i = 0; i < domains.length; i++) {
const credentials = getCredentials(domains[i].hostname);
@@ -859,82 +857,98 @@ function startServer(app, port) {
// process.exit(1);
}
wss.on('connection', (ws) => {
// console.log('Client connected');
let scriptProcess = null;
if (wss) {
ws.on('message', (message) => {
const parsedMessage = JSON.parse(message);
wss.on('connection', (ws) => {
console.log('Client socket connected...');
if (parsedMessage.type === 'start_script') {
if (scriptProcess) {
scriptProcess.kill();
}
const { User } = require('./models/user');
const scriptPath = path.join(__dirname, '..', '..', '', parsedMessage.scriptName);
let scriptProcess = null;
// 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
});
try {
let buffer = '';
scriptProcess.on('data', (data) => {
buffer += data;
const pty = require('node-pty');
// Invia l'output al client
ws.send(JSON.stringify({ type: 'output', data: data }));
ws.on('message', (message) => {
const parsedMessage = JSON.parse(message);
// 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 = '';
if ((parsedMessage.type === 'start_script') && (User.isAdminById(parsedMessage.user_id))) {
if (scriptProcess) {
scriptProcess.kill();
}
// Pulisci il buffer se diventa troppo grande
if (buffer.length > 5024) {
buffer = buffer.slice(-500);
}
});
const scriptPath = path.join(__dirname, '..', '..', '', parsedMessage.scriptName);
scriptProcess.on('exit', (code) => {
if (code === 0) {
ws.send(JSON.stringify({ type: 'close', data: `*** FINE SCRIPT ***` }));
// 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: 'close', data: `Script terminato con codice ${code}` }));
ws.send(JSON.stringify({ type: 'error', data: 'Script non trovato o non autorizzato' }));
}
});
} 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');
}
} else if (parsedMessage.type === 'input') {
if (scriptProcess) {
scriptProcess.write(parsedMessage.data + '\n');
}
}
});
ws.on('close', () => {
console.log('*** Client socket disconnected');
if (scriptProcess) {
scriptProcess.kill();
}
});
} catch (error) {
console.error('connection: Errore durante l\'inizializzazione del WebSocket, error:', error.message);
}
});
ws.on('close', () => {
console.log('Client disconnected');
if (scriptProcess) {
scriptProcess.kill();
}
});
});
} else {
console.error('Nessuna Socket Aperta con WebSocket !!');
}
} catch (e) {
console.log('error ' + e);
console.log('error startServer: ' + e);
}
}

View File

@@ -2486,8 +2486,13 @@ class Telegram {
file = '~/batch/test_restart_server.sh';
}
const ris = await tools.execScriptByTelegram(this.idapp, msg, file,
this.chisono(rec) + ' Restart il Server (Node.Js) : ' + process.version);
let messaggio = this.chisono(rec) + ' Restart il Server (Node.Js) : ' + process.version;
messaggio += '\nVersione Server: ' + await tools.getVersServer();
const ris = await tools.execScriptByTelegram(this.idapp, msg, file, messaggio);
} else {
this.nonAbilitato(msg);
}

View File

@@ -1861,9 +1861,9 @@ module.exports = {
this.MYAPPS.find(item => item.idapp === idapp);
if (myapp) {
if (process.env.NODE_ENV === 'test')
mypath = (myapp) ? myapp.dir_test : '';
mypath = (myapp && myapp.dir_test) ? myapp.dir_test : '';
else
mypath = (myapp) ? myapp.dir : '';
mypath = (myapp && myapp.dir) ? myapp.dir : '';
if (dirmain) {
if (!this.sulServer()) {
@@ -3812,15 +3812,30 @@ module.exports = {
},
readlogfile(idapp, filename) {
async readlogfile(idapp, filename) {
try {
return fs.readFileSync(idapp + '/' + filename, 'utf8');
return await fs.readFileSync(idapp + '/' + filename, 'utf8');
} catch (e) {
return '';
}
},
async readfilecontent(filename) {
try {
const cont = await fs.readFileSync(filename, 'utf8');
return cont;
} catch (e) {
return '';
}
},
async getVersServer() {
return await this.readfilecontent(__dirname + '/../version.txt');
},
writelog(mystr) {
this.writelogfile(mystr, FILELOG);
},
@@ -3852,11 +3867,6 @@ module.exports = {
this.writelogfile(mystr, idapp + '/' + riga + '_' + col + '.txt');
},
readFlottaLog(idapp, riga, col) {
const nomefile = riga + '_' + col + '.txt';
return this.readlogfile(idapp, nomefile);
},
writeNaveLog(mystr) {
this.writelogfile(mystr, FILENAVE);
},
@@ -4507,6 +4517,7 @@ module.exports = {
for (let i = 0; i < arrscripts.length; i++) {
let label = arrscripts[i];
let sock = false;
let description = '';
if (listafiles) {
if (arrscripts[i].endsWith('.sh')) {
@@ -4537,6 +4548,8 @@ module.exports = {
label = value;
} else if (paramstr === 'DESCRIZ') {
description = value;
} else if (paramstr === 'SOCK') {
sock = (value.toLowerCase() === 'true');
}
}
@@ -4551,7 +4564,7 @@ module.exports = {
}
if ((label) && (!extfiles || (extfiles && arrscripts[i].endsWith('.' + extfiles)))) {
arrout.push({ label, value: arrscripts[i], description });
arrout.push({ label, value: arrscripts[i], description, sock });
}
}
@@ -4559,6 +4572,20 @@ module.exports = {
});
});
},
execScriptNoOutput: async function (script) {
return new Promise(async (resolve, reject) => {
console.log('execScriptNoOutput:', script);
exec(script, async (error, stdout, stderr) => { // Aggiunto async qui
if (error) {
console.error(`error: ${error}`);
}
if (stderr) {
console.error(`stderr: ${stderr}`);
}
resolve(!error && !stderr);
});
});
},
execScriptWithInputOnServer: async function (idapp, script) {
return new Promise((resolve, reject) => {

1
src/server/version.txt Normal file
View File

@@ -0,0 +1 @@
1.0.56