Files
freeplanet_serverside/src/server/tools/general.js
Surya Paolo 5668c620da - Sistemato link pdf che ogni volta che si aggiorna prendeva il PDF dalla cache...
- Raccolta Cataloghi, procedura che li AUTO genera in automatico.
2025-06-13 17:46:03 +02:00

6216 lines
189 KiB
JavaScript
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const os = require('os');
const fs = require('fs-extra'); // 👈 Usa il modulo promises
const xml2js = require('xml2js');
const path = require('path');
const WebSocket = require('ws');
require('../config/config');
require('../models/subscribers');
const ImageDownloader = require('../modules/ImageDownloader');
const printf = require('util').format;
const { JSDOM } = require('jsdom');
const axios = require('axios');
const CryptoJS = require('crypto-js');
const Url = require('url-parse');
const { ObjectId } = require('mongodb');
const shared_consts = require('./shared_nodejs');
const mongoose = require('mongoose').set('debug', false);
const server_constants = require('./server_constants');
// SETTINGS WebPush Configuration
const webpush = require('web-push');
const i18n = require('i18n');
const FILELOG = 'filelog.txt';
const FILEEVENTS = 'logevents.txt';
const FILEMANAGERS = 'logmanagers.txt';
const FILETRANSACTION = 'logtrans.txt';
const FILEERRLOGIN = 'errlogin.txt';
const FILESOSTITUZIONI = 'log_sostituzioni.txt';
const FILEIP_TO_BAN = 'log_iptoban.txt';
const FILENAVE = 'logNave.txt';
const subject = process.env.VAPI_KEY_SUBJECT;
const publicVapidKey = process.env.PUBLIC_VAPI_KEY;
const privateVapidKey = process.env.PRIVATE_VAPI_KEY;
const FIELDS_REGEX = ['username', 'name', 'surname'];
const sanitizeHtml = require('sanitize-html');
const { exec } = require('child_process');
const util = require('util');
const execPromise = util.promisify(exec);
const { spawn } = require('child_process');
const readline = require('readline');
// Code goes here
const keySize = 256;
// const ivSize = 128;
const iterations = 1000;
if (!!process.env.GCM_API_KEY && process.env.GCM_API_KEY !== '') {
webpush.setGCMAPIKey(process.env.GCM_API_KEY);
webpush.setVapidDetails(subject, publicVapidKey, privateVapidKey);
}
// console.log('setVapidDetails... config...');
// To Translate!
const textlang = {
it: {
"L'Email è già stata Verificata": "L'Email è già stata Verificata",
'Nuova Registrazione': 'Nuova Registrazione',
'Effettuata una Nuova Registrazione': 'Effettuata una Nuova Registrazione',
partecipanti: "partecipanti all'Evento",
'partecipanti a Pranzo': 'partecipanti a Pranzo',
'partecipanti a Cena': 'partecipanti a Cena',
'partecipanti a Cena Condivisa': 'partecipanti a Cena Condivisa',
TESTO_ASSISTENZA:
'<strong><a href="%s">👉 Per entrare nel Sito</a></strong>\n\n' +
'👉 <strong><a href="https://freeplanet.app/requestresetpwd">Hai dimenticato la password?</a></strong>\n\n',
BENVENUTO: 'Benvenut@',
TUE_NAVI: 'Ecco le tue Navi programmate',
HAI_I_7_REQUISITI: 'PRIMI PASSI OK!\nHai i Primi Requisiti per Entrare nella Lista !',
NON_HAI_I_7_REQUISITI: 'Attenzione!\nAncora non hai i 7 Requisiti per Entrare nella Lista !',
INFO_LA_MIA_LAVAGNA: '✨ Lista dei Passi: ✨ \n',
INFO_LAVAGNA_SITO_COMPLETARE:
'Per completare tutti i requisiti vai sul sito:\n%s\n👉🏻 <a href="%s">Entra nella tua Lavagna</a>.\n',
INFO_LAVAGNA_SITO:
'Per vedere in dettaglio lo <strong>STATO</strong>, sul sito \n 👉🏻 <a href="%s">Entra nella tua Lavagna</a>.\n',
INFO_LINK_DA_CONDIVIDERE: 'Link da condividere ai tuoi invitati per farli registrare al sito:\n\n%s',
INFO_LINK_ZOOM: 'Link da condividere per partecipare allo Zoom (Conferenza OnLine):\n%s',
ZOOM_CONFERENCE: 'Ecco il programma delle Conferenze (Zoom) aperti a TUTTI:',
NON_VERIF: 'Non Verificata',
VERIF: 'Verificata',
EMAIL: 'Email',
BOT: 'BOT',
EMAIL_NON_VERIF:
'Email Non Verificata\nleggi la tua casella email e trova **"Confermare la Registrazione"**\ne clicca sul bottone **"Verifica Registrazione"**',
TELEGRAM_NOT_CONNECTED: 'Telegram non associato al tuo account!',
NESSUN_INVITATO: 'Non hai invitato nessuno',
ZOOM_PARTECIPATO: 'Partecipazione ad almeno 1 Conferenza (Zoom)',
LINEE_GUIDA: 'Accettato le Linee Guida',
VIDEO_INTRO: 'Visto il Video',
SCRITTO_SOGNO: 'Hai scritto il tuo Sogno',
PAYMENTS: 'Modalità di Pagamento',
INVITATI: 'persone registrate che hai invitato',
INVITATI_ATTIVI: 'Invitati con i 7 Requisiti',
NONREG: 'Invitati non Registrati',
CLICCA_PER_ZOOM: 'AL GIORNO E ORA INDICATA, PER ENTRARE NELLA VIDEO-CONFERENZA, CLICCA SUL LINK INDICATO',
CLICCA_ENTRA: 'CLICCA QUI PER ENTRARE !',
ZOOM_INIZIATO: "QUESTA CONFERENZA E' INIZIATA!",
SCEGLI_VOCE: 'scegli una voce:',
INVITATI_LISTA: 'I Tuoi Invitati (in verde con almeno i primi 7 Requisiti)',
CIAO: 'Ciao',
ADDED_TOLISTAINGRESSO:
"<strong>Complimenti! 🎊</strong>\nSei stato aggiunto alla <strong>Lista D'Imbarco</strong> !\nNei prossimi giorni riceverai un messaggio qui quando la tua Nave sarà pronta a partire.\nRicorda che per salire di graduatoria, puoi condividere il Movimento con i tuoi amici ❤️.",
REGALATO_INVITANTE: 'da fare.... 😍🎊 Hai ricevuto in Regalo un Invitato {invitato} da parte di {mittente} !',
NO_PROG: "Attualmente non sei ancora dentro alla Lista d'Imbarco!",
SEND_LINK_CHAT_DONATORI:
'Ciao %s!\nLa tua NAVE sta finalmente Salpando!\nEntra nella Gift Chat della nave {%s} cliccando qui: %s',
SEND_LINK_CHAT_SOGNATORE:
'Ciao %s!\nOggi Diventi Sognatore !!! 🎊🎊🎊 Entra nella Gift Chat della nave {%s} cliccando qui: %s',
ENTRA_GIFT_CHAT: 'Entra nella Gift Chat',
DATA_PART_NAVE: 'data di Partenza della Nave:',
SOGNATORE: 'SOGNATORE',
INTERMEDIO: 'Intermedio',
MEDIATORE: 'MEDIATORE',
DONATORI: 'DONATORI',
RITESSITURA: 'RITESSITURA',
'NAVE COMPLETATA': 'NAVE COMPLETATA',
'Doni Effettuati': 'Doni Effettuati',
'Facilitatore che affianchèra il Mediatore': 'Facilitatore che affianchèra il Mediatore',
APERTURA_CHIUSURA_GIFT_CHAT:
"%s: Apertura GIFT CHAT\n%s Chiusura GIFT CHAT\nNota Bene: Hai tempo 3 giorni dall'apertura per entrare in Chat ed effettuare il tuo Dono, dopodichè effettueremo la sostituzione.",
'Giorno di Apertura GIFT CHAT': 'Giorno di Apertura GIFT CHAT',
'Giorno in cui Inviare il DONO': 'Hai 3 giorni di tempo per inviare il tuo dono.\nGiorno di Chiusura',
SPOSTATO: 'Sei stato Spostato in una Nuova Nave !',
Note: 'Note',
TEMPORANEA: 'TEMPORANEA',
NAVE: 'NAVE',
MSG_SEND_FROM: 'Msg Inviato da',
ZOOM_CONFERMATO: 'Sei stato confermato ad aver visto la Video Conferenza di Benvenuto!',
RICHIESTA_AMICIZIA: "🌈 Richiesta d'Amicizia da parte di %s",
RICHIESTA_HANDSHAKE: '🌈 %s ha comunicato che ti conosce personalmente e ha fiducia in te.',
ACCETTATO_SUL_GRUPPO: '✅ Sei stato accettato da %s a far parte del Gruppo %s',
CREATO_NUOVO_GRUPPO: '✅ Hai appena creato un nuovo Gruppo chiamato %s',
ACCETTATO_NOTIFICA_ADMINS: "✅ l'utente %s è stato accettato a far parte del Gruppo %s (da parte di %s)",
GROUP_REQUEST: 'Richiesta di entrare nel Gruppo %s da parte di %s',
CLICCA_QUI: 'CLICCA QUI',
TELEFONO: 'Tel',
},
si: {},
es: {
"L'Email è già stata Verificata": 'El correo electrónico ya ha sido verificado',
'Nuova Registrazione': 'Nuevo Registro',
'Effettuata una Nuova Registrazione': 'Se ha realizado un nuevo registro',
partecipanti: 'participantes',
'partecipanti a Pranzo': 'partecipanti a Pranzo',
'partecipanti a Cena': 'partecipanti a Cena',
TESTO_ASSISTENZA:
'Para entrar en el sitio:\n%s\n\n' +
'¿Olvidó su contraseña para acceder al sitio?\nhttps://freeplanet.app/requestresetpwd\n\n',
BENVENUTO: 'Bienvenido',
TUE_NAVI: 'Aquí están sus naves programadas',
HAI_I_7_REQUISITI:
'¡LOS PRIMEROS PASOS ESTÁN BIEN!\nTiene los primeros 7 requisitos para entrar en la lista de embarque!',
NON_HAI_I_7_REQUISITI: '¡Atención!\nTodavía no tienes los 7 requisitos para entrar en la lista de embarque!',
HAI_I_9_REQUISITI: '¡FELICITACIONES!\n¡Has completado los 9 pasos de la Guía! Gracias por ayudar a expandirse!',
NON_HAI_I_9_REQUISITI:
'Recuerda que puedes ayudar a que el Movimiento crezca y se expanda compartiendo nuestro viaje con todos.!',
INFO_LA_MIA_LAVAGNA: '✨ Lista de pasos: ✨ \n',
INFO_LAVAGNA_SITO_COMPLETARE:
'Para completar todos los requisitos vaya al sitio:\n%s\nPara ver el estado de su nave y sus invitados,👉🏻 <a href="%s">Pizarra</a>.\n',
INFO_LAVAGNA_SITO:
'Para ver en detalle el estado de su nave, en el sitio web, haga clic en las 3 líneas de la parte superior izquierda y vaya a "Pizarra"..\n',
INFO_LINK_DA_CONDIVIDERE: 'Enlaces para compartir con sus invitados para que se registren en el sitio web:\n\n%s',
INFO_LINK_ZOOM: 'Enlaces para compartir para participar en el Zoom (Conferencia en línea):\n%s',
ZOOM_CONFERENCE: 'Aquí puedes encontrar las fechas de programación en el Zoom:',
NON_VERIF: 'No verificado',
VERIF: 'Verificado',
EMAIL: 'Email',
BOT: 'BOT',
EMAIL_NON_VERIF:
'Correo electrónico no verificado\nlea su buzón y encuentre **"Confirmar Registro "** <marca>y haga clic en el botón **"Verificar Registro "**.',
TELEGRAM_NOT_CONNECTED: 'Telegram no asociado a su cuenta!',
NESSUN_INVITATO: 'No invitaste a nadie',
ZOOM_PARTECIPATO: 'Participación en al menos 1 Conferencia (Zoom)',
LINEE_GUIDA: 'Directrices aceptadas',
VIDEO_INTRO: 'Ver el video',
SCRITTO_SOGNO: 'Escribiste tu sueño',
PAYMENTS: 'Métodos de pago',
INVITATI: 'las personas registradas que usted invitó',
INVITATI_ATTIVI: 'Invitado con los 7 requisitos',
NONREG: 'Invitados no registrados',
CLICCA_PER_ZOOM: 'AL DÍA Y HORA INDICADOS, PARA ENTRAR EN LA VIDEOCONFERENCIA, PULSE AQUÍ',
CLICCA_ENTRA: 'HAGA CLIC AQUÍ PARA ENTRAR !',
ZOOM_INIZIATO: 'ESTA CONFERENCIA HA COMENZADO!',
SCEGLI_VOCE: 'elegir una voz:',
INVITATI_LISTA: 'Sus invitados (en verde con al menos los 7 primeros requisitos)',
CIAO: 'Hola',
ADDED_TOLISTAINGRESSO: 'Has sido añadido a la lista de personas que entrarán en Lista de embarque!',
NO_PROG: 'Actualmente no está en la lista de embarque.!',
SEND_LINK_CHAT_DONATORI:
'Hola %s!\n¡Tu barco por fin está navegando!\nEntra en el Gift Chat haciendo clic aquí: %s',
SEND_LINK_CHAT_SOGNATORE:
'¡Hola!\n¡Hoy te conviertes en un soñador! 🎊🎊🎊 Entre en el Chat de Regalos de la nave {%s} haciendo clic aquí: %s',
ENTRA_GIFT_CHAT: 'Entre en el Chat de Regalos',
DATA_PART_NAVE: 'fecha de salida de la nave:',
SOGNATORE: 'SOÑADOR',
INTERMEDIO: 'Intermedio',
MEDIATORE: 'MEDIATOR',
DONATORI: 'DONANTES',
RITESSITURA: 'RETEJIDO',
'NAVE COMPLETATA': 'NAVE COMPLETADA',
'Doni Effettuati': 'Regalos Realizados',
'Facilitatore che affianchèra il Mediatore': 'Facilitatore de apoyo al Donante',
APERTURA_CHIUSURA_GIFT_CHAT:
'%s: Apertura del CHAT DE REGALOS\n%s Cierre del CHAT DE REGALOS\nNota: Tienes 3 días desde la apertura para entrar en el Chat y hacer tu Regalo, después de lo cual haremos el reemplazo',
SPOSTATO: 'Has sido trasladado a una nueva nave !',
Note: 'Notas',
TEMPORANEA: 'TEMPORAL',
NAVE: 'NAVE',
MSG_SEND_FROM: 'Mensaje enviado por',
ZOOM_CONFERMATO: '¡Se ha confirmado que ha visto la Video Conferencia de Bienvenida!',
RICHIESTA_AMICIZIA: "Richiesta d'Amicizia da parte di %s",
ACCETTATO_SUL_GRUPPO: 'Sei stato accettato da %s a far parte del Gruppo %s',
ACCETTATO_NOTIFICA_ADMINS: "l'utente %s è stato accettato a far parte del Gruppo %s (da parte di %s)",
RICHIESTA_BLOCCO_GRUPPO: 'Richiesta di bloccare il Gruppo %s da parte di %s',
},
enUs: {
partecipanti: 'participants',
'partecipanti a Pranzo': 'partecipanti a Pranzo',
'partecipanti a Cena': 'partecipanti a Cena',
TESTO_ASSISTENZA:
'To enter the Site:\n%s\n\nForgot your password to access the site?\n' +
'https://freeplanet.app/requestresetpwd\nChat AYNI BOT (this one):\nhttps://t.me/notevoleaynibot\n\n',
BENVENUTO: 'Welcome',
TUE_NAVI: 'Here are your programmed ships',
HAI_I_7_REQUISITI: 'FIRST STEPS OK!\nYou have the First 7 Requirements to Enter the Boarding List!',
NON_HAI_I_7_REQUISITI: 'Attention!\nYou still do not have the 7 requirements to enter the boarding list!',
INFO_LA_MIA_LAVAGNA: '✨ Step List: ✨ \n',
INFO_LAVAGNA_SITO_COMPLETARE:
'To complete all the requirements go to the site:%s\nTo see the status of your Ship and your guests\n👉🏻 <a href="%s">Dashboard</a>\n',
INFO_LAVAGNA_SITO:
'To see in detail the status of your ship, on the website, click on the 3 lines at the top left and go to "Blackboard".\n',
INFO_LINK_DA_CONDIVIDERE: 'Links to share with your guests to have them register on website:\n\n%s',
INFO_LINK_ZOOM: 'Links to share to participate in Zoom (Online Conference):\n%s',
ZOOM_CONFERENCE: 'Here you can find the Zoom Conference Planning:',
NON_VERIF: 'Not Verified',
VERIF: 'Verified',
EMAIL: 'Email',
BOT: 'BOT',
EMAIL_NON_VERIF:
'Email Not Verified\nread your mailbox and find **"Confirm Registration "**<br>and click on the button **"Verify Registration "**.',
TELEGRAM_NOT_CONNECTED: 'Telegram not associated with your account!',
NESSUN_INVITATO: "You didn't invite anyone",
ZOOM_PARTECIPATO: 'Participation in at least 1 Conference (Zoom)',
LINEE_GUIDA: 'Guidelines Accepted',
VIDEO_INTRO: 'Seen the Video',
SCRITTO_SOGNO: 'You wrote your Dream',
PAYMENTS: 'Methods of Payment',
INVITATI: 'registered people you invited',
INVITATI_ATTIVI: 'Guests with the 7 Requirements',
NONREG: 'Non-registered Guests',
CLICCA_PER_ZOOM: 'TO THE DAY AND TIME INDICATED, TO ENTER THE VIDEO-CONFERENCE, CLICK HERE',
CLICCA_ENTRA: 'CLICK HERE TO ENTER !',
ZOOM_INIZIATO: 'THIS CONFERENCE HAS BEGUN!',
SCEGLI_VOCE: 'choose a menu item:',
INVITATI_LISTA: 'Your Guests (in green with at least the first 7 requirements)',
CIAO: 'Hi',
ADDED_TOLISTAINGRESSO: 'You have been added to the List of people who will enter the Boarding List!',
NO_PROG: 'You are not currently on the boarding list.!',
SEND_LINK_CHAT_DONATORI: 'Hi %s!\nYour ship is finally sailing!\nEnter the Gift Chat by clicking here: %s',
SEND_LINK_CHAT_SOGNATORE:
"Hello %s!\nToday you become a Dreamer! 🎊🎊🎊 Enter the ship's Gift Chat {%s} by clicking here: %s",
ENTRA_GIFT_CHAT: "Enter the ship's Gift Chat",
DATA_PART_NAVE: 'date of departure of the ship:',
SOGNATORE: 'DREAMER',
INTERMEDIO: 'Intermediate',
MEDIATORE: 'MEDIATOR',
DONATORI: 'DONOR',
RITESSITURA: 'RE-ENTER',
'NAVE COMPLETATA': 'SHIP COMPLETED',
'Doni Effettuati': 'Gifts Made',
'Facilitatore che affianchèra il Mediatore': 'Facilitatore supporting the Mediator',
APERTURA_CHIUSURA_GIFT_CHAT:
'%s: Opening GIFT CHAT\n%s Closing GIFT CHAT\nNote: You have 3 days from the opening to enter the Chat and make your Gift, after which we will make the replacement.',
SPOSTATO: "You've been moved to a New Ship !",
Note: 'Note',
TEMPORANEA: 'TEMPORARY',
NAVE: 'SHIP',
MSG_SEND_FROM: 'Msg sent by',
ZOOM_CONFERMATO: 'You have been confirmed to have seen the Welcome Video Conference!',
RICHIESTA_AMICIZIA: "Richiesta d'Amicizia da parte di %s",
ACCETTATO_SUL_GRUPPO: 'Sei stato accettato da %s a far parte del Gruppo %s',
ACCETTATO_NOTIFICA_ADMINS: "l'utente %s è stato accettato a far parte del Gruppo %s (da parte di %s)",
RICHIESTA_BLOCCO_GRUPPO: 'Richiesta di bloccare il Gruppo %s da parte di %s',
},
fr: {
"L'Email è già stata Verificata": 'Le courrier électronique a déjà été vérifié',
'Nuova Registrazione': 'Nouvelle inscription',
'Effettuata una Nuova Registrazione': 'Un nouvel enregistrement a été effectué',
partecipanti: 'participants',
'partecipanti a Pranzo': 'partecipanti a Pranzo',
'partecipanti a Cena': 'partecipanti a Cena',
TESTO_ASSISTENZA:
'Pour entrer sur le site:\n%s\n\n' +
'Vous avez oublié votre mot de passe pour accéder au site ?\nhttps://ayni.gifteconomy.app/requestresetpwd\n\n',
BENVENUTO: 'Bienvenue',
TUE_NAVI: 'Voici vos navires programmés',
HAI_I_7_REQUISITI:
"PREMIÈRES ÉTAPES OK!\nvous avez les 7 premiers Requis pour Entrer dans la liste d'embarquement!",
NON_HAI_I_7_REQUISITI:
"'Attention!\nVous ne remplissez pas encore les 7 conditions pour figurer sur la liste d'embarquement!",
HAI_I_9_REQUISITI:
"FÉLICITATIONS!\n!Vous avez franchi les 9 étapes de la conduite ! Merci d'avoir aidé à se développer!",
NON_HAI_I_9_REQUISITI:
"N'oubliez pas que vous pouvez aider le Mouvement à grandir et à se développer en partageant notre voyage avec tout le monde.!",
INFO_LA_MIA_LAVAGNA: '✨ Liste des étapes: ✨ \n',
INFO_LAVAGNA_SITO_COMPLETARE:
'Pour remplir toutes les conditions, rendez-vous sur le site:\n%s\nPour voir le statut de votre navire et de vos invités\n 👉🏻 <a href="%s">Tableau</a>.\n',
INFO_LAVAGNA_SITO:
'Pour voir en détail le statut de votre navire, sur le site, cliquez sur les 3 lignes en haut à gauche et allez sur "Tableau".\n',
INFO_LINK_DA_CONDIVIDERE: "Liens à partager avec vos invités pour qu'ils s'inscrivent sur le site web:\n\n%s",
INFO_LINK_ZOOM: 'Liens à partager pour participer à Zoom (Conférence en ligne):\n%s',
ZOOM_CONFERENCE: 'Vous trouverez ici les dates de programmation sur Zoom:',
NON_VERIF: 'Non vérifié',
VERIF: 'Vérifié',
EMAIL: 'Courriel',
BOT: 'BOT',
EMAIL_NON_VERIF:
'Courriel non vérifié\nlisez votre boîte aux lettres et trouvez **"Confirmer l\'inscription "**<br>et cliquez sur le bouton **"Vérifier l\'inscription "**.',
TELEGRAM_NOT_CONNECTED: 'Télégramme non associé à votre compte!',
NESSUN_INVITATO: "Vous n'avez invité personne",
ZOOM_PARTECIPATO: 'Participation à au moins 1 conférence (Zoom)',
LINEE_GUIDA: 'Lignes directrices acceptées',
VIDEO_INTRO: 'Voir la vidéo',
SCRITTO_SOGNO: 'Vous avez écrit votre rêve',
PAYMENTS: 'Modes de paiement',
INVITATI: 'personnes inscrites que vous avez invitées',
INVITATI_ATTIVI: 'Invité avec les 7 exigences',
NONREG: 'Invités non enregistrés',
CLICCA_PER_ZOOM: "AU JOUR ET À L'HEURE INDIQUÉS, POUR ENTRER DANS LA VIDÉOCONFÉRENCE, CLIQUEZ ICI",
CLICCA_ENTRA: 'CLIQUEZ ICI POUR ENTRER !',
ZOOM_INIZIATO: 'CETTE CONFÉRENCE A COMMENCÉ!',
SCEGLI_VOCE: 'choisir une voix:',
INVITATI_LISTA: 'Vos invités (en vert avec au moins les 7 premières exigences)',
CIAO: 'Salut',
ADDED_TOLISTAINGRESSO: "Vous avez été ajouté à la liste d'embarquement !",
NO_PROG: "Vous n'êtes pas encore sur la liste d'embarquement.!",
SEND_LINK_CHAT_DONATORI:
'Salut %s!\nVotre SHIP prend enfin la mer.!\nEntrez dans le Chat Cadeau en cliquant ici: %s',
SEND_LINK_CHAT_SOGNATORE:
"Bonjour %s !\nAujourd'hui, vous devenez un Rêveur ! 🎊🎊🎊 Entrez dans le chat des cadeaux du navire {%s} en cliquant ici : %s",
ENTRA_GIFT_CHAT: 'Entrez dans le chat des cadeaux',
DATA_PART_NAVE: 'la date de départ du navire:',
SOGNATORE: 'Rêveur',
INTERMEDIO: 'Intermediaire',
MEDIATORE: 'Médiateur',
DONATORI: 'DONATEUR',
RITESSITURA: 'RETESSITURA',
'NAVE COMPLETATA': 'NAVIRE COMPLÉTÉ',
'Doni Effettuati': 'Don effectués',
'Facilitatore che affianchèra il Mediatore': 'Le tuteur qui soutient le Mediateur',
APERTURA_CHIUSURA_GIFT_CHAT:
"%s : Chat d'ouverture\n%s Clôture du GIFT CHAT\nNote: Vous avez 3 jours à partir de l'ouverture pour entrer dans le Chat et faire votre Cadeau, après quoi nous ferons le remplacement",
SPOSTATO: 'Vous avez été transféré sur un nouveau navire !',
Note: 'Notes',
TEMPORANEA: 'TEMPORAIRE',
NAVE: 'NAVIRE',
MSG_SEND_FROM: 'Message envoyé par',
ZOOM_CONFERMATO: 'Vous avez été confirmé comme ayant vu la vidéoconférence de bienvenue !',
RICHIESTA_AMICIZIA: "Richiesta d'Amicizia da parte di %s",
ACCETTATO_SUL_GRUPPO: 'Sei stato accettato da %s a far parte del Gruppo %s',
ACCETTATO_NOTIFICA_ADMINS: "l'utente %s è stato accettato a far parte del Gruppo %s (da parte di %s)",
RICHIESTA_BLOCCO_GRUPPO: 'Richiesta di bloccare il Gruppo %s da parte di %s',
},
pt: {
"L'Email è già stata Verificata": '',
'Nuova Registrazione': 'Novo Registo',
'Effettuata una Nuova Registrazione': 'Foi efectuado um novo registo',
partecipanti: 'participantes',
'partecipanti a Pranzo': 'partecipanti a Pranzo',
'partecipanti a Cena': 'partecipanti a Cena',
TESTO_ASSISTENZA:
'Para entrar no site:\n%s\n\n' +
'Esqueceu sua senha para acessar o site?\nhttps://freeplanet.app/requestresetpwd\n\n',
BENVENUTO: 'Bem-vindo',
TUE_NAVI: 'Aqui estão os seus navios programados',
HAI_I_7_REQUISITI: 'PRIMEIROS PASSOS OK!\nVocê tem os 7 primeiros requisitos para entrar na lista de embarque!',
NON_HAI_I_7_REQUISITI: 'Atenção!\nVocê ainda não tem os 7 requisitos para entrar na lista de embarque!',
INFO_LA_MIA_LAVAGNA: '✨ Lista de etapas: ✨ \n',
INFO_LAVAGNA_SITO_COMPLETARE:
'Para completar todos os requisitos ir para o sitio:\n%s\nPara ver o estado do seu navio e dos seus convidados:\n 👉🏻 <a href="%s">Entre no seu Tablero</a>.\n',
INFO_LAVAGNA_SITO:
'Para ver em detalhe o estado do seu navio, no site, clique nas 3 linhas no canto superior esquerdo e vá para "DashBoard"..\n',
INFO_LINK_DA_CONDIVIDERE: 'Links para partilhar com os seus convidados para que se registem no website:\n\n%s',
INFO_LINK_ZOOM: 'Links para partilhar para participar na Zoom (Conferência Online):\n%s',
ZOOM_CONFERENCE: 'Aqui está o programa das Conferências (Zoom) aberto a TODOS:',
NON_VERIF: 'Não verificado',
VERIF: 'Verificado',
EMAIL: 'Email',
BOT: 'BOT',
EMAIL_NON_VERIF:
'Email Não verificado\nleia a sua caixa de correio e encontre **"Confirmar o registo"**<br>e clique no botão **"Verificação do registo"**',
TELEGRAM_NOT_CONNECTED: 'Telegrama não associado à sua conta!',
NESSUN_INVITATO: 'Você não convidou ninguém',
ZOOM_PARTECIPATO: 'Participação em pelo menos 1 Conferência (Zoom)',
LINEE_GUIDA: 'Directrizes Aceites',
VIDEO_INTRO: 'Ver o vídeo',
SCRITTO_SOGNO: 'Você escreveu o seu sonho',
PAYMENTS: 'Formas de pagamento',
INVITATI: 'pessoas registadas que convidou',
INVITATI_ATTIVI: 'Convidado com os 7 Requisitos',
NONREG: 'Convidados não registados',
CLICCA_PER_ZOOM: 'PARA O DIA E HORA INDICADOS, PARA ENTRAR NA VÍDEO-CONFERÊNCIA, CLIQUE AQUI',
CLICCA_ENTRA: 'CLIQUE AQUI PARA ENTRAR !',
ZOOM_INIZIATO: 'ESTA CONFERÊNCIA JÁ COMEÇOU!',
SCEGLI_VOCE: 'escolha uma voz:',
INVITATI_LISTA: 'Os seus convidados (em verde com, pelo menos, os 7 primeiros requisitos)',
CIAO: 'Olá',
ADDED_TOLISTAINGRESSO: 'Foi acrescentado à Lista de Embarque !',
NO_PROG: 'Actualmente, ainda não consta da lista de embarque.!',
SEND_LINK_CHAT_DONATORI: 'Olà %s!\nO seu SHIP está finalmente a zarpar.!\nEntre no Gift Chat, clicando aqui: %s',
SEND_LINK_CHAT_SOGNATORE:
'Olá %s!\nHoje você se torna um sonhador! 🎊🎊🎊 Entre no Gift Chat do navio {%s} clicando aqui: %s',
ENTRA_GIFT_CHAT: 'Entre no Gift Chat do navio',
DATA_PART_NAVE: 'data de partida do navio:',
SOGNATORE: 'SONHEIROS',
INTERMEDIO: 'Intermediar',
MEDIATORE: 'MEDIATOR',
DONATORI: 'DONATORES',
RITESSITURA: 'ENTRE EM',
'NAVE COMPLETATA': 'NAVIO COMPLETADO',
'Doni Effettuati': 'Regalo Feitos',
'Facilitatore che affianchèra il Mediatore': 'Facilitatore que apoia o Mediator',
APERTURA_CHIUSURA_GIFT_CHAT:
'%s: Abertura do GIFT CHAT\n%s Fechamento GIFT CHAT\nNota: Você tem 3 dias desde a abertura para entrar no Chat e fazer o seu Presente, depois do qual faremos o substituição.',
SPOSTATO: 'Você foi transferido para um novo navio !',
Note: 'Notas',
TEMPORANEA: 'TEMPORÁRIO',
NAVE: 'NAVE',
MSG_SEND_FROM: 'Mensagem enviada por',
ZOOM_CONFERMATO: 'Foi-lhe confirmado que assistiu à Conferência de Vídeo de Boas-vindas!',
RICHIESTA_AMICIZIA: "Richiesta d'Amicizia da parte di %s",
ACCETTATO_SUL_GRUPPO: 'Sei stato accettato da %s a far parte del Gruppo %s',
ACCETTATO_NOTIFICA_ADMINS: "l'utente %s è stato accettato a far parte del Gruppo %s (da parte di %s)",
RICHIESTA_BLOCCO_GRUPPO: 'Richiesta di bloccare il Gruppo %s da parte di %s',
},
};
module.exports = {
MYAPPS: [],
INITDB_FIRSTIME: true,
ACAPO: '\n',
ENABLE_CRONTAB: 'CRONTAB',
UPDATE_GRADUATORIA: 'UPDATE_GRAD',
LANGADMIN: 'it',
FREEPLANET: '1',
AYNI: '7',
CNM: '10',
RISO: '13',
FIOREDELLAVITA: '15',
PIUCHEBUONO: '17',
MACRO: '18',
IDAPP_BOTONGROUP: '1000',
HELP_CHAT: '',
TYPECONF_ZOOM: 'zoom',
TYPECONF_JITSI: 'jitsi',
APORTADOR_NONE: '------',
SEP: '|',
TYPE_PROJECT: 1,
TYPE_TODO: 2,
TipoMsg: {
SEND_LINK_CHAT_DONATORI: 1,
SEND_MSG: 2,
SEND_MSG_SINGOLO: 3,
SEND_TO_ALL: 10,
SEND_MSG_EFFETTUA_IL_DONO: 1000,
SEND_MSG_SOLLECITO_DONATORI_NO_DONO: 1005,
SEND_MSG_A_MEDIATORI: 1010,
SEND_MSG_A_SOGNATORE: 1020,
SEND_MSG_A_UTENTE_SOSTITUITO: 1030,
SEND_MSG_DONO_RICEVUTO_CORRETTAMENTE: 1040,
SEND_MSG_DONO_NON_RICEVUTO: 1050,
},
Perm: {
PERM_NONE: 0,
PERM_FRIEND: 1,
PERM_ALL: 10,
},
Placca: {
DONATORI: 1,
TUTTI: 2,
STR_SOGNATORE: '<strong>Sognatore</strong>',
STR_MEDIATORE: '<strong>Mediatore</strong>',
STR_MEDIATORI: '<strong>Mediatori</strong>',
STR_DONATORI: '<strong>Donatori</strong>',
SOGNATORE: 'E1 🌈 ',
MEDIATORE: 'A1 💦 ',
SONOFUOCO: 0,
SONOACQUA: 3,
SONOTERRA: 2,
SONOARIA: 1,
},
FieldType: {
boolean: 1,
date: 2,
string: 4,
binary: 8,
html: 16,
select: 32,
number: 64,
typeinrec: 128,
multiselect: 256,
password: 512,
listimages: 1024,
exact: 2048,
image: 3000,
image_and_filename: 3100,
nationality: 4096,
intcode: 5000,
multioption: 6000,
onlydate: 7000,
hours: 8000,
crypted: 9000,
},
MAX_PHASES: 5,
FIRST_PROJ: '__PROJECTS',
EXECUTE_CALCPROJ: true,
isDirectoryAsync: async function (dir) {
try {
const stats = await fs.promises.stat(dir);
return stats.isDirectory();
} catch (e) {
return false;
}
},
isFileExistsAsync: async function (filename) {
try {
let fileExists = await fs.promises
.stat(filename)
.then(() => true)
.catch(() => false);
// console.log(filename, 'esiste', fileExists)
return fileExists;
} catch (e) {
// console.log(filename, 'esiste', 'FALSE')
return false;
}
},
gettranslate: function (text, lang) {
try {
return textlang[lang][text];
} catch (e) {
return textlang['it'][text];
}
},
getlangbyres: function (res) {
// ++Todo: res estrarre la lingua
let lang = '';
try {
lang = res.lang;
} catch (e) {}
if (!lang) {
lang = 'it';
}
return lang;
},
get__: function (text, lang) {
try {
return textlang[lang][text];
} catch (e) {
return textlang['it'][text];
}
},
getres__: function (text, res) {
let lang = this.getlangbyres(res);
try {
return textlang[lang][text];
} catch (e) {
return textlang['it'][text];
}
},
getHostname: function () {
return os.hostname();
},
testing: function () {
return process.env.TESTING_ON === '1';
},
mylog: function (...args) {
if (!this.testing()) console.log(args);
},
mylogoff: function (...args) {
// doing nothing
},
mylogshow: function (...args) {
console.log(args);
},
mylogserr: function (...args) {
console.error(args);
},
allfieldSendMsg: function () {
return [
'userId',
'source',
'dest',
'message',
'datemsg',
'read',
'deleted',
'origin',
'idapp',
'status',
'options',
];
},
allfieldSendNotif: function () {
return [
'type',
'userId',
'sender',
'typedir',
'typeid',
'dest',
'descr',
'title',
'openUrl',
'datenotif',
'date_updated',
'read',
'deleted',
'idapp',
'tablerec',
'extrafield',
'tag',
'options',
'idrec',
'status',
];
},
allfieldTodo: function () {
return [
'userId',
'pos',
'category',
'descr',
'note',
'priority',
'statustodo',
'assignedToUsers',
'created_at',
'groupId',
'modify_at',
'completed_at',
'expiring_at',
'enableExpiring',
'progress',
'modified',
'phase',
'assigned_to_userId',
'assignedToUsers',
'hoursplanned',
'hoursworked',
'start_date',
'themecolor',
'themebgcolor',
];
},
allfieldMyEvent: function () {
return ['userId'];
},
allfieldTodoWithId: function () {
return ['_id', ...this.allfieldTodo()];
},
// #TODO Projects++ Add fields ...
allfieldProject: function () {
return [
'idapp',
'userId',
'respUsername',
'viceRespUsername',
'pos',
'typeproj',
'id_main_project',
'id_parent',
'descr',
'longdescr',
'groupId',
'hoursplanned',
'hoursleft',
'themecolor',
'themebgcolor',
'hoursworked',
'priority',
'statusproj',
'created_at',
'modify_at',
'completed_at',
'expiring_at',
'enableExpiring',
'progressCalc',
'modified',
'live_url',
'test_url',
'begin_development',
'begin_test',
'totalphases',
'actualphase',
'hoursweeky_plannedtowork',
'endwork_estimate',
'privacyread',
'privacywrite',
'tipovisu',
'view',
];
},
allfieldBooking: function () {
return [
'idapp',
'userId',
'username',
'id_bookedevent',
'tableType',
'numpeople',
'numpeopleLunch',
'numpeopleDinner',
'numpeopleDinnerShared',
'msgbooking',
'modified',
'infoevent',
'datebooked',
'booked',
];
},
allfieldBookingChange: function () {
return [
'numpeople',
'numpeopleLunch',
'numpeopleDinner',
'numpeopleDinnerShared',
'msgbooking',
'modified',
'infoevent',
'datebooked',
'booked',
];
},
allfieldProjectWithId: function () {
return ['_id', ...this.allfieldProject()];
},
jsonCopy(src) {
return JSON.parse(JSON.stringify(src));
},
CloneRecordToNew(src, modelTable) {
const myrec = Object.assign({}, src);
delete myrec._doc['_id'];
myrec._id = new ObjectId();
if (modelTable === 'Circuit') {
myrec._doc.name = myrec._doc.name + ' copia';
myrec._doc.path = myrec._doc.path + '_copia';
}
return myrec._doc;
},
sendBackNotif: async function (subscription, payload) {
const Subscription = require('../models/subscribers');
// console.log('sendBackNotif:', subscription, payload);
const pushOptions = {
vapidDetails: {
subject: process.env.VAPI_KEY_SUBJECT,
privateKey: process.env.PRIVATE_VAPI_KEY,
publicKey: process.env.PUBLIC_VAPI_KEY,
},
TTL: payload.ttl,
headers: {},
};
// Pass object into sendNotification
return (
webpush
.sendNotification(subscription._doc, JSON.stringify(payload), pushOptions)
.catch((err) => {
if (err.statusCode === 410) {
// Gone: is not valid anymore (Expired probably!), so I have to delete from my db
return Subscription.findOneAndDelete({ _id: subscription._id });
} else {
console.log('Subscription is no longer valid: ', err);
}
})
.then((ris) => {})
// console.log('sendNotification', ris);
.catch((err) => {
console.error(err);
})
);
},
sendNotificationToUser: async function (userId, title, content, openUrl, openUrl2, tag, actions, id) {
const Subscription = require('../models/subscribers');
content = this.convertHTMLtoText(content);
content = this.ConvertHTMLToPlainText(content);
let payload = {
actions,
title: title,
content,
url: openUrl,
url2: openUrl2,
tag,
id,
// ttl: req.body.ttl,
// icon: req.body.icon,
// image: req.body.image,
// badge: req.body.badge,
// tag: req.body.tag
};
try {
let subscriptions = [];
try {
subscriptions = await Subscription.find({ userId });
} catch (err) {
console.error(`Error occurred while getting subscriptions`);
// res.status(500).json({
// error: 'Technical error occurred'
// });
//++ Rimuovi questo record !?
return false;
}
let conta = 0;
if (subscriptions && subscriptions.length > 0) {
let parallelSubscriptionCalls = subscriptions.map((subscription) => {
const trovati = subscriptions.length;
return new Promise((resolve, reject) => {
const pushSubscription = {
endpoint: subscription.endpoint,
keys: {
p256dh: subscription.keys.p256dh,
auth: subscription.keys.auth,
},
};
conta++;
const parse = require('url-parse');
const parsedUrl = parse(subscription.endpoint);
const audience = parsedUrl.protocol + '//' + parsedUrl.hostname;
const vapidHeaders = webpush.getVapidHeaders(
audience,
process.env.VAPI_KEY_SUBJECT,
process.env.PUBLIC_VAPI_KEY,
process.env.PRIVATE_VAPI_KEY,
'aes128gcm'
);
const pushOptions = {
vapidDetails: {
subject: process.env.VAPI_KEY_SUBJECT,
privateKey: process.env.PRIVATE_VAPI_KEY,
publicKey: process.env.PUBLIC_VAPI_KEY,
},
TTL: payload.ttl,
headers: vapidHeaders,
};
// console.log('************ INVIO WEBPUSH.SENDNOTIFICATION N° ', conta, '/', trovati, 'A', subscription.browser);
const pushPayload = JSON.stringify(payload);
webpush
.sendNotification(pushSubscription, pushPayload, pushOptions)
.then((value) => {
// console.log('Invio Push', value);
resolve({
status: true,
endpoint: subscription.endpoint,
data: value,
});
})
.catch(async (err) => {
console.error('err Push', err.body);
if (err.body) {
// Cancella dal DB la notifica Push, visto che da errore! (sarà scaduto)
const ris = await Subscription.deleteOne({ _id: subscription._id });
}
reject({
status: false,
endpoint: subscription.endpoint,
data: err,
});
});
}).catch((error) => {
console.log('ERROR: sendNotificationToUser', error.data.body ? error.data.body : error);
});
});
return true;
}
// q.allSettled(parallelSubscriptionCalls).then((pushResults) => {
// console.info(pushResults);
// });
// res.json({
// data: 'Push triggered'
// });
} catch (e) {
console.error('sendNotificationToUser', e.message);
}
},
getReqByPar(idapp, usernameOrig, groupOrig) {
return {
body: {
idapp: idapp,
},
user: {
username: usernameOrig,
groupOrig,
},
};
},
sendNotificationByUsername: async function (idapp, username, cmd, telegram, usernameOrig, recObjCreator) {
var { User } = require('../models/user');
const { SendNotif } = require('../models/sendnotif');
const telegrambot = require('../telegram/telegrambot');
const user = await User.findOne({ idapp, username }, { _id: 1, username: 1, lang: 1 }).lean();
if (!user) return;
let userId = user._id;
let lang = user.lang;
let sendmynotif = true;
let title = this.getNomeAppByIdApp(idapp);
let descr = '';
let openUrl = '/';
let tag = '';
let actions = [];
let domanda = '';
let keyb = null;
if (cmd) {
if (cmd === shared_consts.FRIENDSCMD.REQFRIEND) {
descr = printf(this.get__('RICHIESTA_AMICIZIA', lang), usernameOrig);
openUrl = '/my/' + usernameOrig;
tag = 'reqfriends';
const userrecDest = await User.getUserShortDataByUsername(idapp, usernameOrig);
if (userrecDest) {
sendmynotif = false; // non lo rimandare 2 volte !
// SEND TELEGRAM NOTIFICATION
telegrambot.askConfirmationUserFriend(
idapp,
shared_consts.CallFunz.RICHIESTA_AMICIZIA,
userrecDest,
username,
usernameOrig
);
}
} else if (cmd === shared_consts.FRIENDSCMD.SETHANDSHAKE) {
const userrecDest = await User.getUserShortDataByUsername(idapp, usernameOrig);
const foundIfAlready = await User.isMyHandShake(idapp, username, usernameOrig);
if (!foundIfAlready) {
telegrambot.askConfirmationUserFriend(
idapp,
shared_consts.CallFunz.RICHIESTA_HANDSHAKE,
userrecDest,
username,
usernameOrig
);
}
}
}
if (userId) {
// SEND PUSH NOTIFICATION
await this.sendNotificationToUser(userId, title, descr, openUrl, '', tag, actions);
}
if (telegram && sendmynotif) {
const idtelegram = await User.TelegIdByUsername(idapp, username);
await telegrambot.sendMsgTelegramByIdTelegram(
idapp,
idtelegram,
descr + domanda,
undefined,
undefined,
true,
keyb
);
}
},
sendMsgTelegramToAdmin: async function (idapp, msg) {
const telegrambot = require('../telegram/telegrambot');
const idtelegram = telegrambot.ADMIN_IDTELEGRAM_SERVER;
await telegrambot.sendMsgTelegramByIdTelegram(idapp, idtelegram, msg);
},
sendNotifAndMsgTelegram: async function (idapp, userId, objmsg, telegram, msgextrateleg) {
if (userId) {
await this.sendNotificationToUser(
userId,
objmsg.title,
objmsg.descr,
objmsg.openUrl,
'',
objmsg.tag,
objmsg.actions
);
}
if (telegram) {
var { User } = require('../models/user');
const telegrambot = require('../telegram/telegrambot');
const idtelegram = await User.TelegIdById(idapp, userId);
const msgteleg = objmsg.descr + (msgextrateleg ? '\n' + msgextrateleg : '');
await telegrambot.sendMsgTelegramByIdTelegram(idapp, idtelegram, msgteleg);
}
},
sendNotifGroupByUsername: async function (
cmd,
idapp,
usernameOrig,
usernameDest,
username_action,
groupname,
myrecgroup,
isAdmin,
username_worked
) {
const { SendNotif } = require('../models/sendnotif');
const { User } = require('../models/user');
const telegrambot = require('../telegram/telegrambot');
const req = this.getReqByPar(idapp, usernameOrig);
const user = await User.findOne({ idapp, username: usernameDest }, { _id: 1, lang: 1 });
if (user) {
let lang = user.lang;
let paramsObj = {
usernameDest,
groupnameDest: groupname,
username_action: username_action,
singleadmin_username: usernameDest,
options: 0,
lang,
isAdmin,
username_worked,
};
let sendnotif = true;
let typedir = shared_consts.TypeNotifs.TYPEDIR_GROUPS;
let typeid = 0;
let onlysave = false;
let numuseringroup = await User.countUsersInGroup(idapp, groupname);
if (cmd) {
if (cmd === shared_consts.GROUPSCMD.SETGROUP) {
if (myrecgroup && myrecgroup.createdBy === usernameDest && numuseringroup <= 1) {
typeid = shared_consts.TypeNotifs.ID_GROUP_NEW_REC;
} else {
typeid = shared_consts.TypeNotifs.ID_GROUP_ACCEPTED;
}
} else if (cmd === shared_consts.GROUPSCMD.REFUSE_REQ_GROUP) {
typeid = shared_consts.TypeNotifs.ID_GROUP_REFUSED;
} else if (cmd === shared_consts.GROUPSCMD.REMOVE_FROM_MYGROUP) {
typeid = shared_consts.TypeNotifs.ID_GROUP_REMOVED;
} else if (cmd === shared_consts.GROUPSCMD.REQGROUP) {
typeid = shared_consts.TypeNotifs.ID_GROUP_REQUEST_TO_ENTER;
// paramsObj.options = MessageOptions.Notify_OnlyToNotifinApp + MessageOptions.Notify_ByBotTelegram;
const myuserdata = await User.getUserShortDataByUsername(idapp, username_action);
telegrambot.askConfirmationUser(
idapp,
shared_consts.CallFunz.RICHIESTA_GRUPPO,
myuserdata,
usernameDest,
groupname,
myrecgroup._id
);
onlysave = false;
} else if (cmd === shared_consts.GROUPSCMD.BLOCK_USER) {
typeid = shared_consts.TypeNotifs.ID_GROUP_BLOCK_USER;
} else if (cmd === shared_consts.GROUPSCMD.DELETE_GROUP) {
typeid = shared_consts.TypeNotifs.ID_GROUP_DELETE_USER;
} else if (cmd === shared_consts.GROUPSCMD.ADDADMIN_OFMYGROUP) {
typeid = shared_consts.TypeNotifs.ID_GROUP_ADDED_ADMIN_OFMYGROUP;
} else if (cmd === shared_consts.GROUPSCMD.REMOVEADMIN_OFMYGROUP) {
typeid = shared_consts.TypeNotifs.ID_GROUP_REMOVED_ADMIN_OFMYGROUP;
}
}
if (sendnotif && typeid > 0) {
// CREATE NOTIFICATION IN TABLE SENDNOTIF
await SendNotif.createNewNotifToSingleUser(req, null, paramsObj, onlysave, typedir, typeid);
}
}
},
sendNotifCircuitByUsername: async function (
cmd,
idapp,
usernameOrig,
groupOrig,
usernameDest,
groupDest,
username_action,
circuitname,
path,
myreccircuit,
isAdmin,
username_worked,
extrarec
) {
const { SendNotif } = require('../models/sendnotif');
const { User } = require('../models/user');
const telegrambot = require('../telegram/telegrambot');
const { MyGroup } = require('../models/mygroup');
const { Circuit } = require('../models/circuit');
const req = this.getReqByPar(idapp, usernameOrig, groupOrig);
let arrris = [];
const userOrig = await User.findOne(
{ idapp, username: usernameOrig },
{ _id: 1, lang: 1, aportador_solidario: 1, name: 1, surname: 1, username: 1 }
);
const user = await User.findOne({ idapp, username: usernameDest }, { _id: 1, lang: 1 });
let lang = 'it';
if (user) {
lang = user.lang;
}
let ris = null;
try {
let paramsObj = {
usernameDest,
circuitnameDest: circuitname,
path,
username_action: username_action,
singleadmin_username: usernameDest,
extrarec,
options: 0,
lang,
isAdmin,
username_worked,
};
let sendnotif = true;
let typedir = shared_consts.TypeNotifs.TYPEDIR_CIRCUITS;
let typeid = 0;
let onlysave = false;
let numuserincircuit = await User.countUsersInCircuit(idapp, circuitname);
const mycircuit = await Circuit.findOne({ name: circuitname }).lean();
if (mycircuit && extrarec) {
extrarec.fido_scoperto_default = mycircuit.fido_scoperto_default;
extrarec.fido_scoperto_default_grp = mycircuit.fido_scoperto_default_grp;
}
if (cmd) {
if (cmd === shared_consts.CIRCUITCMD.SET) {
if (myreccircuit && myreccircuit.createdBy === usernameDest && numuserincircuit <= 1) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_NEW_REC;
} else {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_ACCEPTED;
}
} else if (cmd === shared_consts.CIRCUITCMD.REFUSE_REQ) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_REFUSED;
} else if (cmd === shared_consts.CIRCUITCMD.REMOVE_FROM_MYLIST) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_REMOVED;
} else if (cmd === shared_consts.CIRCUITCMD.REQ) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_REQUEST_TO_ENTER;
// paramsObj.options = MessageOptions.Notify_OnlyToNotifinApp + MessageOptions.Notify_ByBotTelegram;
const myuserdata = await User.getUserShortDataByUsername(idapp, username_action);
let cmdrichiesta = shared_consts.CallFunz.RICHIESTA_FIDO;
if (mycircuit && mycircuit.askManagerToEnter) {
cmdrichiesta = shared_consts.CallFunz.RICHIESTA_CIRCUIT;
}
telegrambot.askConfirmationUser(
idapp,
cmdrichiesta,
myuserdata,
usernameDest,
circuitname,
myreccircuit._id,
'',
extrarec.groupname
);
if (mycircuit.sendEmailAfterAskingToEnter) {
const { Circuit } = require('../models/circuit');
const path = await Circuit.getPathByCircuitName(idapp, circuitname);
let myapp = this.getHostByIdApp(idapp);
let linkcirc = myapp + path;
let messaggio = '';
let mytitle = i18n.__('CIRCUIT_REQUEST_TO_ENTER_ASKMANAGER_TITLE', usernameOrig);
messaggio = i18n.__(
'CIRCUIT_REQUEST_TO_ENTER_ASKMANAGER_SHORT',
usernameOrig,
'<strong>' + circuitname + '</strong>',
numuserincircuit,
userOrig.aportador_solidario
);
messaggio += '\n\n';
messaggio += '<a href="' + linkcirc + '" target="_blank">Clicca qui per entrare sul Circuito</a>\n';
const sendemail = require('../sendemail');
const email = myuserdata.email;
sendemail.sendEmail_ByText(lang, email, myuserdata, idapp, {
emailbody: messaggio,
emailtitle: mytitle,
});
}
onlysave = false;
} else if (cmd === shared_consts.CIRCUITCMD.ADDADMIN) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_ADDED_ADMIN;
} else if (cmd === shared_consts.CIRCUITCMD.SETFIDO) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_SETFIDO;
} else if (cmd === shared_consts.CIRCUITCMD.REMOVEADMIN) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_REMOVED_ADMIN;
} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REQ) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_SENDCOINSREQ;
} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REQ_SENT) {
// Crea l'ID di Transazione
paramsObj.idTransaction = new ObjectId();
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_SENDCOINSREQ_SENT;
} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_COINS_ACCEPTED;
} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT_SENT) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_COINS_ACCEPTED_SENT;
// } else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE) {
// typeid = shared_consts.TypeNotifs.ID_CIRCUIT_COINS_REFUSED;
//} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE_SENT) {
// typeid = shared_consts.TypeNotifs.ID_CIRCUIT_COINS_REFUSED_SENT;
}
}
if (sendnotif && typeid > 0) {
const groupDestoContoCom = groupDest
? groupDest
: extrarec && extrarec.contoComDest
? extrarec.contoComDest
: '';
// Check if is group:
if (
groupDestoContoCom &&
cmd !== shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT_SENT &&
cmd !== shared_consts.CIRCUITCMD.SENDCOINS_REFUSE_SENT
) {
let arrusers = await MyGroup.getListAdminsByGroupName(idapp, groupDestoContoCom);
if (arrusers.length <= 0) arrusers = await Circuit.getListAdminsByCircuitPath(idapp, groupDestoContoCom);
let notiftoUpdate = '';
let findrecnotif = await SendNotif.findOne({ _id: paramsObj.extrarec.notifId }).lean();
notiftoUpdate = findrecnotif ? findrecnotif.extrarec.notifIdToUpdate : '';
if (findrecnotif) {
let arrrec = [];
if (notiftoUpdate) arrrec = await SendNotif.find({ 'extrarec.notifIdToUpdate': notiftoUpdate });
for (let rec of arrrec) {
paramsObj.usernameDest = rec.dest;
paramsObj.sender = rec.sender;
if (
cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT ||
cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE
) {
try {
paramsObj.extrarec.notifId = rec._id;
} catch (e) {}
}
ris = await SendNotif.createNewNotifToSingleUser(req, null, paramsObj, onlysave, typedir, typeid);
if (!ris) {
console.error(
'Errore createNewNotifToSingleUser! ',
paramsObj.usernameDest,
'dest ->',
groupDestoContoCom
);
} else {
arrris.push(ris._id);
}
}
} else {
for (let i = 0; i < arrusers.length; i++) {
paramsObj.usernameDest = arrusers[i].username;
ris = await SendNotif.createNewNotifToSingleUser(req, null, paramsObj, onlysave, typedir, typeid);
if (!ris) {
console.error(
'Errore createNewNotifToSingleUser! ',
paramsObj.usernameDest,
'dest ->',
groupDestoContoCom
);
} else {
arrris.push(ris._id);
}
}
}
} else {
// CREATE NOTIFICATION IN TABLE SENDNOTIF
ris = await SendNotif.createNewNotifToSingleUser(req, null, paramsObj, onlysave, typedir, typeid);
if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT || cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE) {
if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_COINS_ACCEPTED_SENT;
} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE) {
typeid = shared_consts.TypeNotifs.ID_CIRCUIT_COINS_REFUSED_SENT;
}
let notiftoUpdate = '';
let findrecnotif = await SendNotif.findOne({ _id: paramsObj.extrarec.notifId }).lean();
notiftoUpdate = findrecnotif ? findrecnotif.extrarec.notifIdToUpdate : '';
arrnotiftoUpdate = findrecnotif ? findrecnotif.extrarec.arrnotifIdToUpdate : '';
if (findrecnotif && notiftoUpdate && arrnotiftoUpdate) {
for (let myid of arrnotiftoUpdate) {
let rec = await SendNotif.findOne({ _id: myid }).lean();
if (rec && rec.status === 0) {
paramsObj.usernameDest = rec.dest;
paramsObj.extrarec.idStatusToSent = rec._id;
ris = await SendNotif.createNewNotifToSingleUser(req, null, paramsObj, onlysave, typedir, typeid);
if (!ris) {
console.error(
'Errore createNewNotifToSingleUser! ',
paramsObj.usernameDest,
'dest ->',
groupDestoContoCom
);
}
}
}
}
}
}
}
return { recnotif: ris, arrris };
} catch (e) {
console.log(e.message);
}
},
sendNotificationByGroupname: async function (idapp, usernameOrig, groupname, cmd, value, telegram, username_action) {
const { MyGroup } = require('../models/mygroup');
const { User } = require('../models/user');
const group = await MyGroup.findOne({ idapp, groupname }, { _id: 1, admins: 1, createdBy: 1 }).lean();
if (!group) return;
let giainviato = false;
try {
// SEND TO THE ADMINS THE NOTIFICATIONS
for (const singleadmin of group.admins) {
try {
if (singleadmin.username) {
if (usernameOrig === singleadmin.username) giainviato = true;
await this.sendNotifGroupByUsername(
cmd,
idapp,
usernameOrig,
singleadmin.username,
username_action,
groupname,
group,
true
);
}
} catch (e) {
console.error('sendNotificationByGroupname', e);
}
}
if (!giainviato && cmd !== shared_consts.GROUPSCMD.REQGROUP) {
// SEND TO THE USER THE NOTIFICATION
await this.sendNotifGroupByUsername(
cmd,
idapp,
usernameOrig,
usernameOrig,
username_action,
groupname,
null,
false
);
}
} catch (e) {
console.error('e', e);
}
},
getAdminsByCircuit(circuit) {
// return circuit.admins
return [...circuit.admins, { username: shared_consts.USER_ADMIN_CIRCUITS }];
},
sendNotificationByCircuit: async function (
idapp,
usernameOrig,
circuitname,
cmd,
value,
telegram,
username_action,
extrarec
) {
const { Circuit } = require('../models/circuit');
const { SendNotif } = require('../models/sendnotif');
const circuit = await Circuit.findOne(
{ idapp, name: circuitname },
{ _id: 1, admins: 1, createdBy: 1, path: 1 }
).lean();
if (!circuit) return;
let giainviato = false;
try {
// SEND TO THE ADMINS THE NOTIFICATIONS
let ris = false;
let inviato = false;
let arrris = [];
if (
cmd === shared_consts.CIRCUITCMD.SENDCOINS_REQ ||
cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT ||
cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE
) {
groupOrig = extrarec.grouporig;
let recnotif = null;
if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REQ) {
// msg al Mittente (o mittenti del 'groupOrig') "Stai inviando X RIS"
let res = await this.sendNotifCircuitByUsername(
shared_consts.CIRCUITCMD.SENDCOINS_REQ_SENT,
idapp,
extrarec.dest,
extrarec.groupdest,
usernameOrig,
groupOrig,
username_action,
circuitname,
circuit.path,
null,
false,
'',
extrarec
);
if (res) {
recnotif = res.recnotif;
arrris = res.arrris;
}
} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT) {
// msg ai MITTENTI: "X RIS sono stati accettati da Destinatario"
await this.sendNotifCircuitByUsername(
shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT_SENT,
idapp,
extrarec.dest,
extrarec.groupdest,
usernameOrig,
groupOrig,
username_action,
circuitname,
circuit.path,
null,
false,
'',
extrarec
);
} else if (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE) {
await this.sendNotifCircuitByUsername(
shared_consts.CIRCUITCMD.SENDCOINS_REFUSE_SENT,
idapp,
extrarec.dest,
extrarec.groupdest,
usernameOrig,
groupOrig,
username_action,
circuitname,
circuit.path,
null,
false,
'',
extrarec
);
}
if (recnotif) extrarec.notifIdToUpdate = recnotif._id;
if (arrris) extrarec.arrnotifIdToUpdate = arrris;
let usernametoOrigUse = usernameOrig;
if (extrarec.groupname) {
usernametoOrigUse = '';
}
ris = await this.sendNotifCircuitByUsername(
cmd,
idapp,
usernametoOrigUse,
groupOrig,
extrarec.dest,
extrarec.groupdest,
username_action,
circuitname,
circuit.path,
null,
false,
'',
extrarec
);
if (arrris && ris && ris.recnotif) {
for (const rec of arrris) {
let obj = {
'extrarec.notifIdToUpdate': ris.recnotif._id,
};
await SendNotif.findOneAndUpdate({ _id: rec._id }, { $set: obj }, { new: false });
}
}
extrarec.notifIdToUpdate = '';
if (ris.recnotif) inviato = true;
// ++Todo: Inviare anche agli Admin ?!
} else {
const groupOrig = ''; //++Todo: extrarec.groupOrig
for (const singleadmin of this.getAdminsByCircuit(circuit)) {
try {
if (singleadmin.username) {
if (usernameOrig === singleadmin.username) giainviato = true;
await this.sendNotifCircuitByUsername(
cmd,
idapp,
usernameOrig,
groupOrig,
singleadmin.username,
'',
username_action,
circuitname,
circuit.path,
circuit,
true,
'',
extrarec
);
inviato = true;
}
} catch (e) {
console.error('sendNotificationByCircuit', e);
}
}
if (!giainviato && cmd !== shared_consts.CIRCUITCMD.REQ) {
// SEND TO THE USER DEST THE NOTIFICATION
ris = await this.sendNotifCircuitByUsername(
cmd,
idapp,
usernameOrig,
groupOrig,
usernameOrig,
'',
username_action,
circuitname,
circuit.path,
null,
false,
'',
extrarec
);
if (ris && ris.recnotif) inviato = true;
}
}
if (inviato) {
if (arrris && arrris.length > 0) {
for (const notif of arrris) {
await SendNotif.updatePendingTransactions(notif);
}
} else {
if (ris) {
await SendNotif.updatePendingTransactions(ris.recnotif);
}
}
}
return { ris: ris.recnotif, inviato };
} catch (e) {
console.error('sendNotificationByCircuit: ', e);
return { ris: null, inviato: false };
}
},
// **********************
// SORT WITH PREV_ID
// **********************
/* mapSort: function (linkedList) {
let sortedList = [];
let remainingList = [];
var map = new Map();
var currentId = null;
// console.log('linkedList', linkedList);
// index the linked list by previous_item_id
for (var i = 0; i < linkedList.length; i++) {
var item = linkedList[i];
if (item.id_prev === server_constants.LIST_START) {
// first item
currentId = item._id.toString();
// console.log('currentId', currentId);
sortedList.push(item);
} else {
map.set(item.id_prev.toString(), i);
}
}
let conta = 0;
while (conta < linkedList.length) {
// get the item with a previous item ID referencing the current item
var nextItem = linkedList[map.get(currentId)];
if (nextItem === undefined) {
} else {
sortedList.push(nextItem);
currentId = nextItem._id.toString();
}
conta++;
}
if (linkedList.length > sortedList.length) {
// If are not in the list, I'll put at the bottom of the list
// console.log('ATTENZIONE !!! ', sortedList.length, linkedList.length);
for (const itemlinked of linkedList) {
const elemtrov = sortedList.find((item) => item._id === itemlinked._id);
if (elemtrov === undefined) {
sortedList.push(itemlinked);
}
}
}
// console.log('DOPO sortedList', sortedList);
return sortedList;
},
*/
async sendNotifToCircuitsAdmin(idapp, circuit, alsotelegram, title, msg, tag = '') {
const { User } = require('../models/user');
const telegrambot = require('../telegram/telegrambot');
if (!circuit || !this.getAdminsByCircuit(circuit)) {
console.error('sendNotifToCircuitsAdmin: missing circuit or circuit.admins', circuit);
return;
}
for (const singleadmin of this.getAdminsByCircuit(circuit)) {
try {
if (singleadmin && singleadmin.username) {
const user = await User.getUserShortDataByUsername(idapp, singleadmin.username);
if (user) {
if (alsotelegram) {
if (!user.profile || !user.profile.teleg_id) {
console.error('sendNotifToCircuitsAdmin: missing user.profile.teleg_id', user);
} else {
telegrambot.local_sendMsgTelegramByIdTelegram(idapp, user.profile.teleg_id, title + ' ' + msg);
}
}
if (!user._id) {
console.error('sendNotifToCircuitsAdmin: missing user._id', user);
} else {
await this.sendNotificationToUser(user._id, title, msg, '/', '', tag, []);
}
}
}
} catch (e) {
console.error('sendNotifToCircuitsAdmin', e);
}
}
},
sendNotifToAdmin(idapp, alsotelegram, title, msg, tag = '') {
try {
const { User } = require('../models/user');
const queryadmins = { username: 'paoloar77', idapp };
if (idapp === 0) idapp = '13';
User.find(queryadmins).then(async (arrusers) => {
if (arrusers !== null) {
for (const user of arrusers) {
if (alsotelegram) {
this.sendMsgTelegramToAdmin(idapp, title + ' ' + msg);
}
await this.sendNotificationToUser(user._id, title, msg, '/', '', tag, []).then((ris) => {
if (ris) {
} else {
// already sent the error on calling sendNotificationToUser
}
});
}
}
});
} catch (e) {
console.error(e);
}
},
checkUserOk(userpassed, userauth, res) {
// this.mylog('checkUserOk', userpassed, userauth);
if (String(userpassed) !== String(userauth)) {
// I'm trying to write something not mine!
this.mylog("I'm trying to write something not mine!: userId = ", userpassed, 'req.user._id', userauth);
if (!res) {
return {
exit: true,
ret: false,
};
} else {
return {
exit: true,
ret: false,
// ret: res.status(404).
// send({ code: server_constants.RIS_CODE_TODO_CREATING_NOTMYUSER }),
};
}
} else {
return { exit: false, ret: false };
}
},
ConvertHTMLToPlainText(strHTML) {
if (strHTML) return strHTML.replace(/<[^>]+>/g, '');
return '';
},
convertSpaces_ToUScore(mystr) {
if (mystr) return mystr.replace(/\s+/g, '_');
return '';
},
convertHTMLtoText(myhtml) {
let msg = myhtml;
if (msg) {
msg = msg.replace('&quot;', '"');
msg = msg.replace(/<strong>/g, '');
msg = msg.replace(/<\/strong>/g, '');
msg = msg.replace(/<em>/g, '');
msg = msg.replace(/<\/em>/g, '');
msg = msg.replace('&gt;', '>');
msg = msg.replace('&lt;', '<');
msg = msg.replace('&amp;', '&');
msg = msg.replace('<br>', '\n');
}
return msg;
},
htmlToTelegramText(html) {
try {
const withMarkdown = html
.replace(/<strong>(.*?)<\/strong>/g, '*$1*')
.replace(/<b>(.*?)<\/b>/g, '*$1*')
.replace(/<em>(.*?)<\/em>/g, '_$1_')
.replace(/<u>(.*?)<\/u>/g, '__$1__');
// Remove other HTML tags
const plainText = withMarkdown.replace(/<[^>]*>/g, '');
// Replace HTML entities with their equivalent Markdown or plain text representations
const replacements = [
{ pattern: /&amp;/g, replacement: '&' },
{ pattern: /&lt;/g, replacement: '<' },
{ pattern: /&gt;/g, replacement: '>' },
{ pattern: /&quot;/g, replacement: '"' },
{ pattern: /&#39;/g, replacement: "'" },
];
let telegramText = plainText;
replacements.forEach((replacement) => {
telegramText = telegramText.replace(replacement.pattern, replacement.replacement);
});
return telegramText;
} catch (e) {
console.error(e);
}
},
htmlToTelegramText(html) {
try {
const withMarkdown = html
.replace(/<strong>(.*?)<\/strong>/g, '*$1*')
.replace(/<b>(.*?)<\/b>/g, '*$1*')
.replace(/<em>(.*?)<\/em>/g, '_$1_')
.replace(/<u>(.*?)<\/u>/g, '__$1__');
// Remove other HTML tags
const plainText = withMarkdown.replace(/<[^>]*>/g, '');
// Replace HTML entities with their equivalent Markdown or plain text representations
const replacements = [
{ pattern: /&amp;/g, replacement: '&' },
{ pattern: /&lt;/g, replacement: '<' },
{ pattern: /&gt;/g, replacement: '>' },
{ pattern: /&quot;/g, replacement: '"' },
{ pattern: /&#39;/g, replacement: "'" },
];
let telegramText = plainText;
replacements.forEach((replacement) => {
telegramText = telegramText.replace(replacement.pattern, replacement.replacement);
});
return telegramText;
} catch (e) {
console.error(e);
}
},
convertTexttoHtml(myhtml) {
// let msg = myhtml;
// msg = msg.replace('\n', '<br>');
// return msg
return myhtml;
},
removeSpecialCharForEmail(myhtml) {
let msg = myhtml;
try {
if (msg) msg = msg.replace(/"/g, "'");
} catch (e) {
return msg;
}
return msg;
},
getNomeAppByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) return (process.env.NODE_ENV === 'test' ? 'Test: ' : '') + myapp.name;
else return '';
},
getTimeExpReg: async function (idapp, username) {
var { User } = require('../models/user');
return await User.createNewReqRegistrationGetLink(idapp, username);
},
getLinkRegByIdAppAndMsgStrutt: function (idapp, msg, rec) {
let myapp = this.getHostByIdApp(idapp);
if (myapp) {
myapp +=
'/registrati/' + rec.aportador_solidario + '/' + msg.from.username + '/' + msg.from.id + '/' + rec.regexpire;
}
return myapp;
},
getHostByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) {
let siteport = myapp.portapp && myapp.portapp !== '0' ? ':' + myapp.portapp : '';
if (process.env.NODE_ENV === 'test') return myapp.host_test + siteport;
else return myapp.host + siteport;
} else return '';
},
getLinkUserProfile: function (idapp, username) {
return this.getHostByIdApp(idapp) + '/my/' + username;
},
getLinkUserTelegram: async function (idapp, username, myuser) {
var { User } = require('../models/user');
let u_tg = '';
if (myuser)
u_tg =
myuser.profile && myuser.profile.hasOwnProperty('username_telegram')
? myuser.profile.username_telegram
: usernametelegram;
if (!u_tg) {
u_tg = await User.getUsernameTelegram(idapp, username);
}
if (u_tg) return `https://t.me/${u_tg}`;
else return '';
},
getLinkEditUserProfile: function (idapp) {
return this.getHostByIdApp(idapp) + '/editprofile';
},
getConfSiteOptionEnabledByIdApp: function (idapp, option) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) {
if (myapp.hasOwnProperty('confsite')) {
if (myapp.confsite.hasOwnProperty('options')) {
return this.isBitActive(myapp.confsite.options, option);
}
}
}
return false;
},
getEnableTokenExpiredByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp && myapp.confpages && myapp.confpages.hasOwnProperty('enableTokenExpired')) {
return myapp.confpages.enableTokenExpired;
}
return false;
},
getConfParamSiteByIdApp: function (idapp, field) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) {
if (myapp.hasOwnProperty('confsite')) {
if (myapp.confsite.hasOwnProperty(field)) {
return myapp.confsite[field];
}
}
}
return false;
},
isAbilitaNave: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
return myapp.abilitanave;
},
removeLastSlashFromPath: function (myString) {
let regex = /\/$/;
let result = myString;
try {
if (myString) result = myString.replace(regex, '');
} catch (e) {
return myString;
}
return result;
},
getdirByIdApp: function (idapp, dirmain = false) {
let mypath = '';
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) {
if (process.env.NODE_ENV === 'test') mypath = myapp && myapp.dir_test ? myapp.dir_test : '';
else mypath = myapp && myapp.dir ? myapp.dir : '';
if (dirmain) {
if (!this.sulServer()) {
mypath += 'public';
}
}
}
return this.removeLastSlashFromPath(mypath);
},
getAdminEmailByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) return myapp.adminemail;
else return '';
},
getreplyToEmailByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) return myapp.replyTo;
else return '';
},
getpathregByIdApp: function (idapp, lang) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) {
const addstr = myapp.pathreg_add ? myapp.pathreg_add : '';
return 'registration' + addstr + '/' + lang;
} else {
return 'registration' + '/' + lang;
}
},
getparamSiteTableByIdApp: function (idapp, param) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
return myapp && param ? myapp[param] : '';
},
getAskToVerifyReg: function (idapp) {
return this.getConfSiteOptionEnabledByIdApp(idapp, shared_consts.ConfSite.Need_Aportador_On_DataReg_To_Verify_Reg);
},
getidMyGroupBySite: function (idapp) {
return this.getparamSiteTableByIdApp(idapp, 'idMyGroup');
},
isManagAndAdminDifferent(idapp) {
const manag = this.getManagerEmailByIdApp(idapp);
return manag !== this.getAdminEmailByIdApp(idapp) && manag !== '';
},
getManagerEmailByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (myapp) return !!myapp.manageremail ? myapp.manageremail : '';
else return '';
},
getEmailByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
return myapp ? myapp.email_from : '';
},
getPwdByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
return myapp ? this.decryptdata(myapp.email_pwd) : '';
},
getTelegramBotNameByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development')
return myapp ? myapp.telegram_bot_name_test : '';
else return myapp ? myapp.telegram_bot_name : '';
},
getTelegramSupportChat: function (idapp) {
try {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
return myapp && myapp.telegram_support_chat ? myapp.telegram_support_chat : '';
} catch (e) {
return '';
}
},
getTelegramKeyByIdApp: function (idapp) {
const myapp = this.MYAPPS.find((item) => item.idapp === idapp);
if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development')
return myapp ? myapp.telegram_key_test : '';
else return myapp ? myapp.telegram_key : '';
},
getArrTelegramFromSite: function () {
const myapp = this.MYAPPS;
let arrteleg = [];
for (const site of myapp) {
if (site.active) {
if (process.env.NODE_ENV === 'test') {
if (site.telegram_bot_name_test) arrteleg.push(site.idapp);
} else {
if (site.telegram_bot_name) arrteleg.push(site.idapp);
}
}
}
return arrteleg;
},
getLookupPipeLine(params, proj) {
let myquery = [
{
$lookup: {
from: params.lk_tab,
let: { username: '$' + params.lk_LF, idapp: params.idapp },
pipeline: [
{
$match: {
$expr: {
$and: [{ $eq: ['$' + params.lk_FF, '$$' + params.lk_FF] }, { $eq: ['$idapp', '$$idapp'] }],
},
},
},
],
as: params.lk_as,
},
},
{ $project: proj },
];
return myquery;
},
getNumTabByTable(table) {
const myrec = shared_consts.MYTABS.find((rec) => rec.table === table);
return myrec ? myrec.id : -1;
},
getTableByNumTab(numtab) {
const myrec = shared_consts.MYTABS.find((rec) => rec.id === numtab);
return myrec ? myrec.table : '';
},
getGroupnameLookupPipeLine(params, proj) {
let myquery = [
{
$lookup: {
from: params.lk_tab,
let: { groupname: '$' + params.lk_LF, idapp: params.idapp },
pipeline: [
{
$match: {
$expr: {
$and: [{ $eq: ['$' + params.lk_FF, '$$' + params.lk_FF] }, { $eq: ['$idapp', '$$idapp'] }],
},
},
},
],
as: params.lk_as,
},
},
{ $project: proj },
];
return myquery;
},
getLookupStandardPipeline: function (params, num) {
const query = [];
if (!params) return;
query.push(
{
$lookup: {
from: params.lk_tab,
let: { searchId: { $toObjectId: '$' + params.lk_LF } },
pipeline: [
{
$match: {
$expr: {
$and: [{ $eq: ['$' + params.lk_FF, '$$searchId'] }],
},
},
},
{
$project: params.lk_proj,
},
],
as: params.lk_as + num,
},
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
{
$arrayElemAt: ['$' + params.lk_as + num, 0],
},
'$$ROOT',
],
},
},
}
);
return query;
},
sanitizzaHtml(html) {
try {
return sanitizeHtml(html);
} catch (e) {
return html;
}
},
sanitizzaLookup: function (str) {
return str;
},
sanitizzaProjection: function (mioproj) {
// mioproj = {valore: '$password'};
const COL_TO_REMOVE = ['$password', '$tokens', '$tokens.token', 'ipaddr'];
for (let chiave in mioproj) {
// Elimina questa richiesta della password !
if (COL_TO_REMOVE.includes(mioproj[chiave])) {
delete mioproj[chiave];
}
}
return mioproj;
},
getLookup: function (params, num, pass_proj, proj_add) {
const query = [];
if (!params) return;
let mylkLF = params.lk_LF;
if (params.af_objId_tab) {
const myobj = {};
myobj['myId' + num] = { $toObjectId: '$' + params.lk_LF };
if (params.lk_tab === 'users') {
myobj.namecomplete = {
$concat: [{ $toLower: '$name' }, { $toLower: '$surname' }, { $toLower: '$username' }],
};
}
query.push({ $addFields: myobj });
mylkLF = 'myId' + num;
} else {
}
if (params.lk_tab) {
let proj = params.lk_proj;
proj = this.sanitizzaProjection(proj);
if (!!pass_proj) {
proj = pass_proj;
}
proj = Object.assign({}, proj, proj_add);
query.push({
$lookup: {
from: params.lk_tab,
localField: mylkLF, // field in my collection
foreignField: params.lk_FF, // field in the 'from' collection
as: params.lk_as,
},
});
if (params.unwind) {
query.push({
$unwind: {
path: '$' + params.lk_as,
preserveNullAndEmptyArrays: true,
},
});
}
if (!params.noarray) {
query.push({
$replaceRoot: {
newRoot: {
$mergeObjects: [
{
$arrayElemAt: ['$' + params.lk_as, 0],
},
'$$ROOT',
],
},
},
});
}
query.push({ $project: proj });
}
return query;
},
getFilterParam: function (filter, fieldsearch) {
let myregexp = {};
myregexp = new RegExp(filter.trim().replace(' ', '|'), 'ig');
let query = [];
const myfilters = [];
for (const rec of fieldsearch) {
let data = {};
if (rec.type === this.FieldType.exact) {
data[rec.field] = filter.trim();
} else if (rec.type === this.FieldType.string) {
data[rec.field] = myregexp;
if (rec.field === 'profile.username_telegram') {
myregexp = new RegExp(this.rimuoviAtPrimoCarattere(filter).trim().replace(' ', '|'), 'ig');
data[rec.field] = myregexp;
}
} else if (rec.type === this.FieldType.number || rec.type === this.FieldType.hours) {
data[rec.field] = parseFloat(filter.trim());
}
if (data) myfilters.push(data);
}
if (myfilters.length > 0) {
query = [{ $match: { $or: myfilters } }];
}
return query;
},
addQueryIdMatch: function (params) {
myquery = {};
if (
shared_consts.TABLES_ID_NUMBER.includes(params.table) ||
shared_consts.TABLES_ID_STRING.includes(params.table)
) {
myquery = {
$match: {
$expr: {
$eq: ['$_id', params.myid],
},
},
};
} else if (shared_consts.TABLES_NUM_AS_ID_NUMBER.includes(params.table)) {
myquery = {
$match: {
$expr: {
$eq: ['$Num', params.myid],
},
},
};
} else {
myquery = {
$match: {
$expr: {
$eq: ['$_id', mongoose.Types.ObjectId(params.myid)],
},
},
};
}
return myquery;
},
contieneIdStatusSkill(filtersearch) {
for (let i = 0; i < filtersearch.length; i++) {
const obj = filtersearch[i];
if (obj.$or) {
for (let j = 0; j < obj.$or.length; j++) {
const condition = obj.$or[j];
if (condition.idStatusSkill) {
return true;
}
}
}
}
return false;
},
addNumFavoriteAndBookmarkToQuery(idapp, numtab) {
let query = [];
try {
/*
query =
[
{
$lookup: {
from: "reactions",
let: {
tab: numtab,
id: '$_id',
},
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ['$idrec', '$$id'] },
{ $eq: ['$tab', numtab] },
{ $eq: ['$idapp', idapp] },
],
},
},
},
{
$group: {
_id: "$idrec",
numseen: {
$sum: {
$cond: {
if: { $ifNull: ["$seen", false] }, // Check if the field exists and is not null
then: 1, // Increment count by 1 if the field exists
else: 0, // Otherwise, keep the count unchanged
}
}
},
numfav: {
$sum: {
$cond: {
if: { $ifNull: ["$fav", false] }, // Check if the field exists and is not null
then: 1, // Increment count by 1 if the field exists
else: 0, // Otherwise, keep the count unchanged
}
}
},
numbook: {
$sum: {
$cond: {
if: { $ifNull: ["$book", false] }, // Check if the field exists and is not null
then: 1, // Increment count by 1 if the field exists
else: 0, // Otherwise, keep the count unchanged
}
}
}
},
},
],
as: 'myreact',
},
},
{
$unwind: {
path: "$myreact",
preserveNullAndEmptyArrays: true,
},
},
];
if (true) {
// RIMUOVI
// query = {};
}
if (true) {
// RIMUOVI
// query = {};
}
if (Object.keys(query).length > 0) {
const numtabbacheca = this.getNumTabByTable(shared_consts.TABLES_MYBACHECAS);
if (numtab === numtabbacheca) {
const queryadd = this.getQueryMyBacheca(idapp);
query = [...query, ...queryadd];
}
}
const numtabbacheca = this.getNumTabByTable(shared_consts.TABLES_MYBACHECAS);
if (numtab === numtabbacheca) {
const queryadd = this.getQueryMyBacheca(idapp);
query = [...query, ...queryadd];
}
*/
proj = {
numseen: 1,
numfav: 1,
numbook: 1,
numattend: 1,
};
} catch (e) {
console.error(e);
}
return { query, proj };
},
getQueryMyBacheca: function (idapp) {
const arrquery = [
{
$lookup: {
from: 'bookings',
let: {
id: '$_id',
},
pipeline: [
{
$match: {
$expr: {
$and: [{ $eq: ['$id_bookedevent', '$$id'] }, { $eq: ['$idapp', idapp] }],
},
},
},
{
$project: {
id_bookedevent: 1,
username: 1,
numpeople: 1,
numpeopleLunch: 1,
numpeopleDinner: 1,
numpeopleDinnerShared: 1,
infoevent: 1,
msgbooking: 1,
booked: 1,
datebooked: 1,
userId: 1,
idapp: 1,
},
},
],
as: 'mybookings',
},
},
/**
{
$lookup: {
from: "users",
localField: "myId1",
foreignField: "_id",
as: "user",
},
},
{
$lookup: {
from: "users",
let: {
myid: { $toObjectId: "$mybookings.userId" },
},
pipeline: [
{
$match: {
$expr: {
$and: [
{
$eq: [
"$_id",
"$$myid",
],
},
{
$eq: [
"$idapp",
"13",
],
},
],
},
},
},
{
$project: { _id: 1, username: 1 },
}
],
as: "myuser",
},
}**/
];
return arrquery;
},
getQueryTable: async function (idapp, params, user) {
try {
const { Search } = require('../models/search');
if (typeof params.startRow !== 'number') {
throw new Error('startRow must be number');
} else if (typeof params.endRow !== 'number') {
throw new Error('endRow must be number');
}
let newvers = !!params.newvers;
let query = [];
if (params.filter && params.fieldsearch) {
params.filter = this.sanitizzaHtml(params.filter);
params.fieldsearch = this.sanitizzaHtml(params.fieldsearch);
const querytemp = this.getFilterParam(params.filter, params.fieldsearch);
if (querytemp) {
query = [...query, ...querytemp];
}
}
let filtriadded = [];
// if (params.table === 'extralist') {
// if (params.filterand.includes(shared_consts.FILTER_EXTRALIST_DELETED))
// filtriadded.push({ deleted: true });
// else
// filtriadded.push({ deleted: { $exists: false } });
// }
if (params.filterand) {
params.filterand = this.sanitizzaHtml(params.filterand);
if (params.filterand.includes(shared_consts.FILTER_EXTRALIST_NOT_REGISTERED))
filtriadded.push({ registered: false });
if (params.filterand.includes(shared_consts.FILTER_EXTRALIST_NOT_CONTACTED)) {
filtriadded.push({ contacted: { $exists: false } });
}
if (params.filterand.includes(shared_consts.FILTER_EXTRALIST_WITH_NOTE))
filtriadded.push({
note: { $exists: true },
$expr: { $gt: [{ $strLenCP: '$note' }, 1] },
});
if (params.filterand.includes(shared_consts.FILTER_QUALIFIED)) filtriadded.push({ 'profile.qualified': true });
if (params.filterand.includes(shared_consts.FILTER_USER_NO_ZOOM))
filtriadded.push({ 'profile.saw_zoom_presentation': false });
if (params.filterand.includes(shared_consts.FILTER_ASK_ZOOM_VISTO))
filtriadded.push({ 'profile.ask_zoom_partecipato': false });
if (params.filterand.includes(shared_consts.FILTER_USER_NO_INVITANTE))
filtriadded.push({
aportador_solidario: { $exists: false },
});
if (params.filterand.includes(shared_consts.FILTER_USER_NO_TELEGRAM_ID))
filtriadded.push({ 'profile.teleg_id': { $lt: 1 } });
if (params.filterand.includes(shared_consts.FILTER_USER_SI_TELEGRAM_ID))
filtriadded.push({ 'profile.teleg_id': { $gt: 1 } });
if (params.filterand.includes(shared_consts.FILTER_USER_CODICE_AUTH_TELEGRAM))
filtriadded.push({ 'profile.teleg_checkcode': { $gt: 1 } });
if (params.filterand.includes(shared_consts.FILTER_USER_NO_EMAIL_VERIFICATA))
filtriadded.push({ verified_email: false });
if (params.filterand.includes(shared_consts.FILTER_USER_NO_VERIFIED_APORTADOR))
filtriadded.push({
verified_by_aportador: { $exists: false },
});
if (params.filterand.includes(shared_consts.FILTER_USER_WITHOUT_USERNAME_TELEGRAM))
filtriadded.push({
$or: [
{ 'profile.username_telegram': { $exists: false } },
{ 'profile.username_telegram': { $exists: true, $eq: '' } },
],
});
if (params.filterand.includes(shared_consts.FILTER_USER_NO_DREAM))
filtriadded.push({
'profile.my_dream': {
$exists: false,
},
});
if (params.filterand.includes(shared_consts.FILTER_USER_TELEGRAM_BLOCKED))
filtriadded.push({ 'profile.teleg_id_old': { $gt: 1 } });
if (params.filterand.includes(shared_consts.FILTER_USER_PROVINCE))
filtriadded.push({ 'profile.resid_province': { $exists: true } });
if (params.filterand.includes(shared_consts.FILTER_USER_SENZA_PROVINCE))
filtriadded.push({ 'profile.resid_province': { $exists: false } });
if (params.filterand.includes(shared_consts.FILTER_ATTIVI))
filtriadded.push({
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
});
// Hours
if (params.filterand.includes(shared_consts.FILTER_HOURS_ALL))
filtriadded.push({
idapp,
todoId: params.codeId,
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
});
else if (params.filterand.includes(shared_consts.FILTER_HOURS_MYLIST))
filtriadded.push({
idapp,
userId: params.userId,
todoId: params.codeId,
$or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }],
});
if (params.filterand.includes(shared_consts.FILTER_NASCOSTI))
filtriadded.push({
deleted: { $exists: true, $eq: true },
});
if (params.filterand.includes(shared_consts.FILTER_NAVI_NON_PRESENTI))
filtriadded.push({
navinonpresenti: { $exists: true, $eq: true },
$or: [{ subaccount: { $exists: false } }, { subaccount: { $exists: true, $eq: false } }],
});
// Iscritti Conacreis
if (params.filterand.includes(shared_consts.FILTER_REPORTED))
filtriadded.push({ reported: { $exists: true, $eq: true } });
if (params.filterand.includes(shared_consts.FILTER_TO_MAKE_MEMBERSHIP_CARD))
filtriadded.push({
$or: [{ codiceConacreis: { $exists: false } }, { codiceConacreis: { $exists: true, $eq: '' } }],
});
if (params.filterand.includes(shared_consts.FILTER_MEMBERSHIP_CARD_OK))
filtriadded.push({
codiceConacreis: { $exists: true },
$expr: { $gt: [{ $strLenCP: '$codiceConacreis' }, 0] },
});
}
if (params.filtercustom) {
params.filtercustom = this.sanitizzaHtml(params.filtercustom);
let condition = {};
for (const myfilter of params.filtercustom) {
if (myfilter['userId']) {
myfilter['userId'] = new ObjectId(myfilter['userId']);
}
if (myfilter['_idOBJ']) {
filtriadded.push({ _id: new ObjectId(myfilter['_idOBJ']) });
} else if (myfilter['dateTimeStart']) {
const gte = myfilter['dateTimeStart'].$gte;
const lte = myfilter['dateTimeStart'].$lte;
condition = {
dateTimeStart: {
$gte: new Date(gte),
$lte: new Date(lte),
},
};
filtriadded.push(condition);
} else if (myfilter.hasOwnProperty('pub_to_share')) {
// non aggiungere niente
} else {
filtriadded.push(myfilter);
}
}
}
if (params.filter_gte) {
params.filter_gte = this.sanitizzaHtml(params.filter_gte);
for (let ind = 0; ind < params.filter_gte.length; ind++) {
for (const [key, value] of Object.entries(params.filter_gte[ind])) {
if (value > 0) {
let condition = {};
condition[key] = { $gte: value };
filtriadded.push(condition);
}
}
}
}
if (params.filtersearch) {
params.filtersearch = this.sanitizzaHtml(params.filtersearch);
filtriadded.push(...params.filtersearch);
}
if (params.options) {
if (this.isBitActive(params.options, shared_consts.OPTIONS_SEARCH_ONLY_FULL_WORDS)) {
}
}
if (params.filterextra) {
params.filterextra = this.sanitizzaHtml(params.filterextra);
if (params.filterextra.length > 0) query = [...query, ...params.filterextra];
}
if (filtriadded) {
filtriadded = this.sanitizzaHtml(filtriadded);
if (filtriadded.length > 0) 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) {
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);
if (
params.querytype === shared_consts.QUERYTYPE_MYGROUP ||
params.querytype === shared_consts.QUERYTYPE_CIRCUIT
) {
const myq = this.addQueryIdMatch(params);
if (myq) query.push(myq);
query.push({ $project: { req_users: 1 } });
const qa1 = this.getLookup(
{
lk_tab: 'users',
lk_LF: 'req_users.username',
lk_FF: 'username',
lk_as: 'user',
},
0,
{
'user.idapp': 1,
'user.username': 1,
'user.name': 1,
'user.surname': 1,
'user.profile.img': 1,
'user.profile.qualifica': 1,
'user.profile.note': 1,
'profile.da_contattare': 1,
}
);
if (qa1) query = [...query, ...qa1];
query.push({ $unwind: '$user' });
query.push({
$match: {
$and: [{ 'user.idapp': params.idapp }],
},
});
query.push({
$replaceRoot: {
newRoot: '$user',
},
});
} else if (
params.querytype === shared_consts.QUERYTYPE_REFUSED_USER_GRP ||
params.querytype === shared_consts.QUERYTYPE_REFUSED_USER_CIRCUIT
) {
/*
const myq = this.addQueryIdMatch(params);
if (myq)
query.push(myq);
*/
const myq = this.addQueryIdMatch(params);
if (myq) query.push(myq);
query.push({ $project: { refused_users: 1 } });
query.push({ $unwind: '$refused_users' });
const qa1 = this.getLookupPipeLine(
{
lk_tab: 'users',
lk_LF: 'refused_users.username',
lk_FF: 'username',
lk_as: 'user',
idapp,
},
{
'user.idapp': 1,
'user.username': 1,
'user.name': 1,
'user.surname': 1,
'user.profile.img': 1,
'user.profile.qualifica': 1,
'user.profile.note': 1,
'profile.da_contattare': 1,
}
);
if (qa1) query = [...query, ...qa1];
query.push({ $unwind: '$user' });
/*
query.push({
$match: {
$and: [
{'user.idapp': params.idapp},
],
},
});
*/
query.push({
$replaceRoot: {
newRoot: '$user',
},
});
} else if (params.querytype === shared_consts.QUERYTYPE_GROUP_CIRCUIT) {
const myq = this.addQueryIdMatch(params);
if (myq) query.push(myq);
query.push({ $project: { req_groups: 1 } });
const qa1 = this.getLookup(
{
lk_tab: 'mygroups',
lk_LF: 'req_groups.groupname',
lk_FF: 'groupname',
lk_as: 'group',
},
0,
{
'group.idapp': 1,
'group.groupname': 1,
'group.photos': 1,
}
);
if (qa1) query = [...query, ...qa1];
query.push({ $unwind: '$group' });
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({
$replaceRoot: {
newRoot: '$group',
},
});
} else if (params.querytype === shared_consts.QUERYTYPE_REFUSED_GROUP_CIRCUIT) {
const myq = this.addQueryIdMatch(params);
if (myq) query.push(myq);
query.push({ $project: { refused_groups: 1 } });
query.push({ $unwind: '$refused_groups' });
const qa1 = this.getGroupnameLookupPipeLine(
{
lk_tab: 'mygroups',
lk_LF: 'refused_groups.groupname',
lk_FF: 'groupname',
lk_as: 'group',
idapp,
},
{
'group.idapp': 1,
'group.groupname': 1,
'group.descr': 1,
'group.photos': 1,
}
);
if (qa1) query = [...query, ...qa1];
query.push({ $unwind: '$group' });
/*
query.push({
$match: {
$and: [
{'user.idapp': params.idapp},
],
},
});
*/
query.push({
$replaceRoot: {
newRoot: '$group',
},
});
} else if (params.querytype === shared_consts.QUERYTYPE_LIST_MOVEMENTS) {
const { Movement } = require('../models/movement');
const myquery = await Movement.getQueryMovsByCircuitId(params.idapp, params.username, '', '', params.myid);
query.push(...myquery);
} else if (params.querytype === shared_consts.QUERYTYPE_LIST_MOVEMENTS_GROUPNAME) {
const { Movement } = require('../models/movement');
const myquery = await Movement.getQueryMovsByCircuitId(params.idapp, '', params.groupname, '', params.myid);
query.push(...myquery);
} else if (params.querytype === shared_consts.QUERYTYPE_LIST_MOVEMENTS_CONTOCOM) {
const { Movement } = require('../models/movement');
const myquery = await Movement.getQueryMovsByCircuitId(params.idapp, '', '', params.contocom, params.myid);
query.push(...myquery);
} else if (params.querytype === shared_consts.QUERYTYPE_LIST_ALLMOVEMENTS) {
const { Movement } = require('../models/movement');
const myquery = await Movement.getQueryAllUsersMovsByCircuitId(params.idapp, params.myid);
query.push(...myquery);
}
if (params.filterextra2) {
if (params.filterextra2.length > 0) query = [...query, ...params.filterextra2];
}
if (newvers) {
// NUOVA VERSIONE
let proj = params.lookup2 ? params.lookup2.lk_proj : null;
proj = this.sanitizzaProjection(proj);
if (params.proj0) {
query.push({ $project: params.proj0 });
}
if (params.unwind0) {
query.push({ $unwind: params.unwind0 });
}
let objadd = { query: [], proj: {} };
let numtab = this.getNumTabByTable(params.table);
const q1 = this.getLookup(params.lookup1, 1, proj, objadd.proj);
if (q1) query = [...query, ...q1];
if (params.unwind1) {
query.push({ $unwind: params.unwind1 });
}
if (params.lookupPipeline1) {
const q1p = this.getLookupStandardPipeline(params.lookupPipeline1, 1);
if (q1p) query = [...query, ...q1p];
}
params.lookup2 = this.sanitizzaLookup(params.lookup2);
params.lookup3 = this.sanitizzaLookup(params.lookup3);
params.lookup4 = this.sanitizzaLookup(params.lookup4);
params.lookup5 = this.sanitizzaLookup(params.lookup5);
const q2 = this.getLookup(params.lookup2, 2, proj, objadd.proj);
if (q2) query = [...query, ...q2];
if (params.lookupPipeline2) {
const q2p = this.getLookupStandardPipeline(params.lookupPipeline2, 2);
if (q2p) query = [...query, ...q2p];
}
const q3 = this.getLookup(params.lookup3, 3, proj, objadd.proj);
if (q3) query = [...query, ...q3];
const q4 = this.getLookup(params.lookup4, 4, proj, objadd.proj);
if (q4) query = [...query, ...q4];
const q5 = this.getLookup(params.lookup5, 5, proj, objadd.proj);
if (q5) query = [...query, ...q5];
if (params.filtersearch2) {
if (params.filtersearch2.length > 0) {
query.push({ $match: { $and: params.filtersearch2 } });
}
}
let filteradmin = false;
if (params.filtercustom) {
let condition = {};
for (const myfilter of params.filtercustom) {
if (!!myfilter.admins) {
filteradmin = true;
}
if (
myfilter['pub_to_share'] === shared_consts.PUBTOSHARE.ONLY_TABLE_FOLLOW &&
params.table === 'mygroups'
) {
let arraygroups = [];
if (user && user.profile.mygroups) {
arraygroups = user.profile.mygroups.map((rec) => rec.groupname);
}
// prendere i gruppi dell'utente
// Cerca tra i gruppi di ogni record, se combaciano almeno 1
condition = {
'profile.mygroups': {
$elemMatch: {
groupname: { $in: arraygroups },
},
},
};
query.push({ $match: { $and: [condition] } });
} else if (
myfilter['pub_to_share'] === shared_consts.PUBTOSHARE.ONLY_TABLE_FOLLOW &&
params.table === 'circuits'
) {
let arraycircuits = [];
if (user && user.profile.mycircuits) {
arraycircuits = user.profile.mycircuits.map((rec) => rec.circuitname);
}
// prendere i gruppi dell'utente
// Cerca tra i gruppi di ogni record, se combaciano almeno 1
condition = {
'profile.mycircuits': {
$elemMatch: {
circuitname: { $in: arraycircuits },
},
},
};
query.push({ $match: { $and: [condition] } });
} else if (shared_consts.TABLES_ENABLE_GETREC_BYID.includes(params.table)) {
// Rimuovi dalla query quelli non visibili
let arraygroups = [];
if (user && user.profile.mygroups) {
arraygroups = user.profile.mygroups.map((rec) => rec.groupname);
}
// prendere i gruppi dell'utente
// Cerca tra i gruppi di ogni record, se combaciano almeno 1
condition = {
'profile.mygroups': {
$elemMatch: {
groupname: { $in: arraygroups },
},
},
};
query.push({
$match: {
$or: [
{
$and: [condition, { pub_to_share: 1 }],
},
{
$or: [
{ pub_to_share: { $exists: false } },
{ pub_to_share: { $exists: true, $eq: shared_consts.PUBTOSHARE.ALL } },
],
},
],
},
});
}
}
}
if (params.table === shared_consts.TABLES_MYBACHECAS) {
const myq = this.getQueryMyBacheca(idapp);
query.push(myq[0]);
}
if (params.filtersearch3or) {
if (params.filtersearch3or.length > 0) {
query.push({ $match: { $or: params.filtersearch3or } });
}
}
if (params.filtersearch3and) {
if (params.filtersearch3and.length > 0) {
// Se c'è statusskill allora glielo metto in OR
if (
params.table === 'myskills' &&
params.filtersearch &&
!this.contieneIdStatusSkill(params.filtersearch)
) {
query.push({
$match: {
$or: [{ $and: params.filtersearch3and }, { idStatusSkill: { $in: [2] } }],
},
});
} else {
query.push({ $match: { $and: params.filtersearch3and } });
}
}
}
if (params.filter && params.fieldsearch_last) {
const querytemp = this.getFilterParam(params.filter, params.fieldsearch_last);
if (querytemp) {
query = [...query, ...querytemp];
}
// Save the search:
if (user._id) {
const mysearch = new Search({ idapp, userId: user._id, text: params.filter });
await mysearch.save();
}
}
if (params.table === 'mygroups' || params.table === 'circuits') {
// BINARY CHECK (?): const filter = [{ visibility: { $bitsAnyClear: [1] } }];
// if (!User.isAdmin(req.user.perm)) {
// not Visibility_Group.HIDDEN
if (!filteradmin) {
if (user) {
const filter = [
{
$or: [
{
visibility: {
$nin: [shared_consts.Visibility_Group.HIDDEN],
},
},
{
createdBy: {
$eq: user.username,
},
},
],
},
];
query.push({ $match: { $and: filter } });
} else {
const filter = [
{
visibility: {
$nin: [shared_consts.Visibility_Group.HIDDEN],
},
},
];
query.push({ $match: { $and: filter } });
}
}
// }
}
if (params.options && this.isBitActive(params.options, shared_consts.OPTIONS_ADD_COUNT_FAVORITE)) {
// objadd = this.addNumFavoriteAndBookmarkToQuery(idapp, numtab);
// if (Object.keys(objadd.query).length > 0)
// query = [...query, ...objadd.query];
}
} else {
// VECCHIA VERSIONE
const q1 = this.getLookup(params, 1);
if (q1) query = [...query, ...q1];
}
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);
// console.table(mysort);
query.push(mysort);
}
query.push(
{
$group: {
_id: null,
// get a count of every result that matches until now
count: { $sum: 1 },
// keep our results for the next operation
results: { $push: '$$ROOT' },
},
}
// and finally trim the results to within the range given by start/endRow
);
if (projectEnd) {
query.push({
$project: {
count: 1,
rows: projectEnd,
},
});
}
if (this.testing()) {
// console.log('query', query);
}
//console.log('query', query);
return query;
} catch (e) {
console.error('Err query:', e);
}
},
startTimeLog(name) {
if (this.testing()) {
// console.log('inizio', name);
try {
console.time(name);
} catch (e) {}
}
},
endTimeLog(name) {
if (this.testing()) {
// console.log(' ... fine', name);
console.timeEnd(name);
}
},
async executeQueryTable(mythistable, idapp, params, user) {
let query = await this.getQueryTable(idapp, params, user);
try {
// console.log('query', query);
this.startTimeLog('Query 1');
const [ris] = await mythistable.aggregate(query);
if (ris) {
if (params.table === 'users') {
for (const myrec of ris.rows) {
if (myrec.ipaddr) myrec.ipaddr = '';
if (myrec.tokens) myrec.tokens = [];
if (myrec.password) myrec.password = '';
}
} else if (params.table === 'mygroups') {
for (const myrec of ris.rows) {
if (myrec.pwd_cryp) myrec.pwd_cryp = '';
}
}
this.endTimeLog('Query 1');
// console.table(ris.rows);
// console.log('ROW ', ris.count);
return { count: ris.count, rows: ris.rows };
} else {
return { count: 0, rows: [] };
}
} catch (e) {
console.log('error', e);
}
},
async DuplicateAllRecords(mythistable, idapporig, idappdest) {
console.log(mythistable.name);
const numrec = await mythistable.findAllIdApp(idappdest).then((arrrec) => {
if (arrrec && arrrec.length > 1) {
return arrrec.length; // Has Already set
} else {
return 0;
}
});
// Before check if exist more than 1 record in the destination,
// if Yes don't copy
if (numrec <= 0) {
return await mythistable.findAllIdApp(idapporig).then(async (arrrec) => {
let num = 0;
for (let ind = 0; ind < arrrec.length; ind++) {
let newrec = new mythistable(arrrec[ind]);
newrec._id = new ObjectId();
newrec.idapp = idappdest;
try {
const rec = await newrec.save();
if (rec) {
num++;
}
} catch (e) {
console.error('e', e);
}
}
return num;
});
}
},
isBitActive(bit, whattofind) {
return (bit & whattofind) === whattofind;
},
isBitAttivoESelez(bit, whattofind, loSono) {
const abil = this.isBitActive(bit, whattofind);
return (abil && loSono) || !abil;
},
SetBit(myval, bit) {
let myvalout = myval;
myvalout |= bit;
return myvalout;
},
async snooze(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
},
IncDateNow(secs) {
let mydate = new Date(new Date().getTime() + secs);
// console.log('mydate', mydate);
return mydate;
},
isdiffSecDateLess(mydatediffstr, secs) {
let mydate = new Date();
// console.log('mydate', mydate);
let mydata2 = new Date(mydatediffstr);
let ris = (mydate.getTime() - mydata2.getTime()) / 1000;
return ris < secs;
},
AddDate(mydate, days) {
let date = new Date(mydate);
date.setTime(date.getTime() + days * 86400000);
return date;
},
isMonToSat() {
const dayOfWeek = new Date(new Date()).getDay();
return dayOfWeek >= 1 && dayOfWeek <= 6;
},
isMonToFri() {
const dayOfWeek = new Date(new Date()).getDay();
return dayOfWeek >= 1 && dayOfWeek <= 5;
},
// var startTime = '15:10:10';
// var endTime = '22:30:00';
isBetweenTwoTime(startTime, endTime) {
currentDate = new Date();
startDate = new Date(currentDate.getTime());
startDate.setHours(startTime.split(':')[0]);
startDate.setMinutes(startTime.split(':')[1]);
startDate.setSeconds(startTime.split(':')[2]);
endDate = new Date(currentDate.getTime());
endDate.setHours(endTime.split(':')[0]);
endDate.setMinutes(endTime.split(':')[1]);
endDate.setSeconds(endTime.split(':')[2]);
valid = startDate < currentDate && endDate > currentDate;
return valid;
},
getlimiti(mypos) {
if (mypos.col < 0) {
mypos.col = 0;
}
if (mypos.riga < 0) {
mypos.riga = 0;
mypos.col = 0;
}
return mypos;
},
getRigaColByPosUp(mypos) {
if (mypos.numup > 0) {
mypos.riga = mypos.riga - mypos.numup;
mypos.col = Math.ceil(mypos.col / Math.pow(2, mypos.numup));
}
if (mypos.numup < 0) {
mypos.riga = mypos.riga - mypos.numup;
mypos.col = Math.ceil(mypos.col * Math.pow(2, -mypos.numup));
}
if (mypos.riga < 1) {
mypos.riga = 1;
}
if (mypos.col < 1) {
mypos.col = 1;
}
},
getRigaColGenerica(idapp, riga, col, numup) {
mypos = {
idapp,
riga,
col,
numup,
};
if (idapp === this.AYNI) {
this.getRigaColByPosUp(mypos);
ris = this.getlimiti(mypos);
}
return ris;
},
getRigaColSognatoreByDonatore(idapp, riga, col) {
return this.getRigaColGenerica(idapp, riga, col, 6);
},
getRigaColMediatoreByFuoco(idapp, riga, col) {
return this.getRigaColGenerica(idapp, riga, col, 3);
},
getRigaColSognatoreByMediatore(idapp, riga, col) {
return this.getRigaColGenerica(idapp, riga, col, 3);
},
appendLeadingZeroes(n) {
if (n <= 9) {
return '0' + n;
}
return n;
},
getWeekDayByLangByNumCar(date, lang, num) {
if (!lang) lang = 'it';
const dayOfWeek = new Date(date).getDay();
const myday = {
it: ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'],
enUs: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
fr: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
es: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'iernes', 'Sábado'],
pt: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'],
de: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
si: ['Nedelja', 'Ponedeljek', 'Torek', 'Sreda', 'četrtek', 'Petek', 'Sobota'],
};
if (num > 0) {
return isNaN(dayOfWeek) ? '' : myday[lang][dayOfWeek].substring(0, num);
} else {
return isNaN(dayOfWeek) ? '' : myday[lang][dayOfWeek];
}
},
isSunday(mydate) {
const dayOfWeek = new Date(mydate).getDay();
return dayOfWeek === 0;
},
isMonday(mydate) {
const dayOfWeek = new Date(mydate).getDay();
return dayOfWeek === 1;
},
isSundayDate(mydate) {
const dayOfWeek = mydate.getDay();
return dayOfWeek === 0;
},
isMondayDate(mydate) {
const dayOfWeek = mydate.getDay();
return dayOfWeek === 1;
},
getWeekDayByLang(date, lang) {
return this.getWeekDayByLangByNumCar(date, lang, 3);
},
getWeekDayByLangTot(date, lang) {
return this.getWeekDayByLangByNumCar(date, lang, 0);
},
getWeekDay(date) {
//Create an array containing each day, starting with Sunday.
const weekdays = ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedí', 'Venerdì', 'Sabato'];
//Use the getDay() method to get the day.
const day = date.getDay();
//Return the element that corresponds to that index.
return weekdays[day];
},
getstrDateTimeShort(mydate, lang) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
this.getWeekDayByLang(mydate, lang) +
' ' +
this.appendLeadingZeroes(mydate.getDate()) +
'/' +
this.appendLeadingZeroes(mydate.getMonth() + 1) +
' ORE ' +
this.appendLeadingZeroes(mydate.getHours()) +
':' +
this.appendLeadingZeroes(mydate.getMinutes())
);
} else {
return '';
}
},
getstrTime(mytimestamp) {
// Create a Date object with your desired date
const date = new Date(mytimestamp); // You can replace this with your specific date
// Get the hour and minute components from the date
const hours = date.getHours();
const minutes = date.getMinutes();
// Format the hour and minute components as HH:MM
const formattedTime = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
return formattedTime;
},
getstrDateShort(mydate, lang) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
this.getWeekDayByLang(mydate, lang).substring(0, 3) +
' ' +
this.appendLeadingZeroes(mydate.getDate()) +
'/' +
this.appendLeadingZeroes(mydate.getMonth() + 1)
);
} else {
return '';
}
},
getstrDate_DD_MM_YYYY(mydate) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
this.appendLeadingZeroes(mydate.getDate()) +
'/' +
this.appendLeadingZeroes(mydate.getMonth() + 1) +
'/' +
this.appendLeadingZeroes(mydate.getFullYear())
);
} else {
return '';
}
},
getstrDateYYYY_MM_DD(mydate) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
mydate.getFullYear() +
'-' +
this.appendLeadingZeroes(mydate.getMonth() + 1) +
'-' +
this.appendLeadingZeroes(mydate.getDate())
);
} else {
return '';
}
},
getstrUTCDateYYYY_MM_DD(mydate) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
mydate.getUTCFullYear() +
'-' +
this.appendLeadingZeroes(mydate.getUTCMonth() + 1) +
'-' +
this.appendLeadingZeroes(mydate.getUTCDate())
);
} else {
return '';
}
},
getstrDateLong(mydate, lang) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
this.getWeekDayByLang(mydate, lang) +
' ' +
this.appendLeadingZeroes(mydate.getDate()) +
'/' +
this.appendLeadingZeroes(mydate.getMonth() + 1) +
'/' +
mydate.getFullYear()
);
} else {
return '';
}
},
getstrDateLongTot(mydate, lang) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
this.getWeekDayByLangTot(mydate, lang) +
' ' +
this.appendLeadingZeroes(mydate.getDate()) +
'/' +
this.appendLeadingZeroes(mydate.getMonth() + 1) +
'/' +
mydate.getFullYear()
);
} else {
return '';
}
},
getstrDateLongFile(mydate, lang) {
if (mydate) {
// console.log('getstrDate', mytimestamp)
return (
mydate.getFullYear() +
'-' +
this.appendLeadingZeroes(mydate.getMonth() + 1) +
'-' +
this.appendLeadingZeroes(mydate.getDate()) +
' (' +
this.getWeekDayByLang(mydate, lang) +
')'
);
} else {
return '';
}
},
getlinkzoom(rec) {
if (rec === null) {
rec = {
typeconf: this.TYPECONF_ZOOM,
id_conf_zoom: '',
};
}
let typeconf = rec.typeconf;
if (typeconf === '') typeconf = this.TYPECONF_ZOOM;
let mylink = 'https://zoom.us/j/';
if (typeconf === this.TYPECONF_JITSI) mylink = 'https://meet.jit.si/';
if (rec.id_conf_zoom === '') {
rec.id_conf_zoom = '6668882000';
}
return mylink + rec.id_conf_zoom;
},
getmd5(mystr) {
return CryptoJS.MD5(mystr ? mystr.toLowerCase() : '').toString();
},
getHash(mystr) {
return CryptoJS.SHA512(mystr, { outputLength: 256 }).toString();
},
encrypt(msg, pass) {
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
// Deriva la chiave usando PBKDF2
const key = CryptoJS.PBKDF2(pass, salt, {
keySize: keySize / 32,
iterations: iterations,
});
// Critta il messaggio
const encrypted = CryptoJS.AES.encrypt(msg, key, {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC,
});
// 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) {
try {
let saltHex, ivHex, encrypted;
// 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);
}
// Converte salt e IV da esadecimale
const salt = CryptoJS.enc.Hex.parse(saltHex);
const iv = CryptoJS.enc.Hex.parse(ivHex);
// 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 '';
// Encrypt
//return CryptoJS.AES.encrypt(JSON.stringify(mydata), process.env.SECRK);
return this.encrypt(mydata, process.env.SECRK);
},
decryptdata(mydatacrypted) {
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 '';
}
},
BoolToInt(mybool) {
return mybool ? -1 : 0;
},
StrToBool(mystr) {
return mystr === '-1' ? true : false;
},
writelogfile(mystr, filename) {
// fs.appendFile(FILELOG, mystr, function (err) {
// if (err) throw err;
// console.log('Saved!');
// });
try {
mystr = this.getstrDateTimeShort(new Date(), 'it') + ': ' + mystr;
const stream = fs.createWriteStream(filename, { flags: 'a' });
stream.write('\n' + mystr);
stream.end();
} catch (e) {}
},
async readlogfile(idapp, filename) {
try {
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);
},
writeEventsLog(mystr) {
this.writelogfile(mystr, FILEEVENTS);
},
writeManagersLog(mystr) {
this.writelogfile(mystr, FILEMANAGERS);
},
writeTransactionLog(mystr) {
this.writelogfile(mystr, FILETRANSACTION);
},
writeErrorLog(mystr) {
this.writelogfile(mystr, FILEERRLOGIN);
},
writeSostituzioniLog(mystr) {
this.writelogfile(mystr, FILESOSTITUZIONI);
},
writeIPToBan(mystr) {
this.writelogfile(mystr, FILEIP_TO_BAN);
},
writeFlottaLog(idapp, mystr, riga, col) {
this.mkdirpath(idapp + '/');
this.writelogfile(mystr, idapp + '/' + riga + '_' + col + '.txt');
},
writeNaveLog(mystr) {
this.writelogfile(mystr, FILENAVE);
},
async copyFile(src, dest) {
return new Promise((resolve, reject) => {
const readStream = fs.createReadStream(src);
const writeStream = fs.createWriteStream(dest);
readStream.on('error', reject);
writeStream.on('error', reject);
writeStream.on('finish', resolve);
readStream.pipe(writeStream);
});
},
/**
* Sposta un file da oldPath a newPath.
* Se rename fallisce con EXDEV (diverso device), fa copia + delete.
* Se la cartella di destinazione non esiste, la crea.
* @param {string} oldPath
* @param {string} newPath
* @param {(err?: Error) => void} [callback] - opzionale, se non passato ritorna Promise
*/
async move(oldPath, newPath, callback) {
const moveOp = async () => {
// Assicurati che la cartella di destinazione esista
const dir = path.dirname(newPath);
await fs.promises.mkdir(dir, { recursive: true });
try {
const newOldPath = oldPath.replace(/\/$/, '');
const newNewPath = newPath.replace(/\/$/, '');
await fs.promises.rename(newOldPath, newNewPath);
console.log(`File spostato: ${oldPath} -> ${newPath}`);
} catch (err) {
if (err.code === 'EXDEV') {
// Spostamento tra device diversi: copia + elimina
await copyFile(oldPath, newPath);
await fs.promises.unlink(oldPath);
console.log(`File copiato e cancellato: ${oldPath} -> ${newPath}`);
} else if (err.code === 'ENOENT') {
throw new Error(`File non trovato: ${oldPath}`);
} else {
throw err;
}
}
};
if (callback && typeof callback === 'function') {
moveOp()
.then(() => callback())
.catch(callback);
} else {
return moveOp();
}
},
copy(oldPath, newPath, callback) {
fs.copyFile(oldPath, newPath, (err) => {
if (err) throw err;
// console.log('source.txt was copied to destination.txt');
});
},
extractFileName: function (filename) {
return path.basename(filename);
},
extractFilePath: function (filename) {
return path.dirname(filename);
},
async deleteFile(filePath) {
try {
await fs.promises.unlink(filePath);
// console.log(`File eliminato con successo: ${filePath}`);
} catch (err) {
console.error(`Errore durante l'eliminazione del file: ${filePath}`, err);
throw err;
}
},
async delete(mypath, alsothumb, callback) {
try {
if (await this.isFileExistsAsync(mypath)) {
await fs.promises.unlink(mypath);
// console.log(`deleted file ${mypath}`);
if (alsothumb) {
let img_small = '';
try {
img_small = path.dirname(mypath) + '/' + server_constants.PREFIX_IMG_SMALL + path.basename(mypath);
if (await this.isFileExistsAsync(img_small)) {
await fs.promises.unlink(img_small);
console.log(`deleted file ${img_small}`);
} else {
// console.warn(`File not found: ${img_small}`);
}
console.log(`deleted file ${img_small}`);
} catch (e) {
console.error(`Error deleting file ${img_small}`, e?.message);
}
}
}
} catch (e) {
console.error(`Error deleting file ${mypath}`, e?.message);
callback(e);
return;
}
callback();
},
async mkdirpath(dirPath) {
try {
if (!(await this.isFileExistsAsync(dirPath))) {
fs.mkdirSync(dirPath, { recursive: true });
}
} catch (e) {
if (dirPath !== path.dirname(dirPath)) {
const myname = path.dirname(dirPath);
await this.mkdirpath(myname);
// this.mkdirpath(dirPath);
}
}
},
getNomeCognomeTelegram(msg) {
if (msg && msg.chat) {
let nomecognome = msg.chat.first_name ? msg.chat.first_name : '';
nomecognome += msg.chat.last_name ? ' ' + msg.chat.last_name : '';
return nomecognome;
}
return '';
},
extractNameAndSurnameByComplete(name_complete) {
const suffissoCognome = ['Del', 'La', 'De', 'Lo'];
let campi = name_complete.split(' ');
let namesurname = {
name: '',
surname: '',
};
if (campi.length === 2) {
namesurname.name = campi[0];
namesurname.surname = campi[1];
} else if (campi.length === 3) {
if (suffissoCognome.includes(campi[1])) {
namesurname.name = campi[0];
namesurname.surname = campi[1] + ' ' + campi[2];
} else {
namesurname.name = campi[0] + ' ' + campi[1];
namesurname.surname = campi[2];
}
} else if (campi.length === 4) {
namesurname.name = campi[0] + ' ' + campi[1];
namesurname.surname = campi[2] + ' ' + campi[3];
} else if (campi.length > 4) {
namesurname.name = campi[0] + ' ' + campi[1];
namesurname.surname = ' ' + campi[2];
for (let ind = 3; ind < campi.length; ind++) {
namesurname.surname += ' ' + campi[ind];
}
}
return namesurname;
},
getiPAddressUser(req) {
try {
const striniziale = '::ffff:';
if (req.ip.indexOf(striniziale) >= 0) {
return req.ip.substring(striniziale.length);
} else {
return req.ip; // Express
}
} catch (e) {
return '';
}
},
removespaces(mystr) {
return mystr.replace(/\s+/g, '');
},
async ModificheConsentite(req, table, fieldsvalue, idrec, user) {
const { Circuit } = require('../models/circuit');
if (table === 'sharewithus') {
return true;
}
if (table === 'hours') {
return true;
}
if (table === 'users') {
if (idrec && req.user._id.toString() === idrec) {
if (Object.keys(fieldsvalue).some((key) => key.startsWith('profile.'))) {
return true;
}
if (Object.keys(fieldsvalue).some((key) => server_constants.User_Fields.includes(key))) {
return true;
}
}
if ('aportador_solidario' in fieldsvalue) {
return true;
}
if ('ALL' in fieldsvalue) {
//++Todo: Cancellalo solo se sono io il creatore dell'utente ... o se posso!
return true;
}
} else if (table === 'circuits') {
if (idrec) {
// Permetti di fare modifiche se è un admin del circuito
return await Circuit.isCircuitAdmin(idrec, req.user ? req.user.username : '');
}
} else if (table === 'accounts') {
if (idrec) {
if ('fidoConcesso' in fieldsvalue) {
// Permetti di fare modifiche se è un admin del circuito
return await Circuit.isCircuitAdmin(idrec, req.user ? req.user.username : '');
}
}
}
if (shared_consts.TABLES_PERM_CHANGE_FOR_USERS.includes(table)) {
return true;
}
if (shared_consts.TABLES_PERM_NEWREC.includes(table)) {
return true;
}
return false;
},
NotifyIfDelRecord(table) {
if (table === 'users' || table === 'extralist' || table === 'groups' || table === 'graduatorias') {
return true;
}
return false;
},
getFirstWord(mystr) {
const myarr = mystr.split(' ');
if (myarr.length > 0) return myarr[0];
else return mystr;
},
getFirst2Car(mystr) {
if (!!mystr) return mystr.substring(0, 2) + '.';
else return '';
},
getmaxcol(riga) {
return Math.pow(2, riga - 1);
},
getPrimoFuocoByIndCol(col) {
// let ris = Math.ceil(col - (col % 8)) + 1;
let ris = (Math.ceil(col / 8) - 1) * 8 + 1;
if (ris <= 0) ris = 1;
return ris;
},
getPrimaColFlotta(col) {
// let ris = Math.ceil(col - (col % 8)) + 1;
let ris = (Math.ceil(col / 64) - 1) * 64 + 1;
if (ris <= 0) ris = 1;
return ris;
},
getStrMsgByTipoMsg(tipomsg) {
let mystr = '';
if (tipomsg === this.TipoMsg.SEND_MSG_EFFETTUA_IL_DONO)
mystr = 'Inviato Messaggio per Effettuare il Dono a Tutta la Flotta';
else if (tipomsg === this.TipoMsg.SEND_MSG_SOLLECITO_DONATORI_NO_DONO)
mystr = "Inviato Messaggio per RICORDARE di Effettuare il Dono a chi ancora non l'ha fatto";
else if (tipomsg === this.TipoMsg.SEND_MSG_A_MEDIATORI) mystr = 'Inviato Messaggio ai Mediatori';
else if (tipomsg === this.TipoMsg.SEND_MSG_A_SOGNATORE) mystr = 'Inviato Messaggio al Sognatore';
else if (tipomsg === this.TipoMsg.SEND_MSG_A_UTENTE_SOSTITUITO) mystr = "Inviato Messaggio all'utente Sostituito";
else if (tipomsg === this.TipoMsg.SEND_MSG_DONO_RICEVUTO_CORRETTAMENTE)
mystr = 'Inviato Messaggio Dono Ricevuto Correttamente';
return mystr;
},
getflagtelegrambyLang(lang) {
if (lang === 'it') return '🇮🇹';
else if (lang === 'si') return '🇸🇮';
else if (lang === 'es') return '🇪🇸';
else if (lang === 'enUs') return '🇬🇧';
else if (lang === 'uk') return '🇬🇧';
else if (lang === 'fr') return '🇫🇷';
},
blockwords(mystr) {
const arrwords = ['http', 'Http', 'Asasfasfas', '://', 'mrbit', 'admin', 'superuser'];
try {
for (const myword of arrwords) {
if (mystr) {
if (mystr.includes(myword)) {
return true;
}
}
}
} catch (e) {}
return false;
},
isAlphaNumeric(str) {
let code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (
!(code > 47 && code < 58) && // numeric (0-9)
!(code > 64 && code < 91) && // upper alpha (A-Z)
!(code > 96 && code < 123)
) {
// lower alpha (a-z)
return false;
}
}
return true;
},
isAlphaNumericAndSpecialCharacter(str) {
let code, i, len;
for (i = 0, len = str.length; i < len; i++) {
code = str.charCodeAt(i);
if (
!(code > 47 && code < 58) && // numeric (0-9)
!(code > 63 && code < 91) && // upper alpha (A-Z) // e @
code !== 46 && // . (punto)
code !== 95 && // _
code !== 45 && // -
!(code > 96 && code < 123)
) {
// lower alpha (a-z)
return false;
}
}
return true;
},
categorizeQueryString(queryObj) {
let query = {};
let order = {};
//extract query, order, filter value
for (const i in queryObj) {
if (queryObj[i]) {
// extract order
if (i === 'order') {
order['sort'] = queryObj[i];
continue;
}
// extract range
if (i === 'range') {
let range_arr = [];
let query_arr = [];
// multi ranges
if (queryObj[i].constructor === Array) {
for (const r of queryObj[i]) {
range_arr = r.split('-');
query_arr.push({
price: { $gt: range_arr[0], $lt: range_arr[1] },
});
}
}
// one range
if (queryObj[i].constructor === String) {
range_arr = queryObj[i].split('-');
query_arr.push({
price: { $gt: range_arr[0], $lt: range_arr[1] },
});
}
Object.assign(query, { $or: query_arr });
delete query[i];
continue;
}
query[i] = queryObj[i];
}
}
return { query, order };
},
dateToEpoch(thedate) {
const time = new Date(thedate).getTime();
return time - (time % 86400000);
},
dateToEpochStr(thedate) {
const time = new Date(thedate).getTime();
return new Date(time - (time % 86400000));
},
async loadApps() {
const Site = require('../models/site');
try {
this.MYAPPS = await Site.findAll(0);
// console.log('this.MYAPPS', this.MYAPPS);
} catch (e) {
console.error('loadApps', e);
}
},
async getApps() {
if (this.MYAPPS.length <= 0) await this.loadApps();
return this.MYAPPS;
},
getPaymentTypesById(idmetodo) {
return shared_consts.PaymentTypes[idmetodo];
},
getVersionint(versionstr) {
let versionarr = versionstr.split('.');
let version = 0;
versionarr = versionarr.reverse();
for (let i = 0; i < versionarr.length; i++) {
version += versionarr[i] * Math.pow(10, i * 2);
}
return parseInt(version);
},
convstrToInt(mystr) {
try {
const parsed = parseInt(mystr, 10); // Specifica la base come 10
return isNaN(parsed) ? 0 : parsed; // Restituisce 0 se il valore è NaN
} catch (e) {
return 0; // Se c'è un errore, restituisce 0
}
},
isValidNumber(value) {
// Controlla se il valore è un numero valido
return !isNaN(value) && value !== null && value !== '';
},
invertescapeslash(mystr) {
return mystr.replace(/Ç/g, '/');
},
isNumber(n) {
return typeof n != 'boolean' && !isNaN(n) && n;
},
getNumObj(obj) {
let count = 0;
for (let properties in obj) {
count = count + 1;
}
return count;
},
getNomeCognomeEUserNameByUser(user) {
let nome = `${user.name} ${user.surname} (${user.username})`;
if (!user.name) {
nome = user.username;
}
return nome;
},
sulServer() {
return process.env.LOCALE !== '1';
},
refreshAllTablesInMem(idapp, table, updatebot, username) {
const telegrambot = require('../telegram/telegrambot');
if (table === shared_consts.TAB_BOTS || updatebot) {
telegrambot.reloadMenuBot(idapp);
}
if (table === shared_consts.TAB_USERS) {
telegrambot.deleteRecInMemByUsername(idapp, username);
} else if (table === shared_consts.TAB_SITES) {
telegrambot.reloadSites();
}
},
downloadImage(url, filepath) {
const download = require('image-downloader');
try {
return download.image({
url,
dest: filepath,
});
} catch (e) {
console.error('Err download image', e);
return false;
}
},
async checkStr(msg, mystr, user, cmd) {
if (msg.includes(mystr)) {
if (cmd === 1) {
msg = msg.replace(mystr, await this.getTimeExpReg(user.idapp, user.username));
}
}
return msg;
},
getUnsubsribeUrl(mylocalsconf) {
if (mylocalsconf) {
const baseurl = this.getHostByIdApp(mylocalsconf.idapp);
const urlunsibscribe =
baseurl +
'/unsubscribe?em=' +
mylocalsconf.hashemail +
'&mc=' +
mylocalsconf.dataemail.mailchimpactive +
'&email=' +
mylocalsconf.emailto;
return urlunsibscribe;
}
return '';
},
getUnsubsribeUrl_User(user) {
if (user && user.email) {
const hash = this.getHash(user.email + user.username);
return this.getHostByIdApp(user.idapp) + '/unsubscribe_user?em=' + hash + '&email=' + user.email;
}
return '';
},
async convertSpecialTags(user, msg) {
try {
if (!msg) return msg;
if (!!user) {
if (msg.includes('{host}')) {
msg = msg.replace('{host}', this.getHostByIdApp(user.idapp));
}
if (msg.includes('{appname}')) msg = msg.replace('{appname}', this.getNomeAppByIdApp(user.idapp));
msg = msg.replace('{username}', user.username);
// msg = await this.checkStr(msg, '{time_exp_reg}', user, 1);
msg = msg.replace('{name}', user.name ? user.name : user.username);
msg = msg.replace('{surname}', user.surname ? user.surname : '');
msg = msg.replace('{urlunsubscribe_user}', this.getUnsubsribeUrl_User(user));
msg = msg.replace('{aportador_solidario}', user.aportador_solidario ? user.aportador_solidario : '');
if (!!user.profile.link_payment) msg = msg.replace('{link_paypalme}', user.profile.link_payment);
if (!!user.profile.revolut) msg = msg.replace('{revolut}', user.profile.revolut);
if (!!user.profile.payeer_id) msg = msg.replace('{payeer_id}', user.profile.payeer_id);
if (!!user.profile.advcash_id) msg = msg.replace('{advcash_id}', user.profile.advcash_id);
if (!!user.profile.email_paypal) msg = msg.replace('{email_paypal}', user.profile.email_paypal);
if (!!user.profile.note_payment) msg = msg.replace('{note_payment}', user.profile.note_payment);
}
// const cl = getclTelegByidapp(user.idapp);
msg = msg.replace('{link_chathelp}', this.HELP_CHAT);
} catch (e) {
console.log(e);
}
return msg;
},
getUserInfoMsg: function (idapp, myuser, usernametelegram = '', name_telegram = '', surname_telegram = '') {
let msg = '';
try {
const name = myuser.username + (myuser.name ? ` (${myuser.name} ${myuser.surname})` : '');
const linkuserprof = this.getHostByIdApp(idapp) + '/my/' + myuser.username;
msg = `<br>👉🏻 <a href="${linkuserprof}">${name}</a><br>email: ${myuser.email}`;
let u_tg =
myuser.profile && myuser.profile.hasOwnProperty('username_telegram')
? myuser.profile.username_telegram
: usernametelegram;
let name_tg =
myuser.profile && myuser.profile.hasOwnProperty('firstname_telegram')
? myuser.profile.firstname_telegram
: name_telegram;
let surname_tg =
myuser.profile && myuser.profile.hasOwnProperty('lastname_telegram')
? myuser.profile.lastname_telegram
: surname_telegram;
let namesurnametg = '';
if (name_tg || surname_tg) namesurnametg = ` [${name_tg} ${surname_tg}]`;
if (u_tg) {
msg += `<br><br>Apri chat 👉🏻 https://t.me/${u_tg}`;
}
} catch (e) {
console.error('getUserInfoMsg', e);
}
return msg;
},
getUserShortInfoMsg: function (idapp, myuser, usernametelegram = '', name_telegram = '', surname_telegram = '') {
let msg = '';
try {
const name = myuser.username + (myuser.name ? ` (${myuser.name} ${myuser.surname})` : '');
const linkuserprof = this.getLinkUserProfile(idapp, myuser.username);
let u_tg =
myuser.profile && myuser.profile.hasOwnProperty('username_telegram')
? myuser.profile.username_telegram
: usernametelegram;
msg = `<br>Vedi Profilo sulla APP di <a href="${linkuserprof}">${name}</a>`;
msg += `<br>Telegram: @${u_tg}`;
} catch (e) {
console.error('getUserInfoMsg', e);
}
return msg;
},
getlinkRelativeRequestNewPassword: function (idapp, email, tokenforgot) {
const strlinkreg = process.env.LINK_UPDATE_PASSWORD + `?idapp=${idapp}&email=${email}&tokenforgot=${tokenforgot}`;
return strlinkreg;
},
getlinkRequestNewPassword: function (idapp, email, tokenforgot) {
const strlinkreg = this.getHostByIdApp(idapp) + this.getlinkRelativeRequestNewPassword(idapp, email, tokenforgot);
return strlinkreg;
},
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 sock = false;
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;
} else if (paramstr === 'SOCK') {
sock = value ? value.toLowerCase() === 'true' : false;
}
}
}
}
} 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, sock });
}
}
resolve({ error, stdout, stderr, arrout });
});
});
},
execScriptNoOutput: function (script) {
return new Promise((resolve, reject) => {
console.log('execScriptNoOutput:', script);
exec(script, (error, stdout, stderr) => {
if (error) {
console.error(`Exec error: ${error.message}`);
return reject(error);
}
if (stderr) {
console.warn(`Stderr (non bloccante): ${stderr}`);
}
resolve(true);
});
});
},
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');
const idchat = msg.chat.id;
console.log(testo + ' (' + script + ')');
telegrambot.local_sendMsgTelegramByIdTelegram(idapp, idchat, testo);
exec(script, (error, stdout, stderr) => {
if (error) {
telegrambot.local_sendMsgTelegramByIdTelegram(idapp, idchat, 'ERROR: ' + error.message);
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
telegrambot.local_sendMsgTelegramByIdTelegram(idapp, idchat, 'ERROR: ' + stderr);
console.log(`stderr: ${stderr}`);
return;
}
// console.log(` ... stdout: ${stdout}`);
telegrambot.local_sendMsgTelegramByIdTelegram(idapp, idchat, stdout);
});
},
capitalize(value) {
if (!value) {
return '';
}
const myval = value.toString();
return myval.charAt(0).toUpperCase() + myval.slice(1);
},
truncateString(str, maxLength) {
if (str.length > maxLength) {
return str.slice(0, maxLength) + '...';
} else {
return str;
}
},
removeFileExtension(filename) {
// Trova l'ultima occorrenza del punto nel nome del file
const lastDotIndex = filename.lastIndexOf('.');
// Se non c'è un punto o il punto è all'inizio del nome file,
// restituisci il nome file originale
if (lastDotIndex === -1 || lastDotIndex === 0) {
return filename;
}
// Altrimenti, restituisci la parte del nome file prima dell'ultimo punto
return filename.substring(0, lastDotIndex);
},
removeSpanAndDivTags(text) {
// Rimozione dei tag <span> e </span> dalla stringa di testo
const spanRegex = /<span[^>]*>|<\/span>/gi;
const cleanedText = text.replace(spanRegex, '');
// Rimozione dei tag <div> e </div> dalla stringa di testo
const divRegex = /<div[^>]*>|<\/div>/gi;
const finalText = cleanedText.replace(divRegex, '');
return finalText;
},
firstchars(value, numchars = 200, continua, link) {
if (!value) {
return '';
}
try {
value = this.convertHTMLTagsForTelegram(value);
value = this.removeSpanAndDivTags(value);
truncatedValue = this.truncateString(value, numchars);
if (str.length < maxLength) {
continua = false;
}
// Aggiungi il testo aggiuntivo per indicare il troncamento
if (continua) {
if (link) {
truncatedValue += `<em> (... <a href="${link}">continua sulla App</a>)</em>`;
} else {
truncatedValue += `<em> (... continua sulla App)</em>`;
}
} else {
truncatedValue += ' ...';
}
return truncatedValue;
} catch (e) {
return value;
}
},
removeFontTags(text) {
// Rimozione dei tag <font> e </font> dalla stringa di testo
const regex = /<font[^>]*>|<\/font>/gi;
const cleanedText = text.replace(regex, '');
return cleanedText;
},
removeAtChar(mystr) {
if (mystr && mystr[0] === '@') {
return (mystr = mystr.substring(1));
}
return mystr;
},
updateQueryStringParameter(uri, key, value) {
if (uri === '' || !uri) return '';
var re = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
if (uri.match(re)) {
return uri.replace(re, '$1' + key + '=' + value + '$2');
} else {
return uri + separator + key + '=' + value;
}
},
isArray(val) {
return Array.isArray(val);
},
getContentByTypeMsg(typemsg) {},
getContentNotifByParams(params, content, typesend) {
if (typesend === shared_consts.TypeSend.TELEGRAM) {
let myhost = this.getHostByIdApp(params.idapp);
if (params.textaddTelegram) {
content = content + '\n' + params.textaddTelegram;
}
if (params.linkaddTelegram) {
if (params.openUrl)
content = content + '\n' + '<a href="' + myhost + params.openUrl + '">' + params.linkaddTelegram + '</a>';
}
/*if (params.openUrl)
content = content + '\n' + '<a href="' + myhost + params.openUrl + '">' + i18n.__('OPEN PAGE') + '</a>';
*/
}
return content;
},
getAhref(username, link) {
return `<a href='${link}'>${username}</a>`;
},
replaceStringAtEnd(inputString, searchString, replacement) {
// Create a regular expression that matches the searchString at the end of the inputString
const regex = new RegExp(searchString + '$');
// Use the replace method with the regular expression to replace the string
const result = inputString.replace(regex, replacement);
return result;
},
getstrDateTimeEvent(myevent) {
let mystr = '';
// is same day?
if (this.getstrDateShort(myevent.dateTimeStart) === this.getstrDateShort(myevent.dateTimeEnd)) {
mystr = i18n.__(
'DATEDAYONLY',
this.getstrDateLong(myevent.dateTimeStart),
this.getstrTime(myevent.dateTimeStart),
this.getstrTime(myevent.dateTimeEnd)
);
} else {
mystr = i18n.__(
'DATE_2DAYS',
this.getstrDateLong(myevent.dateTimeStart),
this.getstrTime(myevent.dateTimeStart),
this.getstrDateLong(myevent.dateTimeEnd),
this.getstrTime(myevent.dateTimeEnd)
);
}
return '🗓 ' + mystr;
},
getDoveStrByAnnuncio(myrec) {
let dove = '🏠 ';
if (myrec.mycities && myrec.mycities.length > 0) {
dove += myrec.mycities
.map((city) => {
return `${city.comune} (${city.prov})`;
})
.join(', ');
}
return dove;
},
async getDescrEstesaStrByEvent(myrec) {
let mystr = '';
mystr = await this.firstchars(this.replaceStringAtEnd(myrec.note, '</div>', ''), 800);
if (mystr) mystr = ' ' + mystr;
return mystr;
},
async getEventForTelegram(myrec, mydescr, userorig) {
try {
let datastr = this.getstrDateTimeEvent(myrec);
let dovestr = this.getDoveStrByAnnuncio(myrec);
let descrestesa = await this.getDescrEstesaStrByEvent(myrec);
let organizedby = myrec.organisedBy;
let contributo = myrec.contribstr;
let newdescr = i18n.__('NEW_EVENT', userorig, datastr, mydescr, dovestr);
let newdescrtelegram = i18n.__('NEW_EVENT_TELEGRAM', datastr, mydescr, dovestr, descrestesa, userorig);
if (organizedby) {
newdescrtelegram += i18n.__('ORGANIZED_BY', organizedby);
}
if (contributo) {
newdescrtelegram += i18n.__('CONTRIB', contributo);
}
newdescrtelegram += i18n.__('EVENT_ADDED_FROM', userorig);
return { newdescr, newdescrtelegram };
} catch (e) {
console.error('Error', e);
}
},
addRowTelegram(icon, title, content, acapo, acapofine, islink) {
let mystr = '';
let descrcontent = content;
if (islink) {
title = `<a href="${content}">${title}</a>`;
descrcontent = '';
}
if (title) {
if (icon) mystr += `${icon} `;
mystr += `<strong>${title}</strong>`;
if (acapo) {
mystr += `\n`;
} else {
mystr += `: `;
}
}
if (descrcontent) {
mystr += `${descrcontent}\n`;
if (acapofine) {
mystr += `\n`;
}
}
return mystr;
},
async getInCambioDiByRec(myrec) {
const { Contribtype } = require('../models/contribtype');
try {
const idapp = myrec.idapp;
if (!idapp) return '';
const contribtype = await Contribtype.findAllIdApp(idapp);
let mystr = '';
for (const contribId of myrec.idContribType) {
const reccontr = contribtype.find((rec) => rec._id.toString() === contribId);
if (reccontr) {
if (mystr) {
mystr += ', ';
}
mystr += reccontr.label;
}
}
return mystr;
} catch (e) {}
},
async getStatusSkillByRec(myrec, onlyifNoDiPersona) {
const { StatusSkill } = require('../models/statusSkill');
try {
const idapp = myrec.idapp;
if (!idapp) return '';
const statusskill = await StatusSkill.findAllIdApp(idapp);
let mystr = '';
if (onlyifNoDiPersona) {
if (myrec.idStatusSkill.length === 1 && myrec.idStatusSkill[0] === shared_consts.STATUSSKILL_DI_PERSONA)
return '';
}
for (const status of myrec.idStatusSkill) {
const reccontr = statusskill.find((rec) => rec._id === status);
if (reccontr) {
if (mystr) {
mystr += ' e ';
}
mystr += reccontr.descr;
}
}
return mystr;
} catch (e) {}
},
getIconByAdType(adType) {
if (adType === shared_consts.AdType.OFFRO) return '🟢';
else if (adType === shared_consts.AdType.CERCO) return '🔴';
return '';
},
async getCategoriaSkillByRec(myrec) {
const { Skill } = require('../models/skill');
const { Sector } = require('../models/sector');
try {
// console.log('myrec', myrec);
const idapp = myrec.idapp;
if (!idapp) return '';
const skillrec = await Skill.findAllIdApp(idapp);
const sectorrec = await Sector.findAllIdApp(idapp);
let mystr = '';
const recsec = sectorrec.find((rec) => rec._id === myrec.idSector);
if (recsec) {
mystr += recsec.descr;
}
const rec = skillrec.find((rec) => rec._id === myrec.idSkill);
if (rec) {
mystr += ' 👉🏻 ' + rec.descr;
}
return mystr;
} catch (e) {}
},
async getCategoriaGoodByRec(myrec) {
const { SectorGood } = require('../models/sectorgood');
// const { Good } = require('../models/good');
// const goodrec = await Good.findAllIdApp(idapp);
try {
const idapp = myrec.idapp;
if (!idapp) return '';
const secgoodrec = await SectorGood.findAllIdApp(idapp);
let mystr = '';
const rec = secgoodrec.find((rec) => rec._id === myrec.idSectorGood);
// const rec = goodrec.find((rec) => rec._id === myrec.idSectorGood);
if (rec) {
mystr += rec.descr;
}
return mystr;
} catch (e) {}
},
getComuniEProvinceByRec(myrec) {
try {
let mystr = '';
if (myrec.hasOwnProperty('mycities')) {
let ind = 0;
for (const city of myrec.mycities) {
if (ind > 0) mystr += ', ';
mystr += city.comune + ' (' + city.prov + ')';
ind++;
}
}
return mystr;
} catch (e) {}
},
convertAndTruncateHTMLForTelegram(text, maxLength = 200, link = '') {
const tagMap = {
'<ul>': '',
'<ol>': '',
'<li>': '\n• ',
'</ul>': '',
'</ol>': '',
'</li>': '',
'<br>': '\n',
'<div>': '',
'</div>': '\n',
};
// Rimuoviamo specificamente <b>\n</b>
text = text.replace(/<b>\n<\/b>/g, '');
Object.keys(tagMap).forEach((tag) => {
const replacement = tagMap[tag];
text = text.replaceAll(tag, replacement);
});
text = text
.split('\n')
.map((line) => line.trim())
.join('\n');
text = text
.replace(/\n{3,}/g, '\n\n')
.replace(/\n+$/, '')
.trim();
if (text.length <= maxLength) {
return text;
}
// Tronchiamo il testo
let truncated = text.slice(0, maxLength);
let openTags = [];
// Troviamo tutti i tag aperti
const regex = /<(\w+)[^>]*>/g;
let match;
while ((match = regex.exec(truncated)) !== null) {
if (!truncated.includes(`</${match[1]}>`, match.index)) {
openTags.push(match[1]);
}
}
// Rimuoviamo l'ultima parola parziale
truncated = truncated.replace(/\S+$/, '');
let strcontinua = '';
if (link) {
strcontinua = `<em> (... <a href="${link}">continua sulla App</a>)</em>`;
} else {
strcontinua = `<em> (... continua sulla App)</em>`;
}
// Aggiungiamo '...' e chiudiamo i tag aperti
truncated += strcontinua;
while (openTags.length > 0) {
truncated += `</${openTags.pop()}>`;
}
return truncated;
},
convertHTMLTagsForTelegram(text) {
const tagMap = {
'<ul>': '',
'<ol>': '',
'<li>': '\n• ',
'</ul>': '',
'</ol>': '',
'</li>': '',
'<br>': '\n',
'<div>': '',
'</div>': '\n',
};
// Rimuoviamo i tag vuoti o contenenti solo spazi bianchi o newline
text = text.replace(/<(b|i|strong|em)>(\s|\n)*<\/\1>/g, '');
Object.keys(tagMap).forEach((tag) => {
const replacement = tagMap[tag];
text = text.replaceAll(tag, replacement);
});
// Rimuoviamo gli spazi bianchi all'inizio e alla fine di ogni riga
text = text
.split('\n')
.map((line) => line.trim())
.join('\n');
// Rimuoviamo le righe vuote consecutive, lasciandone solo una
text = text.replace(/\n{3,}/g, '\n\n');
// Rimuoviamo le righe vuote alla fine del testo
text = text.replace(/\n+$/, '');
text = text.replace(/<b>\n<\/b>/g, '');
return text.trim();
},
async getAnnuncioForTelegram(myrec, tablerec, mydescr, userorig, nuovo) {
try {
let newdescr = '';
let out = '';
let tiposcambio = '';
let iconascambio = '🟢';
let lang = 'it';
let datastr = '';
let dovestr = '';
let organizedby = '';
let contributo = '';
let img = '';
let descrperNotif = '';
if (tablerec === shared_consts.TABLES_MYGOODS || tablerec === shared_consts.TABLES_MYSKILLS) {
iconascambio = this.getIconByAdType(myrec.adType);
if (myrec.adType === shared_consts.AdType.OFFRO) tiposcambio = 'Offro';
else if (myrec.adType === shared_consts.AdType.CERCO) tiposcambio = 'Cerco';
} else if (tablerec === shared_consts.TABLES_MYHOSPS) {
iconascambio = this.getIconByAdType(myrec.adType);
if (myrec.adType === shared_consts.AdType.CERCO) tiposcambio = 'Cerco';
else tiposcambio = 'Offro';
if (myrec.typeHosp === shared_consts.TYPEHOSP_OSPITALITA) tiposcambio += ' Ospitalità';
else if (myrec.typeHosp === shared_consts.TYPEHOSP_SCAMBIOCASA) tiposcambio += ' Scambio Casa';
} else if (tablerec === shared_consts.TABLES_MYBACHECAS) {
datastr = this.getstrDateTimeEvent(myrec);
organizedby = myrec.organisedBy;
contributo = myrec.contribstr;
}
if (tablerec === shared_consts.TABLES_MYGOODS) {
newdescr = i18n.__('Good', userorig, mydescr);
descrperNotif = i18n.__('Good: %', mydescr);
} else if (tablerec === shared_consts.TABLES_MYSKILLS) {
newdescr = i18n.__('Service', userorig, mydescr);
descrperNotif = i18n.__('Service: %', mydescr);
} else if (tablerec === shared_consts.TABLES_MYHOSPS) {
newdescr = i18n.__('Hosp', userorig, mydescr);
descrperNotif = i18n.__('Hosp %s', userorig, mydescr);
} else if (tablerec === shared_consts.TABLES_MYBACHECAS) {
newdescr = i18n.__('Event', userorig, mydescr);
let dovestr = this.getDoveStrByAnnuncio(myrec);
descrperNotif = i18n.__('NEW_EVENT', userorig, datastr, mydescr, dovestr);
}
let contatto = userorig;
let contatto_telegram = '';
try {
let username_telegram = myrec.profile.username_telegram;
if (username_telegram) {
contatto_telegram = `@${username_telegram}`;
contatto = contatto_telegram;
} else {
contatto = myrec.email;
}
} catch (e) {}
let organizedBy = '';
let cat = '';
let status = '';
let online = false;
let solo_online = false;
let writtenby = myrec.profile.username_telegram;
let sitoweb = '';
let contact_phone = '';
let contact_email = '';
if (tablerec === shared_consts.TABLES_MYGOODS) {
cat = await this.getCategoriaGoodByRec(myrec);
} else if (tablerec === shared_consts.TABLES_MYSKILLS) {
cat = await this.getCategoriaSkillByRec(myrec);
online = myrec.idStatusSkill.findIndex((id) => id === shared_consts.STATUSSKILL_ONLINE) >= 0;
solo_online = online && myrec.idStatusSkill.length === 1;
status = await this.getStatusSkillByRec(myrec, true);
if (status) {
status = ' ' + status;
}
} else if (tablerec === shared_consts.TABLES_MYHOSPS) {
cat = '';
} else if (tablerec === shared_consts.TABLES_MYBACHECAS) {
if (myrec.website) {
sitoweb = myrec.website;
}
contact_phone = myrec.contact_phone || '';
contact_email = myrec.contact_email || '';
if (myrec.organisedBy) {
organizedBy = myrec.organisedBy;
contatto = '';
} else {
if (myrec.mygrp && myrec.mygrp.title) {
organizedBy = myrec.mygrp.title;
contatto = '';
}
}
if (
(myrec.contact_telegram && myrec.contact_telegram?.toLowerCase() !== contatto_telegram?.toLowerCase()) ||
!contatto
) {
contatto += '\n' + myrec.contact_telegram;
}
/*if (myrec.contact_phone) {
contatto += ' 📞 ' + myrec.contact_phone;
}*/
}
// let out = i18n.__('NEW_ANNUNCIO_TELEGRAM', mydescr, dovestr, descrestesa, userorig);
if (tiposcambio) out += this.addRowTelegram(iconascambio, tiposcambio + status, '', true, false);
const url = this.getHostByIdApp(myrec.idapp) + shared_consts.getDirectoryByTable(tablerec, true) + myrec._id;
out += `<strong>${myrec.descr}</strong>\n\n`;
if (datastr) out += this.addRowTelegram('', '', datastr, true, true);
if (cat) out += this.addRowTelegram('⭐️', 'Categoria', cat, true, true);
let descrcontent = this.convertAndTruncateHTMLForTelegram(myrec.note, 500, url);
// let descrcontent = this.firstchars(this.removeLastSpaceAndACapo(note), 200, true, url);
descrcontent = this.cleanHtmlForTelegram(descrcontent);
// descrcontent = '<span size="3"><b>Prova Pao</b> Ciaooo</span>';
if (descrcontent) out += this.addRowTelegram('', '', '📝 ' + descrcontent, true, true);
const localita = this.getComuniEProvinceByRec(myrec);
if (!solo_online) out += this.addRowTelegram('🏠', 'Località', localita, false, true);
const incambiodi = await this.getInCambioDiByRec(myrec);
if (incambiodi) out += this.addRowTelegram('⚖️', 'In cambio di', incambiodi, false, true);
if (organizedBy) {
out += this.addRowTelegram('🏠', 'Organizzato da', organizedBy, false, true);
} else {
out += this.addRowTelegram('👤', 'Contatto', contatto, false, true);
}
if (contributo) out += this.addRowTelegram('💰', 'Contributo Richiesto', contributo, false, true);
if (contact_phone || contact_email || sitoweb) {
out += this.addRowTelegram(
'',
'Per Info:',
(contact_phone ? '📞 ' + contact_phone + ' ' : '') +
(contact_email ? ' 📨 ' + contact_email + ' ' : '') +
(sitoweb ? ' 🌐 ' + sitoweb + ' ' : ''),
true,
true
);
}
if (writtenby && organizedBy) {
out += this.addRowTelegram('✍️', 'Redatto da', '@' + writtenby, false, true);
}
let cosastr = 'Annuncio';
if (tablerec === shared_consts.TABLES_MYBACHECAS) {
cosastr = 'Evento';
}
out += this.addRowTelegram('', `👉🏻 Vedi ${cosastr} completo su RISO`, url, true, true, true);
if (myrec.photos && myrec.photos.length > 0) {
// prende la prima foto ! ;
if (myrec.photos[0].imagefile)
img = this.getURLImg(myrec.idapp, tablerec, myrec.username, myrec.photos[0].imagefile, false);
}
console.log('out', out);
// out += i18n.__('ADDED_FROM', );
return { newdescr, newdescrtelegram: out, img, descrperNotif };
} catch (e) {
console.error('Error', e);
}
},
generateVapiKey() {
const webpush = require('web-push');
const vapidKeys = webpush.generateVAPIDKeys();
const msg1 = 'VAPID Public Key:' + vapidKeys.publicKey;
const msg2 = 'VAPID Private Key:' + vapidKeys.privateKey;
console.log(msg1);
console.log(msg2);
return { msg: msg1 + ' ' + msg2 };
},
differentObjects(obj1, obj2) {
try {
const fieldsUpdated = [];
const obj1Fields = obj1 ? Object.keys(obj1) : [];
const obj2Fields = obj2 ? Object.keys(obj2) : [];
const commonFields = obj1Fields.filter((field) => obj2Fields.includes(field));
commonFields.forEach((field) => {
if (obj1 && obj2 && (obj1[field] && obj1[field].toString()) !== (obj2[field] && obj2[field].toString())) {
if (obj1[field] !== undefined && obj2[field] !== undefined) fieldsUpdated.push(field);
}
});
return fieldsUpdated;
} catch (e) {
console.error('Err:', e);
}
},
isObjectEmpty(obj) {
return Object.keys(obj).length === 0;
},
getUnitsMeasure(unit, short) {
const unitrec = shared_consts.Units_Of_Measure_ListBox.find((rec) => rec.value === unit);
return unitrec ? (short ? unitrec.short : unitrec.label) : '';
},
getIdUnitsByText(unitstr) {
const unitrec = shared_consts.Units_Of_Measure_ListBox.find((rec) => rec.short === unitstr);
return unitrec ? unitrec.value : 0;
},
getWeightAndUnitByText(text) {
const result = [];
text = text.replace(',', '.');
const regex = /^(\d+\.?\d*)\s*(ml|gr|g|l|kg|uova)\s*$/; // Aggiunto un punto dopo \d+ per accettare anche i numeri con la virgola
const match = regex.exec(text);
if (match) {
let peso = parseFloat(match[1]); // Cambiato da parseInt a parseFloat per gestire i numeri con la virgola
let unita = match[2];
if (unita === 'gr') unita = 'g';
const unit = this.getIdUnitsByText(unita);
return { weight: peso, unit };
}
return { weight: 0, unit: 0 };
},
async isManagerByReq(req) {
try {
var { User } = require('../models/user');
const idapp = req.body.idapp;
let userId = '';
if (req.body) userId = req.body.userId;
const myuser = await User.getUserById(idapp, userId);
let ismanager = false;
if (myuser && myuser.perm) {
ismanager = User.isManager(myuser.perm);
}
return ismanager;
} catch (e) {
return false;
}
},
addslashes(str) {
return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
},
removeescape(inputString) {
// return inputString.replace(/\\/g, '').replace(/"/g, '');
if (inputString) return inputString.replace(/\\/g, '').replace(/"/g, '');
else return '';
},
escapeQuotes(stringa) {
if (stringa) return stringa.replace(/"/g, '\\"');
else return '';
},
replaceQuotesWithSingleQuotes(jsonString) {
if (jsonString) return jsonString.replace(/"/g, "'");
else return '';
},
ripulisciCampo(stringa) {
let mystr = this.replaceQuotesWithSingleQuotes(stringa);
return mystr;
},
convertToNumeroVirgola(valstr) {
if (valstr === '' || valstr === undefined) valstr = '0';
valstr = valstr + '';
valstr = valstr.replace(',', '.');
return parseFloat(valstr);
},
convertPriceEurToValue(inputString) {
inputString = this.removeescape(this.addslashes(inputString));
if (inputString === '') return '0';
// Rimuovi il simbolo della valuta (€) e sostituisci la virgola con un punto
return inputString.replace(/[^\d.,]/g, '').replace(',', '.');
},
removeLastSpaceAndACapo(miastr) {
miastr = miastr.trimRight().replace(/[\n\r]+$/, '');
// Rimuove eventuali '<br>' in fondo alla stringa
// Rimuove eventuali '<div><br></div>' in fondo alla stringa
miastr = miastr.replace(/<\/div>$/, '');
miastr = miastr.replace(/<\/div>$/, '');
miastr = miastr.replace(/<br>$/, '');
miastr = miastr.replace(/<div><br><\/div>$/, '');
miastr = miastr.replace(/<br>$/, '');
miastr = miastr.trimRight().replace(/[\n\r]+$/, '');
miastr = miastr.replace(/<div><br><\/div>$/, '');
miastr = miastr.replace(/<div>$/, '');
miastr = miastr.replace(/<br>$/, '');
miastr = miastr.replace(/<br>$/, '');
return miastr;
},
rimuoviAtPrimoCarattere(stringa) {
if (stringa.charAt(0) === '@') {
return stringa.slice(1);
} else {
return stringa;
}
},
// Funzione per ottenere le coordinate di una singola città
async getCityCoordinates(city) {
try {
const response = await axios.get(
`https://nominatim.openstreetmap.org/search?format=json&q=${city.descr},${city.prov},Italia`
);
if (response.data.length > 0) {
city.lat = parseFloat(response.data[0].lat);
city.long = parseFloat(response.data[0].lon);
// console.log(`${city.descr}: Lat ${city.lat}, Long ${city.long}`);
return city;
} else {
console.error(`Coordinate non trovate per ${city.descr}, ${city.prov}`);
}
return null;
} catch (error) {
console.error(`Errore durante il recupero delle coordinate per ${city.descr}, ${city.prov}:`, error.message);
}
},
/**
* Funzione per scaricare dati GeoJSON dei comuni d'Italia e salvarli localmente.
* @param {string} url - L'URL dal quale scaricare i dati GeoJSON.
* @param {string} outputPath - Il percorso del file in cui salvare i dati GeoJSON.
*/
async downloadGeoJSON(url, outputPath) {
try {
// Effettua una richiesta GET all'URL specificato per scaricare i dati.
const response = await axios.get(url);
const data = response.data;
// Salva i dati GeoJSON in un file locale.
await fs.writeFile(outputPath, JSON.stringify(data, null, 2));
console.log(`Dati GeoJSON salvati in ${outputPath}`);
} catch (error) {
console.error('Errore durante il download o il salvataggio dei dati GeoJSON:', error);
}
},
arrotondaA2Decimali(valore) {
try {
return parseFloat(valore).toFixed(2);
} catch (error) {
return valore;
}
},
cleanHtmlForTelegram(htmlContent) {
try {
// Assicurati che l'HTML abbia un elemento body
const dom = new JSDOM(`<body>${htmlContent}</body>`);
const document = dom.window.document;
// Definisci i tag permessi su Telegram
const allowedTags = ['b', 'strong', 'i', 'em', 'u', 's', 'strike', 'del', 'a', 'code'];
// Seleziona tutti gli elementi all'interno del body
const allElements = document.body.querySelectorAll('*');
allElements.forEach((element) => {
const tagName = element.tagName?.toLowerCase();
if (!allowedTags.includes(tagName)) {
// Crea un nodo di testo e sostituisci l'elemento con quel nodo di testo
const textNode = document.createTextNode(element.textContent || '');
element.replaceWith(textNode);
} else {
// Se il tag è permesso, rimuovi tutti gli attributi ad eccezione di 'href' per i link
if (tagName === 'a') {
const href = element.getAttribute('href');
while (element.attributes.length > 0) {
element.removeAttribute(element.attributes[0].name);
}
if (href) {
element.setAttribute('href', href);
}
} else {
while (element.attributes.length > 0) {
element.removeAttribute(element.attributes[0].name);
}
}
}
});
// Ritorna l'HTML pulito
return document.body.innerHTML;
} catch (error) {
console.error("Errore durante la pulizia dell'HTML:", error);
throw error; // Oppure, gestisci l'errore come preferisci
}
},
getHostWithNoHttporHttps(url) {
try {
const parsedUrl = new URL(url);
return parsedUrl.host;
} catch (error) {
console.error("Errore durante la pulizia dell'HTML:", error);
throw error; // Oppure, gestisci l'errore come preferisci
}
},
// Crea un file con all'interno il nome del dominio per ogni app:
createFileWithDomainName() {
const arrapps = getApps();
const filename = server_constants.FILECONFIG_SERVER;
for (const app of arrapps) {
fs.writeFile(filename, this.getHostWithNoHttporHttps(app.host), function (err) {
if (err) {
console.log(err);
}
});
if (app.host_test) {
fs.writeFile(filename, this.getHostWithNoHttporHttps(app.host_test), function (err) {
if (err) {
console.log(err);
}
});
}
}
},
async listCollectionsBySize() {
let output = ''; // Variabile per memorizzare l'output
try {
const conn = mongoose.connection;
// Ottieni le collezioni e calcola la dimensione
const collections = await conn.db.listCollections().toArray();
// Calcola la dimensione per ciascuna collezione
const collectionSizes = await Promise.all(
collections.map(async (collection) => {
const stats = await conn.db.collection(collection.name).stats();
return { name: collection.name, size: stats.size };
})
);
// Ordina le collezioni per dimensione
collectionSizes.sort((a, b) => b.size - a.size); // Ordine decrescente
output += 'Collezioni ordinate per dimensione:\n'; // Inizio dell'output
collectionSizes.forEach((collection) => {
const sizeInMB = (collection.size / (1024 * 1024)).toFixed(2); // Converti in MB
output += `Collezione: ${collection.name}, Dimensione: ${sizeInMB} MB\n`; // Aggiungi all'output
});
return output; // Restituisci l'output alla fine
} catch (error) {
console.error('Errore:', error);
return `Errore: ${error.message}`; // Restituisci l'errore come stringa
}
},
getStringaConto(mov) {
let mystr = '';
let userfrom = '';
let userto = '';
let profilefrom = null;
let profileto = null;
let tipocontofrom = shared_consts.AccountType.USER;
let tipocontoto = shared_consts.AccountType.USER;
if (mov.contocomfrom && mov.contocomfrom.name) {
userfrom += mov.contocomfrom.name;
tipocontofrom = shared_consts.AccountType.COMMUNITY_ACCOUNT;
}
if (mov.groupfrom) {
userfrom += mov.groupfrom.groupname;
tipocontofrom = shared_consts.AccountType.CONTO_DI_GRUPPO;
}
if (mov.userfrom) {
userfrom += mov.userfrom.username;
profilefrom = mov.userfrom.profile;
}
if (mov.contocomto && mov.contocomto.name) {
userto += mov.contocomto.name;
tipocontoto = shared_consts.AccountType.COMMUNITY_ACCOUNT;
}
if (mov.groupto) {
userto += mov.groupto.groupname;
tipocontoto = shared_consts.AccountType.CONTO_DI_GRUPPO;
}
if (mov.userto) {
userto += mov.userto.username;
profileto = mov.userto.profile;
}
// mystr = t('movement.from') + userfrom + ' ' + t('movement.to') + userto
return {
userfrom: { profile: profilefrom, username: userfrom },
userto: { profile: profileto, username: userto },
tipocontofrom,
tipocontoto,
};
},
getDirUpload() {
return 'upload/';
},
getDirByTable(idapp, table) {
let mydir = this.getdirByIdApp(idapp) + '/';
if (table === 'catalog') {
mydir = 'upload/cataloghi/';
}
return mydir;
},
getURLImg(idapp, table, username, img, checkifExist) {
let dirmain = '';
try {
// let dir = this.getdirByIdApp(idapp) + dirmain + '/' + this.getDirUpload();
let dir = this.getdirByIdApp(idapp);
'/' + this.getDirUpload() + shared_consts.getDirectoryImgByTable(table, username) + dirmain;
img = dir + img;
/*if (checkifExist) {
if (!this.isFileExistsAsync(img)) {
return '';
}
}*/
if (!this.sulServer()) {
// Finta Immagine
img = 'https://riso.app/upload/profile/SoniaVioletFlame/myskills/1000133092.jpg';
}
return img;
} catch (e) {
console.error('Err GetURLImg', e);
return '';
}
},
getLangByUsername(idapp, username) {
//++Todo LANG: Estrarre il Lang dall'username (user, group)
return 'it';
},
getFieldsForAnnunci() {
let annunciFields = {
idMyGroup: {
type: String,
},
expiryDateAdv: {
type: Date,
},
enableExpiringAdv: {
type: Boolean,
},
// **ADDFIELD_ANNUNCI
};
return annunciFields;
},
// Funzione per pulire il nome del file
cleanFileName(filePath) {
// Ottieni solo il nome del file dall'intero percorso
// const fileName = filePath.split('/').pop();
// Rimuovi apostrofi e sostituisci gli spazi con underscore
const cleanedName = fileName.replace(/'/g, '').replace(/\s+/g, '_');
// Restituisci il percorso chiaro; puoi decidere di mantenere il resto del percorso
return cleanedName;
},
fixUrl(myurl, idapp) {
if (!myurl.startsWith('http')) {
return this.getHostByIdApp(idapp) + myurl;
}
if (myurl.startsWith('http://127.0.0.1')) {
//myurl = myurl.replace('http://127.0.0.1:8084/', 'https://riso.app/')
// Se è in locale allora metti una foto finta...
myurl =
'https://images.unsplash.com/photo-1464047736614-af63643285bf?q=80&w=2874&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D';
//myurl = myurl.replace('http://127.0.0.1', 'http://localhost')
}
return myurl;
},
// Funzione per convertire XML in JSON
convertXMLToJSON(xml) {
const parser = new xml2js.Parser();
parser.parseString(xml, (err, result) => {
if (err) {
console.error('Error parsing XML:', err);
} else {
console.log(JSON.stringify(result, null, 2)); // Stampa il risultato in formato JSON
}
});
},
async getFreeDiskSpace(path = '/') {
try {
const { stdout } = await execPromise(`df -k ${path} | tail -1 | awk '{print $4}'`);
const freeSpaceKB = parseInt(stdout.trim());
const freeSpaceGB = (freeSpaceKB / 1024 / 1024).toFixed(2);
return `${freeSpaceGB} GB`;
} catch (error) {
console.error('Errore nel recupero dello spazio libero su disco:', error);
return null;
}
},
async findAllQueryIdApp(model, myfind, sort) {
try {
if (sort) {
return await model.find(myfind).sort(sort).lean();
} else {
return await model.find(myfind).lean();
}
} catch (err) {
console.error('Errore in findAllQueryIdApp:', err, model);
return null;
}
},
// 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(),
};
},
getDateFromISOString(mydate) {
const mydate2 = new Date(mydate);
return mydate2;
},
async downloadImgIfMissing(productInfo) {
const ProductInfo = require('../models/productInfo');
const Product = require('../models/product');
try {
if (this.sulServer()) {
dirmain = '';
} else {
dirmain = server_constants.DIR_PUBLIC_LOCALE;
}
/*if (true) {
const prova = await this.isFileExistsAsync('prova');
console.log('PROVA:', prova);
}*/
const vecchiomodo = false;
if (productInfo.image_link && vecchiomodo) {
const relativeimg = productInfo.image_link.split('/').pop();
const img =
this.getdirByIdApp(productInfo.idapp) +
dirmain +
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 || !(await this.isFileExistsAsync(savePath));
if (!productInfo.imagefile && (await this.isFileExistsAsync(savePath))) {
// esiste il file, ma sul DB non è corretto
const stats = fs.statSync(savePath); // Ottieni informazioni sul file
if (stats.size > 0) {
// Controlla se la dimensione del file è maggiore di zero
// Esiste il file ed è non vuoto, ma sul DB non è corretto
productInfo.imagefile = relativeimg;
return { prodInfo: productInfo, aggiornatoimg: true };
} else {
scaricaimg = true;
}
}
if (productInfo.imagefile && (await this.isFileExistsAsync(savePath))) {
// esiste il file, ma sul DB non è corretto
const stats = fs.statSync(savePath); // Ottieni informazioni sul file
if (stats.size <= 0) {
// Controlla se la dimensione del file è maggiore di zero
scaricaimg = true;
}
}
if (scaricaimg && vecchiomodo) {
// Download image from the URL productInfo.image_link
productInfo.imagefile = relativeimg;
const downloader = new ImageDownloader();
const aggiornatoimg = await downloader
.downloadImage(productInfo.image_link, savePath, {
maxRetries: 1,
initialDelay: 300,
timeout: 15000,
})
.then((result) => {
if (result) {
// console.log('Download completato con successo!');
} else {
console.log('Download non riuscito.');
}
return result;
});
return { prodInfo: productInfo, aggiornatoimg: aggiornatoimg.ris };
}
}
let fileesistente = false;
if (productInfo.imagefile && productInfo.imagefile !== 'noimg.jpg') {
// controlla se esiste il file
const img =
this.getdirByIdApp(productInfo.idapp) +
dirmain +
server_constants.DIR_UPLOAD +
'/products/' +
productInfo.imagefile.split('/').pop();
const filecompleto = path.resolve(__dirname, img); // Sostituisci con il percorso dove salvare l'immagine
// Se non esiste lo scarico !
fileesistente = await this.isFileExistsAsync(filecompleto);
}
if (!vecchiomodo && (!productInfo.image_link || !fileesistente)) {
let scarica_da_sito = !productInfo.imagefile || productInfo.imagefile === 'noimg.jpg';
if (!scarica_da_sito && productInfo.imagefile) {
scarica_da_sito = !fileesistente; // Se non esiste lo scarico !
}
if (scarica_da_sito && !productInfo.image_not_found) {
// date and time
productInfo.imagefile = 'img_' + new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
const img =
this.getdirByIdApp(productInfo.idapp) +
dirmain +
server_constants.DIR_UPLOAD +
'/products/' +
productInfo.imagefile.split('/').pop();
let savePath = path.resolve(__dirname, img); // Sostituisci con il percorso dove salvare l'immagine
let link = 'https://www.gruppomacro.com/copertine.php?id_gm=' + productInfo.sku;
const downloader = new ImageDownloader();
let aggiornatoimg;
try {
aggiornatoimg = await downloader.downloadImage(link, savePath, {
maxRetries: 3,
initialDelay: 300,
timeout: 15000,
nomefileoriginale: true,
});
} catch (e) {
aggiornatoimg = { ris: false };
}
if (
aggiornatoimg?.code === 404 ||
(aggiornatoimg?.filepath && aggiornatoimg.filepath.includes('noimg.jpg'))
) {
// non trovato quindi la prossima volta non richiederlo
await ProductInfo.setImgNotFound(productInfo._id);
}
if (aggiornatoimg?.filepath.includes('noimg.jpg')) {
// nascondi il prodotto se non trovo l'immagine !
await Product.updateOne({ idProductInfo: productInfo._id }, { $set: { deleted: true } });
aggiornatoimg = { ris: false, deleted: true };
}
if (aggiornatoimg?.filepath) {
const filenamebase = path.basename(aggiornatoimg.filepath);
// const img = '/upload/products/' + filenamebase;
productInfo.imagefile = filenamebase;
}
return { prodInfo: productInfo, aggiornatoimg: aggiornatoimg.ris };
} else {
return { prodInfo: null, aggiornatoimg: false };
}
}
} catch (e) {
console.error('downloadImgIfMissing', e.message);
}
return { prodInfo: null, aggiornatoimg: false };
},
removeAccents(mystr) {
if (!mystr) return mystr;
const accentsMap = new Map([
['á', 'a'],
['à', 'a'],
['ã', 'a'],
['ä', 'a'],
['â', 'a'],
['é', 'e'],
['è', 'e'],
['ë', 'e'],
['ê', 'e'],
['í', 'i'],
['ì', 'i'],
['ï', 'i'],
['î', 'i'],
['ó', 'o'],
['ò', 'o'],
['ö', 'o'],
['ô', 'o'],
['õ', 'o'],
['ú', 'u'],
['ù', 'u'],
['ü', 'u'],
['û', 'u'],
['ç', 'c'],
['ñ', 'n'],
]);
return Array.from(mystr)
.map((char) => accentsMap.get(char) || char)
.join('');
},
getDateYYYYMMDD_Today() {
// Ottieni la data attuale nel formato YYYY-MM-DD
const today = new Date();
const formattedDate = today.toISOString().split('T')[0]; // Format YYYY-MM-DD
return formattedDate;
},
convertFullFileNameToURL(idapp, fullfilename) {
const mydir = this.getdirByIdApp(idapp);
const myhost = this.getHostByIdApp(idapp);
// ++ remove mydir from fullfilename and add myhost to generate a URL
const url = fullfilename.replace(mydir, '').replace(/\\/g, '/'); // Replace backslashes with slashes
const myurl = myhost + '/' + url;
console.log('myurl', myurl);
return myurl;
},
removePathDirByFileName(idapp, fullfilename) {
const mydir = this.getdirByIdApp(idapp);
let filename = fullfilename.replace(mydir, '').replace(/\\/g, '/'); // Sostituisce backslash con slash
// Rimuove la barra iniziale se presente
if (filename.startsWith('/')) {
filename = filename.substring(1);
}
return filename;
},
isDateValid(mydate) {
try {
return (
mydate instanceof Date && isFinite(mydate.getTime()) && mydate.toISOString().split('T')[0] !== '1970-01-01'
);
} catch {
return false;
}
},
async getSizeFile(filename) {
try {
if (await this.isFileExistsAsync(filename)) {
const stats = fs.statSync ? fs.statSync(filename) : null;
const fileSizeInBytes = stats.size;
const fileSizeInMB = fileSizeInBytes / (1024 * 1024);
return fileSizeInMB.toFixed(2); // Returns size in MB with 2 decimal places
} else {
return 0;
}
} catch (e) {
console.error('Error getting file size:', e);
return '0.00';
}
},
aggiungiSuffissoAlNomeFile(filePath, suffisso) {
const dir = path.dirname(filePath);
const estensione = path.extname(filePath);
const nomeFile = path.basename(filePath, estensione);
const nuovoNomeFile = nomeFile + suffisso + estensione;
return path.join(dir, nuovoNomeFile);
},
async attendiNSecondi(numsec) {
await new Promise((resolve) => setTimeout(resolve, numsec * 1000));
},
async copyDirectory(sourceDir, destinationDir) {
try {
await fs.copy(sourceDir, destinationDir);
console.log('Directory copiata con successo!');
} catch (err) {
console.error('Errore durante la copia della directory:', err);
}
},
fixFilePath(myfilepath) {
return myfilepath.replace(/\\/g, '/');
},
getDateNow() {
const mydate = new Date();
return mydate;
},
};