- aggiornato la guida per installare la App
- aggiornato la Guida Completa e Breve di RISO. - pagina per ricevere i RIS. - sistemato problema creazione nuovi Circuiti (admin non corretti). - corretto giro delle email, invitante, invitato e ricezione msg su telegram.
This commit is contained in:
@@ -66,7 +66,7 @@ db.myelems.insertMany([
|
|||||||
"listcards": [],
|
"listcards": [],
|
||||||
"list": [],
|
"list": [],
|
||||||
"__v": 0,
|
"__v": 0,
|
||||||
"containerHtml": "<style>\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n padding: 20px;\n background-color: #f0f0f0;\n color: #333;\n}\n\nh1 {\n color: #0056b3;\n text-align: center;\n}\n\n\np, li {\n line-height: 1.6;\n}\n\n\nul {\n list-style-type: none;\n padding: 0;\n}\n\n\nli {\n background-color: #fff !important;\n margin-bottom: 10px !important;\n padding: 10px !important;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important; \n}\n\n\na {\n color: #007bff;\n text-decoration: none;\n}\n\n\na:hover {\n text-decoration: underline;\n}\n\n\n.container {\n max-width: 800px;\n margin: 0 auto;\n background-color: #fff;\n padding: 20px;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n}\n\n\n.strong {\n font-weight: bold;\n}\n</style>\n\n\n<p><strong>“Abitare gli Iblei”</strong> è una rete aperta che ha lo scopo di riunire tutte quelle persone che vogliono valorizzare e qualificare la vita nel territorio degli Iblei. </p>\n \n <p>Chi aderisce alla rete si riconosce in una <strong>Carta dei valori comuni</strong> e usa la rete per scambiare conoscenze, esperienze, risorse e prodotti sviluppati nell’ambito delle proprie iniziative (profit e non profit) individuali o collettive.</p>\n\n\n <p>L’area territoriale di questa rete è quella dei <strong>Monti Iblei orientali e occidentali</strong> (Noto, Avola, Canicattini, Siracusa, Palazzolo, Buccheri, Ferla, Modica, …).</p>\n\n\n <p>La rete <strong>“Abitare gli Iblei”</strong> offre i seguenti servizi utili per il territorio ed i suoi abitanti, frutto di una costruzione collettiva:</p>\n \n <ul>\n <li><strong>1. Mappa delle attività virtuose:</strong> permette di identificare attività pubbliche e private nel territorio che possono essere utili nella vita quotidiana. Queste attività possono riguardare artigiani, produttori o fornitori di servizi di cui almeno un membro della rete conosca la qualità e l’affidabilità (agricoltori, falegnami, fabbri, idraulici, imprese edili, strutture ricettive, …). Altre informazioni utili possono riguardare associazioni/istituzioni operanti in vari settori. – <strong>Accesso pubblico</strong></li>\n <li><strong>2. Calendario:</strong> permette di accedere ad annunci di eventi utili alla crescita culturale del territorio. La pubblicazione di eventi è riservata ai soli membri della rete che possono presentare iniziative anche di altri organizzatori. – <strong>Accesso pubblico</strong></li>\n <li><strong>3. Scambi di servizi, prodotti e ospitalità:</strong> questa funzione è riservata ai soli membri della rete e si realizza attraverso la Rete Italiana scambi orizzontali (RISO). – <strong>Accesso riservato</strong></li>\n <li><strong>4. Segnalazione di pericoli per il territorio:</strong> attraverso questa mappa è possibile segnalare incendi, immondizia abbandonata, discariche abusive, fonti di inquinamento per corsi d’acqua e spiagge, presenza di inquinamento nell’aria, … – <strong>Accesso riservato</strong></li>\n </ul>\n \n <p>Se vuoi aderire alla rete puoi richiederne la registrazione utilizzando questo Link <a href=\"#\"><strong>(Pagina in Costruzione)</strong></a>.</p>\n\n",
|
"containerHtml": "<style>\nbody {\n font-family: Arial, sans-serif;\n margin: 0;\n padding: 20px;\n background-color: #f0f0f0;\n color: #333;\n}\n\nh1 {\n color: #0056b3;\n text-align: center;\n}\n\n\np, li {\n line-height: 1.6;\n}\n\n\nul {\n list-style-type: none;\n padding: 0;\n}\n\n\nli {\n background-color: #fff !important;\n margin-bottom: 10px !important;\n padding: 10px !important;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important; \n}\n\n\na {\n color: #007bff;\n text-decoration: none;\n}\n\n\na:hover {\n text-decoration: underline;\n}\n\n\n.container {\n max-width: 800px;\n margin: 0 auto;\n background-color: #fff;\n padding: 20px;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n}\n\n\n.strong {\n font-weight: bold;\n}\n</style>\n\n\n<p><strong>“Abitare gli Iblei”</strong> è una rete aperta che ha lo scopo di riunire tutte quelle persone che vogliono valorizzare e qualificare la vita nel territorio degli Iblei. </p>\n \n <p>Chi aderisce alla rete si riconosce in una <strong>Carta dei valori comuni</strong> e usa la rete per scambiare conoscenze, esperienze, risorse e prodotti sviluppati nell’ambito delle proprie iniziative (profit e non profit) individuali o collettive.</p>\n\n\n <p>L’area territoriale di questa rete è quella dei <strong>Monti Iblei orientali e occidentali</strong> (Noto, Avola, Canicattini, Siracusa, Palazzolo, Buccheri, Ferla, Modica, …).</p>\n\n\n <p>La rete <strong>“Abitare gli Iblei”</strong> offre i seguenti servizi utili per il territorio ed i suoi abitanti, frutto di una costruzione collettiva:</p>\n \n <ul>\n <li><strong>1. Mappa delle attività virtuose:</strong> permette di identificare attività pubbliche e private nel territorio che possono essere utili nella vita quotidiana. Queste attività possono riguardare artigiani, produttori o fornitori di servizi di cui almeno un membro della rete conosca la qualità e l’affidabilità (agricoltori, falegnami, fabbri, idraulici, imprese edili, strutture ricettive, …). Altre informazioni utili possono riguardare associazioni/istituzioni operanti in vari settori. – <strong>Accesso pubblico</strong></li>\n <li><strong>2. Calendario:</strong> permette di accedere ad annunci di eventi utili alla crescita culturale del territorio. La pubblicazione di eventi è riservata ai soli membri della rete che possono presentare iniziative anche di altri organizzatori. – <strong>Accesso pubblico</strong></li>\n <li><strong>3. Scambi di servizi, prodotti e ospitalità:</strong> questa funzione è riservata ai soli membri della rete e si realizza attraverso la Rete Italiana scambio orizzontale (RISO). – <strong>Accesso riservato</strong></li>\n <li><strong>4. Segnalazione di pericoli per il territorio:</strong> attraverso questa mappa è possibile segnalare incendi, immondizia abbandonata, discariche abusive, fonti di inquinamento per corsi d’acqua e spiagge, presenza di inquinamento nell’aria, … – <strong>Accesso riservato</strong></li>\n </ul>\n \n <p>Se vuoi aderire alla rete puoi richiederne la registrazione utilizzando questo Link <a href=\"#\"><strong>(Pagina in Costruzione)</strong></a>.</p>\n\n",
|
||||||
"anim": {
|
"anim": {
|
||||||
"_id": new ObjectId("66db393e3b885ccdfaed28d6"),
|
"_id": new ObjectId("66db393e3b885ccdfaed28d6"),
|
||||||
"name": "",
|
"name": "",
|
||||||
|
|||||||
@@ -423,16 +423,13 @@ html(lang="it")
|
|||||||
.email-header
|
.email-header
|
||||||
- var baseimg = baseurl + '/';
|
- var baseimg = baseurl + '/';
|
||||||
img.header-logo(src=baseimg+"images/logo.png" alt=nomeapp || 'Logo')
|
img.header-logo(src=baseimg+"images/logo.png" alt=nomeapp || 'Logo')
|
||||||
.welcome-icon 💚
|
h1 Benvenuto/a #{name || username} nella community RISO! 💚
|
||||||
h1 Benvenuti nella comunità RISO
|
|
||||||
p
|
|
||||||
strong #{name || username || 'Tu'}
|
|
||||||
| #{name || username ? ',' : ''} sei ufficialmente parte di qualcosa di speciale!
|
|
||||||
|
|
||||||
.email-body
|
.email-body
|
||||||
.welcome-message
|
.welcome-message
|
||||||
h2 🎉 Il tuo invitante #{nomeInvitante} ti ha ammesso!
|
if ammessoUtente
|
||||||
p Sei ora un membro attivo della Rete Italiana di Scambio Orizzontale
|
h2 🎉 Il tuo invitante #{nomeInvitante} ti ha ammesso!
|
||||||
|
p Sei ora un membro della Rete Italiana di Scambio Orizzontale
|
||||||
p Inizia subito a scoprire beni, servizi e ospitalità nella tua comunità territoriale
|
p Inizia subito a scoprire beni, servizi e ospitalità nella tua comunità territoriale
|
||||||
|
|
||||||
.intro-text
|
.intro-text
|
||||||
@@ -444,6 +441,37 @@ html(lang="it")
|
|||||||
strong un'economia più umana e solidale
|
strong un'economia più umana e solidale
|
||||||
| .
|
| .
|
||||||
|
|
||||||
|
.next-steps
|
||||||
|
.next-steps-title 🎯 I tuoi primi passi nella community RISO
|
||||||
|
|
||||||
|
.step-item
|
||||||
|
.step-number 1
|
||||||
|
.step-content
|
||||||
|
h3 ✅ Completa il tuo profilo
|
||||||
|
p Collega il tuo profilo a Telegram, inserisci la tua Provincia ed accedi ai Circuiti Territoriali per poter iniziare ad usare i RIS. Un profilo completo aiuta gli altri membri a conoscerti meglio!
|
||||||
|
|
||||||
|
.step-item
|
||||||
|
.step-number 2
|
||||||
|
.step-content
|
||||||
|
h3 🔍 Esplora gli annunci
|
||||||
|
p Scopri cosa offrono gli altri membri nella tua area. Potresti trovare esattamente ciò che cerchi!
|
||||||
|
|
||||||
|
.step-item
|
||||||
|
.step-number 3
|
||||||
|
.step-content
|
||||||
|
h3 📢 Pubblica il tuo primo annuncio
|
||||||
|
p Cosa puoi offrire? Beni, servizi o ospitalità - ogni contributo arricchisce la comunità. Ricorda di includere come strumento di scambio il RIS e sperimentalo da subito!
|
||||||
|
|
||||||
|
.step-item
|
||||||
|
.step-number 4
|
||||||
|
.step-content
|
||||||
|
h3 💬 Unisciti al gruppo territoriale
|
||||||
|
p Partecipa alle conversazioni, agli eventi e alle iniziative della tua comunità locale sulle chat Telegram di RISO
|
||||||
|
|
||||||
|
.cta-section
|
||||||
|
.cta-title 🚀 Accedi e inizia il tuo viaggio RISO
|
||||||
|
.cta-subtitle Scegli come vuoi accedere alla piattaforma
|
||||||
|
|
||||||
.credentials-box
|
.credentials-box
|
||||||
.credentials-title 📋 I tuoi dati di accesso
|
.credentials-title 📋 I tuoi dati di accesso
|
||||||
|
|
||||||
@@ -465,10 +493,6 @@ html(lang="it")
|
|||||||
br
|
br
|
||||||
a(href=forgetpwd target="_blank") Hai dimenticato la password?
|
a(href=forgetpwd target="_blank") Hai dimenticato la password?
|
||||||
|
|
||||||
.cta-section
|
|
||||||
.cta-title 🚀 Accedi e inizia il tuo viaggio RISO
|
|
||||||
.cta-subtitle Scegli come vuoi accedere alla piattaforma
|
|
||||||
|
|
||||||
if strlinksito
|
if strlinksito
|
||||||
.cta-buttons-wrapper
|
.cta-buttons-wrapper
|
||||||
a.cta-button(href=strlinksito target="_blank")
|
a.cta-button(href=strlinksito target="_blank")
|
||||||
@@ -483,33 +507,6 @@ html(lang="it")
|
|||||||
span.button-icon 📖
|
span.button-icon 📖
|
||||||
| Leggi la Guida
|
| Leggi la Guida
|
||||||
|
|
||||||
.next-steps
|
|
||||||
.next-steps-title 🎯 I tuoi primi passi nella comunità RISO
|
|
||||||
|
|
||||||
.step-item
|
|
||||||
.step-number 1
|
|
||||||
.step-content
|
|
||||||
h3 ✅ Completa il tuo profilo
|
|
||||||
p Aggiungi una foto, descrivi chi sei e cosa ti appassiona. Un profilo completo aiuta gli altri membri a conoscerti meglio!
|
|
||||||
|
|
||||||
.step-item
|
|
||||||
.step-number 2
|
|
||||||
.step-content
|
|
||||||
h3 📢 Pubblica il tuo primo annuncio
|
|
||||||
p Cosa puoi offrire? Beni, servizi o ospitalità - ogni contributo arricchisce la comunità. Ricorda di includere come strumento di scambio il RIS!
|
|
||||||
|
|
||||||
.step-item
|
|
||||||
.step-number 3
|
|
||||||
.step-content
|
|
||||||
h3 🔍 Esplora gli annunci
|
|
||||||
p Scopri cosa offrono gli altri membri nella tua area. Potresti trovare esattamente ciò che cerchi!
|
|
||||||
|
|
||||||
.step-item
|
|
||||||
.step-number 4
|
|
||||||
.step-content
|
|
||||||
h3 💬 Unisciti al gruppo territoriale
|
|
||||||
p Partecipa alle conversazioni, agli eventi e alle iniziative della tua comunità locale sulle chat Telegram di RISO
|
|
||||||
|
|
||||||
.info-box
|
.info-box
|
||||||
p
|
p
|
||||||
strong 💰 Cos'è il RIS?
|
strong 💰 Cos'è il RIS?
|
||||||
@@ -526,6 +523,7 @@ html(lang="it")
|
|||||||
strong sei un membro attivo
|
strong sei un membro attivo
|
||||||
| di una comunità che crede nella solidarietà e nella condivisione!
|
| di una comunità che crede nella solidarietà e nella condivisione!
|
||||||
|
|
||||||
|
|
||||||
.email-footer
|
.email-footer
|
||||||
.divider
|
.divider
|
||||||
p 💚 Benvenuto/a nella famiglia RISO!
|
p 💚 Benvenuto/a nella famiglia RISO!
|
||||||
@@ -300,7 +300,7 @@ html(lang="it")
|
|||||||
.email-container
|
.email-container
|
||||||
//- Header
|
//- Header
|
||||||
.email-header
|
.email-header
|
||||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp+' - Rete Italiana Scambi Orizzontali')
|
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp+' - Rete Italiana Scambio orizzontale')
|
||||||
h1 🎉 Il tuo invito è stato accettato!
|
h1 🎉 Il tuo invito è stato accettato!
|
||||||
p.subtitle Un nuovo membro si è unito a #{nomeapp}
|
p.subtitle Un nuovo membro si è unito a #{nomeapp}
|
||||||
|
|
||||||
@@ -318,12 +318,12 @@ html(lang="it")
|
|||||||
if emailInvitato
|
if emailInvitato
|
||||||
.member-detail
|
.member-detail
|
||||||
strong Email:
|
strong Email:
|
||||||
| #{emailInvitato}
|
a(href=`mailto:${emailInvitato}` style="color: #667eea; text-decoration: none;") #{emailInvitato}
|
||||||
if usernameInvitato
|
if usernameInvitato
|
||||||
.member-detail
|
.member-detail
|
||||||
strong Username:
|
strong Username:
|
||||||
| #{usernameInvitato}
|
| #{usernameInvitato}
|
||||||
|
|
||||||
//- Bottone profilo
|
//- Bottone profilo
|
||||||
if usernameInvitato
|
if usernameInvitato
|
||||||
.buttprof-section
|
.buttprof-section
|
||||||
@@ -389,6 +389,6 @@ html(lang="it")
|
|||||||
.divider
|
.divider
|
||||||
p Hai ricevuto questa email perché hai invitato #{nomeInvitato} su #{nomeapp} oppure la persona ha usato il tuo username come invitante
|
p Hai ricevuto questa email perché hai invitato #{nomeInvitato} su #{nomeapp} oppure la persona ha usato il tuo username come invitante
|
||||||
p(style="margin-top: 12px; font-size: 12px;")
|
p(style="margin-top: 12px; font-size: 12px;")
|
||||||
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambi Orizzontali
|
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambio orizzontale
|
||||||
p(style="margin-top: 12px; font-size: 12px;")
|
p(style="margin-top: 12px; font-size: 12px;")
|
||||||
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||||
471
emails/defaultSite/reg_email_benvenuto_ammesso/it/html.pug
Executable file
471
emails/defaultSite/reg_email_benvenuto_ammesso/it/html.pug
Executable file
@@ -0,0 +1,471 @@
|
|||||||
|
doctype html
|
||||||
|
html(lang="it")
|
||||||
|
head
|
||||||
|
meta(charset="UTF-8")
|
||||||
|
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||||
|
style(type="text/css").
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-logo {
|
||||||
|
width: 80px;
|
||||||
|
height: auto;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header {
|
||||||
|
background: linear-gradient(135deg, #2E7D32 0%, #1B5E20 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 40px 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header h1 {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header p {
|
||||||
|
margin: 8px 0 0 0;
|
||||||
|
font-size: 16px;
|
||||||
|
opacity: 0.95;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-body {
|
||||||
|
padding: 24px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-text {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.7;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-text strong {
|
||||||
|
color: #2E7D32;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-message {
|
||||||
|
background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
|
||||||
|
border-left: 4px solid #2E7D32;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-message h2 {
|
||||||
|
color: #1B5E20;
|
||||||
|
font-size: 20px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-message p {
|
||||||
|
color: #2E7D32;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-box {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-left: 4px solid #2E7D32;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #555;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #666;
|
||||||
|
min-width: 120px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-value {
|
||||||
|
color: #1a1a1a;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
flex: 1;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-value a {
|
||||||
|
color: #2E7D32;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-value a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section {
|
||||||
|
margin: 24px 0;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-title {
|
||||||
|
font-size: 19px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1a1a1a;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-subtitle {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-buttons-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: stretch;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 16px 28px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
background: linear-gradient(135deg, #2E7D32 0%, #1B5E20 100%);
|
||||||
|
border-radius: 50px;
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: 0 4px 12px rgba(46, 125, 50, 0.3);
|
||||||
|
transition: transform 0.2s, box-shadow 0.2s;
|
||||||
|
flex: 1;
|
||||||
|
min-width: 160px;
|
||||||
|
max-width: 200px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 16px rgba(46, 125, 50, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button-secondary {
|
||||||
|
background: linear-gradient(135deg, #388E3C 0%, #2E7D32 100%);
|
||||||
|
box-shadow: 0 4px 12px rgba(56, 142, 60, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button-secondary:hover {
|
||||||
|
box-shadow: 0 6px 16px rgba(56, 142, 60, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button-tertiary {
|
||||||
|
background: linear-gradient(135deg, #66BB6A 0%, #4CAF50 100%);
|
||||||
|
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button-tertiary:hover {
|
||||||
|
box-shadow: 0 6px 16px rgba(76, 175, 80, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-icon {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-right: 6px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.next-steps {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.next-steps-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #2E7D32;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background: #f8fdf9;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 3px solid #4CAF50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-number {
|
||||||
|
background: linear-gradient(135deg, #4CAF50 0%, #388E3C 100%);
|
||||||
|
color: white;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-right: 12px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content h3 {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #1B5E20;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #555;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #A5D6A7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box p {
|
||||||
|
margin: 0;
|
||||||
|
color: #1B5E20;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box strong {
|
||||||
|
color: #2E7D32;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-note {
|
||||||
|
background: #fff3e0;
|
||||||
|
border-left: 4px solid #FF9800;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-note p {
|
||||||
|
color: #E65100;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-footer {
|
||||||
|
padding: 20px 16px;
|
||||||
|
text-align: center;
|
||||||
|
background: #f8f9fa;
|
||||||
|
color: #777;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-footer p {
|
||||||
|
margin: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||||
|
margin: 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header {
|
||||||
|
padding: 24px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header p {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-body {
|
||||||
|
padding: 20px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-message {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credentials-box {
|
||||||
|
padding: 16px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-row {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-label {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.credential-value {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-buttons-wrapper {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
padding: 14px 24px;
|
||||||
|
font-size: 15px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-number {
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content h3 {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-content p {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body
|
||||||
|
.email-container
|
||||||
|
.email-header
|
||||||
|
- var baseimg = baseurl + '/';
|
||||||
|
img.header-logo(src=baseimg+"images/logo.png" alt=nomeapp || 'Logo')
|
||||||
|
h1 💚 #{name || username ? ',' : ''} Benvenuto/a nella piattaforma #{nomeapp} 💚 !
|
||||||
|
|
||||||
|
.email-body
|
||||||
|
.welcome-message
|
||||||
|
if ammessoUtente
|
||||||
|
h2 🎉 Il tuo invitante #{nomeInvitante} ti ha ammesso!
|
||||||
|
p Sei ora un membro attivo della Rete Italiana di Scambio Orizzontale
|
||||||
|
p Inizia subito a scoprire beni, servizi e ospitalità nella tua comunità territoriale
|
||||||
|
|
||||||
|
.credentials-box
|
||||||
|
.credentials-title 📋 I tuoi dati di accesso
|
||||||
|
|
||||||
|
if username
|
||||||
|
.credential-row
|
||||||
|
.credential-label Username:
|
||||||
|
.credential-value #{username}
|
||||||
|
|
||||||
|
if emailto
|
||||||
|
.credential-row
|
||||||
|
.credential-label Email:
|
||||||
|
.credential-value #{emailto}
|
||||||
|
|
||||||
|
if forgetpwd
|
||||||
|
.credential-row
|
||||||
|
.credential-label Password:
|
||||||
|
.credential-value
|
||||||
|
| (la password che hai inserito)
|
||||||
|
br
|
||||||
|
a(href=forgetpwd target="_blank") Hai dimenticato la password?
|
||||||
|
|
||||||
|
.cta-section
|
||||||
|
.cta-title 🚀 Accedi e inizia il tuo viaggio
|
||||||
|
.cta-subtitle Scegli come vuoi accedere alla piattaforma
|
||||||
|
|
||||||
|
if strlinksito
|
||||||
|
.cta-buttons-wrapper
|
||||||
|
a.cta-button(href=strlinksito target="_blank")
|
||||||
|
span.button-icon 🌐
|
||||||
|
| Accedi da Web
|
||||||
|
|
||||||
|
.email-footer
|
||||||
|
.divider
|
||||||
|
p 💚 Benvenuto/a nella famiglia #{nomeapp}!
|
||||||
|
p(style="margin-top: 8px;") Hai ricevuto questa email perché sei stato/a ammesso/a nella community di #{nomeapp}
|
||||||
|
p(style="margin-top: 12px; font-size: 12px;")
|
||||||
|
| © #{new Date().getFullYear()} #{nomeapp}
|
||||||
1
emails/defaultSite/reg_email_benvenuto_ammesso/it/subject.pug
Executable file
1
emails/defaultSite/reg_email_benvenuto_ammesso/it/subject.pug
Executable file
@@ -0,0 +1 @@
|
|||||||
|
=`Benvenuto in ${nomeapp}`
|
||||||
@@ -282,9 +282,8 @@ html(lang="it")
|
|||||||
.email-container
|
.email-container
|
||||||
//- Header
|
//- Header
|
||||||
.email-header
|
.email-header
|
||||||
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp+' - Rete Italiana Scambi Orizzontali')
|
img.header-logo(src=baseurl+'/images/logo.png' alt=nomeapp+' - Rete Italiana Scambio orizzontale')
|
||||||
.success-icon 🎉
|
h1 🎉 Il tuo invito è stato accettato!
|
||||||
h1 Il tuo invito è stato accettato!
|
|
||||||
p.subtitle Un nuovo membro si è unito a #{nomeapp}
|
p.subtitle Un nuovo membro si è unito a #{nomeapp}
|
||||||
|
|
||||||
//- Body
|
//- Body
|
||||||
@@ -301,7 +300,7 @@ html(lang="it")
|
|||||||
if emailInvitato
|
if emailInvitato
|
||||||
.member-detail
|
.member-detail
|
||||||
strong Email:
|
strong Email:
|
||||||
| #{emailInvitato}
|
a(href=`mailto:${emailInvitato}` style="color: #667eea; text-decoration: none;") #{emailInvitato}
|
||||||
if usernameInvitato
|
if usernameInvitato
|
||||||
.member-detail
|
.member-detail
|
||||||
strong Username:
|
strong Username:
|
||||||
|
|||||||
@@ -302,9 +302,9 @@ html(lang="it")
|
|||||||
.email-container
|
.email-container
|
||||||
//- Header
|
//- Header
|
||||||
.email-header
|
.email-header
|
||||||
img.header-logo(src=baseurl+'/images/logo.png' alt='RISO - Rete Italiana Scambi Orizzontali')
|
img.header-logo(src=baseurl+'/images/logo.png' alt='RISO - Rete Italiana Scambio orizzontale')
|
||||||
h1 Sei stato invitato ad unirti a #{nomeapp}!
|
h1 Sei stato invitato ad unirti a #{nomeapp}!
|
||||||
p.subtitle Rete Italiana Scambi Orizzontali
|
p.subtitle Rete Italiana Scambio orizzontale
|
||||||
|
|
||||||
//- Body
|
//- Body
|
||||||
.email-body
|
.email-body
|
||||||
@@ -368,7 +368,7 @@ html(lang="it")
|
|||||||
| <strong>Fiducia:</strong> Base del nostro sistema di scambio
|
| <strong>Fiducia:</strong> Base del nostro sistema di scambio
|
||||||
.value-item
|
.value-item
|
||||||
span.benefit-icon 🚫
|
span.benefit-icon 🚫
|
||||||
| <strong>Non speculativo:</strong> I RIS non hanno valore in sé, si esauriscono negli scambi
|
| <strong>Non speculativo:</strong> I RIS non hanno valore in sé, ma solo come <strong>unità di misura</strong> degli scambi
|
||||||
.value-item
|
.value-item
|
||||||
span.benefit-icon 🌍
|
span.benefit-icon 🌍
|
||||||
| <strong>Sostenibilità:</strong> Promuoviamo stili di vita sani e naturali
|
| <strong>Sostenibilità:</strong> Promuoviamo stili di vita sani e naturali
|
||||||
@@ -415,7 +415,7 @@ html(lang="it")
|
|||||||
.divider
|
.divider
|
||||||
p Hai ricevuto questa email perché #{usernameInvitante || 'un membro della comunità'} ti ha invitato su #{nomeapp}
|
p Hai ricevuto questa email perché #{usernameInvitante || 'un membro della comunità'} ti ha invitato su #{nomeapp}
|
||||||
p(style="margin-top: 12px; font-size: 12px;")
|
p(style="margin-top: 12px; font-size: 12px;")
|
||||||
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambi Orizzontali
|
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambio orizzontale
|
||||||
p(style="margin-top: 8px; font-size: 11px; color: #999;")
|
p(style="margin-top: 8px; font-size: 11px; color: #999;")
|
||||||
| Se non sei interessato, puoi semplicemente ignorare questa email.
|
| Se non sei interessato, puoi semplicemente ignorare questa email.
|
||||||
p(style="margin-top: 12px; font-size: 12px;")
|
p(style="margin-top: 12px; font-size: 12px;")
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ html
|
|||||||
tr
|
tr
|
||||||
td.logoContainer
|
td.logoContainer
|
||||||
a(href=baseurl)
|
a(href=baseurl)
|
||||||
img.logo(src=baseurl+"/public/images/logo.png", alt="Logo")
|
img.logo(src=baseurl+"/images/logo.png", alt="Logo")
|
||||||
|
|
||||||
if dataemail.templ.testoheadermail_out
|
if dataemail.templ.testoheadermail_out
|
||||||
tr
|
tr
|
||||||
|
|||||||
@@ -1,37 +1,307 @@
|
|||||||
p Ciao #{name},
|
doctype html
|
||||||
p Hai ricevuto
|
html(lang="it")
|
||||||
strong #{qty} #{symbol}
|
head
|
||||||
if groupDestoContoCom
|
meta(charset="UTF-8")
|
||||||
| sul conto
|
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||||
strong #{groupDestoContoCom}
|
style(type="text/css").
|
||||||
span da parte di #{mittente} in data #{transactionDate} sul
|
* {
|
||||||
strong #{nomecircuito} !
|
|
||||||
if causalDest
|
|
||||||
p <br>
|
|
||||||
p Descrizione: #{causalDest}
|
|
||||||
if causale
|
|
||||||
p <br>
|
|
||||||
p Commento di #{mittente}: #{causale}
|
|
||||||
p <br>
|
|
||||||
p Apri
|
|
||||||
strong <a href=#{strlinksito} target="_blank">#{nomeapp}</a>
|
|
||||||
span per vedere il tuo nuovo saldo.
|
|
||||||
p <br>
|
|
||||||
p Cordiali Saluti
|
|
||||||
p Supporto #{nomeapp}
|
|
||||||
|
|
||||||
style(type="text/css").
|
|
||||||
html, body {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
p {
|
}
|
||||||
margin: 4px; /* Imposta il margine a 0 per i paragrafi */
|
|
||||||
}
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-logo {
|
||||||
|
width: 120px;
|
||||||
|
height: auto;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header {
|
||||||
|
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 40px 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header h1 {
|
||||||
|
margin: 0 0 8px 0;
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header .subtitle {
|
||||||
|
margin: 8px 0 0 0;
|
||||||
|
font-size: 17px;
|
||||||
|
opacity: 0.95;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.money-icon {
|
||||||
|
font-size: 56px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-body {
|
||||||
|
padding: 32px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-text {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-card {
|
||||||
|
background: linear-gradient(135deg, #f8fdf8 0%, #e8f5e9 100%);
|
||||||
|
border: 2px solid #7cb342;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 24px;
|
||||||
|
margin: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-amount {
|
||||||
|
font-size: 42px;
|
||||||
|
color: #558b2f;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-label {
|
||||||
|
font-size: 14px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #558b2f;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-detail {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #555;
|
||||||
|
margin: 8px 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-detail strong {
|
||||||
|
color: #558b2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider-line {
|
||||||
|
height: 1px;
|
||||||
|
background: #c8e6c9;
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight-box {
|
||||||
|
background: #fff8dc;
|
||||||
|
border-left: 4px solid #7cb342;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight-box p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #1a1a1a;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight-box .label {
|
||||||
|
font-size: 13px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #558b2f;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section {
|
||||||
|
text-align: center;
|
||||||
|
margin: 24px 0;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1a1a1a;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 16px 48px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
background: linear-gradient(135deg, #7cb342 0%, #558b2f 100%);
|
||||||
|
border-radius: 50px;
|
||||||
|
text-decoration: none;
|
||||||
|
box-shadow: 0 4px 12px rgba(124, 179, 66, 0.3);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box {
|
||||||
|
background: #e8f5e9;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 16px;
|
||||||
|
margin: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-box p {
|
||||||
|
margin: 0;
|
||||||
|
color: #2e7d32;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-footer {
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
background: #f8f9fa;
|
||||||
|
color: #777;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-footer p {
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(to right, transparent, #e0e0e0, transparent);
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header {
|
||||||
|
padding: 24px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-header h1 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.money-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-body {
|
||||||
|
padding: 20px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-amount {
|
||||||
|
font-size: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
padding: 14px 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.grande {
|
body
|
||||||
font-size: 1.25rem;
|
.email-container
|
||||||
font-weight: bold;
|
//- Header
|
||||||
}
|
.email-header
|
||||||
|
img.header-logo(src=baseurl+'/images/logo.png' alt='RISO - Rete Italiana Scambio Orizzontale')
|
||||||
|
h1 Ciao <strong>#{username}</strong>, Hai ricevuto dei #{symbol}!
|
||||||
|
p.subtitle Nuova transazione sul #{nomecircuito}
|
||||||
|
|
||||||
|
//- Body
|
||||||
|
.email-body
|
||||||
|
//- Intro
|
||||||
|
|
||||||
|
//- Transaction card
|
||||||
|
.transaction-card
|
||||||
|
.transaction-label Importo Ricevuto
|
||||||
|
.transaction-amount +#{qty} #{symbol}
|
||||||
|
|
||||||
|
.divider-line
|
||||||
|
|
||||||
|
.transaction-detail(style="font-size: 18px; margin-top: 12px;")
|
||||||
|
strong Nuovo Saldo:
|
||||||
|
span(style="color: #558b2f; font-weight: 700; font-size: 20px;") #{saldoAttuale} #{symbol}
|
||||||
|
|
||||||
|
.transaction-detail
|
||||||
|
strong Da:
|
||||||
|
| #{mittente}
|
||||||
|
|
||||||
|
.transaction-detail
|
||||||
|
strong Data:
|
||||||
|
| #{transactionDate}
|
||||||
|
|
||||||
|
if groupDestoContoCom
|
||||||
|
.transaction-detail
|
||||||
|
strong Conto:
|
||||||
|
| #{groupDestoContoCom}
|
||||||
|
|
||||||
|
.transaction-detail
|
||||||
|
strong Circuito:
|
||||||
|
| #{nomecircuito}
|
||||||
|
|
||||||
|
//- Descrizione
|
||||||
|
if causalDest
|
||||||
|
.highlight-box
|
||||||
|
.label 📝 Descrizione
|
||||||
|
p #{causalDest}
|
||||||
|
|
||||||
|
//- Commento mittente
|
||||||
|
if causale
|
||||||
|
.highlight-box
|
||||||
|
.label 💬 Commento di #{mittente}
|
||||||
|
p "#{causale}"
|
||||||
|
|
||||||
|
//- Info box
|
||||||
|
.info-box
|
||||||
|
p
|
||||||
|
| ✓ La transazione è stata registrata con successo<br>
|
||||||
|
| ✓ Il tuo saldo è stato aggiornato
|
||||||
|
|
||||||
|
//- CTA
|
||||||
|
.cta-section
|
||||||
|
.cta-title Accedi alla App
|
||||||
|
a.cta-button(href=strlinksito target="_blank") Apri #{nomeapp}
|
||||||
|
|
||||||
|
//- Footer
|
||||||
|
.email-footer
|
||||||
|
.divider
|
||||||
|
p Hai ricevuto questa email perché hai ricevuto una transazione su #{nomeapp}
|
||||||
|
p(style="margin-top: 12px; font-size: 12px;")
|
||||||
|
| #{new Date().getFullYear()} #{nomeapp} - Rete Italiana Scambi Orizzontali
|
||||||
|
p(style="margin-top: 12px; font-size: 12px;")
|
||||||
|
| 🍚 Comunità · Fiducia · Scambi Solidali · Sostenibilità
|
||||||
@@ -72,3 +72,9 @@ Gio 20/11 ORE 20:55: USER [surya1977]: ciao
|
|||||||
Gio 20/11 ORE 21:15: USER [surya1977]: ciao
|
Gio 20/11 ORE 21:15: USER [surya1977]: ciao
|
||||||
|
|
||||||
Gio 20/11 ORE 21:24: USER [surya5]: ciao
|
Gio 20/11 ORE 21:24: USER [surya5]: ciao
|
||||||
|
|
||||||
|
Sab 22/11 ORE 23:30: USER [surya1977]: ciao
|
||||||
|
|
||||||
|
Dom 23/11 ORE 00:02: USER [perseo5]: ciao
|
||||||
|
|
||||||
|
Dom 23/11 ORE 00:22: USER [perseo7]: ciao
|
||||||
|
|||||||
28
logtrans.txt
28
logtrans.txt
@@ -488,4 +488,30 @@ Ven 03/10 ORE 15:03: [<b>Euro</b>]: Inviate Monete da paoloar77 a piuchebuono 6
|
|||||||
|
|
||||||
Saldi:
|
Saldi:
|
||||||
paoloar77: -312.80 €]
|
paoloar77: -312.80 €]
|
||||||
piuchebuono: 10552.82 €]
|
piuchebuono: 10552.82 €]
|
||||||
|
Dom 23/11 ORE 00:52: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 1 RIS [causale: prova 1 Ciaoooooooo]
|
||||||
|
|
||||||
|
Saldi:
|
||||||
|
perseo9: -1.00 RIS]
|
||||||
|
surya1977: 123.95 RIS]
|
||||||
|
Dom 23/11 ORE 00:56: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 2 RIS [causale: Eccolo!
|
||||||
|
]
|
||||||
|
|
||||||
|
Saldi:
|
||||||
|
perseo9: -3.00 RIS]
|
||||||
|
surya1977: 125.95 RIS]
|
||||||
|
Dom 23/11 ORE 01:00: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 3 RIS [causale: aaaaa]
|
||||||
|
|
||||||
|
Saldi:
|
||||||
|
perseo9: -6.00 RIS]
|
||||||
|
surya1977: 128.95 RIS]
|
||||||
|
Dom 23/11 ORE 01:03: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 4 RIS [causale: BBB]
|
||||||
|
|
||||||
|
Saldi:
|
||||||
|
perseo9: -14.00 RIS]
|
||||||
|
surya1977: 136.95 RIS]
|
||||||
|
Dom 23/11 ORE 01:10: [<b>Circuito RIS Italia</b>]: Inviate Monete da perseo9 a surya1977 5 RIS [causale: sdasdas]
|
||||||
|
|
||||||
|
Saldi:
|
||||||
|
perseo9: -19.00 RIS]
|
||||||
|
surya1977: 141.95 RIS]
|
||||||
@@ -21,14 +21,14 @@ class UserController {
|
|||||||
async register(req, res) {
|
async register(req, res) {
|
||||||
try {
|
try {
|
||||||
tools.mylog('POST /users - Registration');
|
tools.mylog('POST /users - Registration');
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
const validationError = validateRegistration(req.body);
|
const validationError = validateRegistration(req.body);
|
||||||
if (validationError) {
|
if (validationError) {
|
||||||
await tools.snooze(5000);
|
await tools.snooze(5000);
|
||||||
return res.status(400).send({
|
return res.status(400).send({
|
||||||
code: validationError.code,
|
code: validationError.code,
|
||||||
msg: validationError.message
|
msg: validationError.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,33 +38,29 @@ class UserController {
|
|||||||
// Check security (IP bans, block words, etc.)
|
// Check security (IP bans, block words, etc.)
|
||||||
const securityCheck = await this._performSecurityChecks(userData, req);
|
const securityCheck = await this._performSecurityChecks(userData, req);
|
||||||
if (securityCheck.blocked) {
|
if (securityCheck.blocked) {
|
||||||
return res.status(securityCheck.status).send({
|
return res.status(securityCheck.status).send({
|
||||||
code: securityCheck.code,
|
code: securityCheck.code,
|
||||||
msg: securityCheck.message
|
msg: securityCheck.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process registration
|
// Process registration
|
||||||
const result = await this.registrationService.registerUser(userData, req);
|
const result = await this.registrationService.registerUser(userData, req);
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
return res.status(400).send({
|
return res.status(400).send({
|
||||||
code: result.code,
|
code: result.code,
|
||||||
msg: result.message
|
msg: result.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send response with tokens
|
// Send response with tokens
|
||||||
res
|
res.header('x-auth', result.token).header('x-refrtok', result.refreshToken).send(result.user);
|
||||||
.header('x-auth', result.token)
|
|
||||||
.header('x-refrtok', result.refreshToken)
|
|
||||||
.send(result.user);
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in registration:', error.message);
|
console.error('Error in registration:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,6 +71,7 @@ class UserController {
|
|||||||
*/
|
*/
|
||||||
async login(req, res) {
|
async login(req, res) {
|
||||||
try {
|
try {
|
||||||
|
console.log('LOGIN');
|
||||||
const { username, password, idapp, keyappid } = req.body;
|
const { username, password, idapp, keyappid } = req.body;
|
||||||
|
|
||||||
// Validate API key
|
// Validate API key
|
||||||
@@ -85,42 +82,35 @@ class UserController {
|
|||||||
// Validate input
|
// Validate input
|
||||||
const validationError = validateLogin(req.body);
|
const validationError = validateLogin(req.body);
|
||||||
if (validationError) {
|
if (validationError) {
|
||||||
return res.status(400).send({
|
return res.status(400).send({
|
||||||
code: validationError.code,
|
code: validationError.code,
|
||||||
msg: validationError.message
|
msg: validationError.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt login
|
// Attempt login
|
||||||
const result = await this.authService.authenticate(
|
const result = await this.authService.authenticate(idapp, username, password, req);
|
||||||
idapp,
|
|
||||||
username,
|
console.log('attempt...', result);
|
||||||
password,
|
|
||||||
req
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
return res.status(result.status).send({
|
return res.status(result.status).send({
|
||||||
code: result.code,
|
code: result.code,
|
||||||
msg: result.message
|
msg: result.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send response with tokens
|
// Send response with tokens
|
||||||
res
|
res.header('x-auth', result.token).header('x-refrtok', result.refreshToken).send({
|
||||||
.header('x-auth', result.token)
|
usertosend: result.user,
|
||||||
.header('x-refrtok', result.refreshToken)
|
code: server_constants.RIS_CODE_OK,
|
||||||
.send({
|
subsExistonDb: result.subsExistonDb,
|
||||||
usertosend: result.user,
|
});
|
||||||
code: server_constants.RIS_CODE_OK,
|
|
||||||
subsExistonDb: result.subsExistonDb
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in login:', error.message);
|
console.error('Error in login:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC,
|
code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC,
|
||||||
msgerr: error.message
|
msgerr: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,20 +131,14 @@ class UserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get user profile
|
// Get user profile
|
||||||
const profile = await this.userService.getUserProfile(
|
const profile = await this.userService.getUserProfile(idapp, username, usernameOrig, perm);
|
||||||
idapp,
|
|
||||||
username,
|
|
||||||
usernameOrig,
|
|
||||||
perm
|
|
||||||
);
|
|
||||||
|
|
||||||
res.send(profile);
|
res.send(profile);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in getProfile:', error.message);
|
console.error('Error in getProfile:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,21 +152,14 @@ class UserController {
|
|||||||
const username = req.user.username;
|
const username = req.user.username;
|
||||||
const { idapp, circuitId, groupname, lastdr } = req.body;
|
const { idapp, circuitId, groupname, lastdr } = req.body;
|
||||||
|
|
||||||
const result = await this.userService.updateUserBalance(
|
const result = await this.userService.updateUserBalance(idapp, username, circuitId, groupname, lastdr);
|
||||||
idapp,
|
|
||||||
username,
|
|
||||||
circuitId,
|
|
||||||
groupname,
|
|
||||||
lastdr
|
|
||||||
);
|
|
||||||
|
|
||||||
res.send({ ris: result });
|
res.send({ ris: result });
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in updateSaldo:', error.message);
|
console.error('Error in updateSaldo:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,14 +174,13 @@ class UserController {
|
|||||||
const { idapp } = req.body;
|
const { idapp } = req.body;
|
||||||
|
|
||||||
const friends = await this.userService.getUserFriends(idapp, username);
|
const friends = await this.userService.getUserFriends(idapp, username);
|
||||||
|
|
||||||
res.send(friends);
|
|
||||||
|
|
||||||
|
res.send(friends);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in getFriends:', error.message);
|
console.error('Error in getFriends:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,28 +196,20 @@ class UserController {
|
|||||||
|
|
||||||
// Security check
|
// Security check
|
||||||
if (!this._canExecuteFriendCommand(req.user, usernameOrig, usernameDest, cmd)) {
|
if (!this._canExecuteFriendCommand(req.user, usernameOrig, usernameDest, cmd)) {
|
||||||
return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({
|
return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({
|
||||||
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
||||||
msg: ''
|
msg: '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.userService.executeFriendCommand(
|
const result = await this.userService.executeFriendCommand(req, idapp, usernameOrig, usernameDest, cmd, value);
|
||||||
req,
|
|
||||||
idapp,
|
|
||||||
usernameOrig,
|
|
||||||
usernameDest,
|
|
||||||
cmd,
|
|
||||||
value
|
|
||||||
);
|
|
||||||
|
|
||||||
res.send(result);
|
res.send(result);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in executeFriendCommand:', error.message);
|
console.error('Error in executeFriendCommand:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,14 +224,13 @@ class UserController {
|
|||||||
const { idapp } = req.body;
|
const { idapp } = req.body;
|
||||||
|
|
||||||
const groups = await this.userService.getUserGroups(idapp, username, req);
|
const groups = await this.userService.getUserGroups(idapp, username, req);
|
||||||
|
|
||||||
res.send(groups);
|
|
||||||
|
|
||||||
|
res.send(groups);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in getGroups:', error.message);
|
console.error('Error in getGroups:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,20 +244,14 @@ class UserController {
|
|||||||
const username = req.user.username;
|
const username = req.user.username;
|
||||||
const { idapp, nummovTodownload } = req.body;
|
const { idapp, nummovTodownload } = req.body;
|
||||||
|
|
||||||
const circuits = await this.userService.getUserCircuits(
|
const circuits = await this.userService.getUserCircuits(idapp, username, req.user, nummovTodownload);
|
||||||
idapp,
|
|
||||||
username,
|
|
||||||
req.user,
|
|
||||||
nummovTodownload
|
|
||||||
);
|
|
||||||
|
|
||||||
res.send(circuits);
|
|
||||||
|
|
||||||
|
res.send(circuits);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in getCircuits:', error.message);
|
console.error('Error in getCircuits:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,9 +276,8 @@ class UserController {
|
|||||||
|
|
||||||
res.status(200).send({
|
res.status(200).send({
|
||||||
token: result.token,
|
token: result.token,
|
||||||
refreshToken: result.refreshToken
|
refreshToken: result.refreshToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in refreshToken:', error.message);
|
console.error('Error in refreshToken:', error.message);
|
||||||
res.status(500).send({ error: 'Errore interno del server' });
|
res.status(500).send({ error: 'Errore interno del server' });
|
||||||
@@ -353,7 +313,6 @@ class UserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).send();
|
res.status(200).send();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in checkUsername:', error.message);
|
console.error('Error in checkUsername:', error.message);
|
||||||
res.status(400).send();
|
res.status(400).send();
|
||||||
@@ -371,11 +330,10 @@ class UserController {
|
|||||||
await this.userService.setUserPermissions(req.user._id, {
|
await this.userService.setUserPermissions(req.user._id, {
|
||||||
idapp,
|
idapp,
|
||||||
username,
|
username,
|
||||||
perm
|
perm,
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(200).send();
|
res.status(200).send();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in setPermissions:', error.message);
|
console.error('Error in setPermissions:', error.message);
|
||||||
res.status(400).send();
|
res.status(400).send();
|
||||||
@@ -392,28 +350,22 @@ class UserController {
|
|||||||
|
|
||||||
// Check permissions
|
// Check permissions
|
||||||
if (!this._hasAdminPermissions(req.user)) {
|
if (!this._hasAdminPermissions(req.user)) {
|
||||||
return res.status(404).send({
|
return res.status(404).send({
|
||||||
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED
|
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.userService.executeDbOperation(
|
const result = await this.userService.executeDbOperation(idapp, mydata, req, res);
|
||||||
idapp,
|
|
||||||
mydata,
|
|
||||||
req,
|
|
||||||
res
|
|
||||||
);
|
|
||||||
|
|
||||||
res.send({
|
res.send({
|
||||||
code: server_constants.RIS_CODE_OK,
|
code: server_constants.RIS_CODE_OK,
|
||||||
data: result
|
data: result,
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in executeDbOperation:', error.message);
|
console.error('Error in executeDbOperation:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -428,16 +380,15 @@ class UserController {
|
|||||||
|
|
||||||
const mapData = await this.userService.getMapInformation(idapp);
|
const mapData = await this.userService.getMapInformation(idapp);
|
||||||
|
|
||||||
res.send({
|
res.send({
|
||||||
code: server_constants.RIS_CODE_OK,
|
code: server_constants.RIS_CODE_OK,
|
||||||
ris: mapData
|
ris: mapData,
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in getMapInfo:', error.message);
|
console.error('Error in getMapInfo:', error.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
msg: error.message
|
msg: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -446,13 +397,21 @@ class UserController {
|
|||||||
|
|
||||||
_extractUserData(body) {
|
_extractUserData(body) {
|
||||||
const fields = [
|
const fields = [
|
||||||
'email', 'password', 'username', 'group', 'name',
|
'email',
|
||||||
'surname', 'idapp', 'keyappid', 'lang', 'profile',
|
'password',
|
||||||
'aportador_solidario'
|
'username',
|
||||||
|
'group',
|
||||||
|
'name',
|
||||||
|
'surname',
|
||||||
|
'idapp',
|
||||||
|
'keyappid',
|
||||||
|
'lang',
|
||||||
|
'profile',
|
||||||
|
'aportador_solidario',
|
||||||
];
|
];
|
||||||
|
|
||||||
const userData = {};
|
const userData = {};
|
||||||
fields.forEach(field => {
|
fields.forEach((field) => {
|
||||||
if (body[field] !== undefined) {
|
if (body[field] !== undefined) {
|
||||||
userData[field] = body[field];
|
userData[field] = body[field];
|
||||||
}
|
}
|
||||||
@@ -469,16 +428,14 @@ class UserController {
|
|||||||
|
|
||||||
async _performSecurityChecks(userData, req) {
|
async _performSecurityChecks(userData, req) {
|
||||||
const { User } = require('../models/user');
|
const { User } = require('../models/user');
|
||||||
|
|
||||||
// Check for blocked words
|
// Check for blocked words
|
||||||
if (tools.blockwords(userData.username) ||
|
if (tools.blockwords(userData.username) || tools.blockwords(userData.name) || tools.blockwords(userData.surname)) {
|
||||||
tools.blockwords(userData.name) ||
|
|
||||||
tools.blockwords(userData.surname)) {
|
|
||||||
await tools.snooze(5000);
|
await tools.snooze(5000);
|
||||||
return {
|
return {
|
||||||
blocked: true,
|
blocked: true,
|
||||||
status: 404,
|
status: 404,
|
||||||
code: server_constants.RIS_CODE_ERR
|
code: server_constants.RIS_CODE_ERR,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,11 +449,11 @@ class UserController {
|
|||||||
tools.writeIPToBan(msg);
|
tools.writeIPToBan(msg);
|
||||||
await telegrambot.sendMsgTelegramToTheAdmin(userData.idapp, '‼️ BAN: ' + msg, true);
|
await telegrambot.sendMsgTelegramToTheAdmin(userData.idapp, '‼️ BAN: ' + msg, true);
|
||||||
await tools.snooze(5000);
|
await tools.snooze(5000);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
blocked: true,
|
blocked: true,
|
||||||
status: 400,
|
status: 400,
|
||||||
code: server_constants.RIS_CODE_BANIP
|
code: server_constants.RIS_CODE_BANIP,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,15 +464,12 @@ class UserController {
|
|||||||
|
|
||||||
_canExecuteFriendCommand(user, usernameOrig, usernameDest, cmd) {
|
_canExecuteFriendCommand(user, usernameOrig, usernameDest, cmd) {
|
||||||
const { User } = require('../models/user');
|
const { User } = require('../models/user');
|
||||||
|
|
||||||
if (User.isAdmin(user.perm) || User.isManager(user.perm)) {
|
if (User.isAdmin(user.perm) || User.isManager(user.perm)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const allowedCommands = [
|
const allowedCommands = [shared_consts.FRIENDSCMD.SETFRIEND, shared_consts.FRIENDSCMD.SETHANDSHAKE];
|
||||||
shared_consts.FRIENDSCMD.SETFRIEND,
|
|
||||||
shared_consts.FRIENDSCMD.SETHANDSHAKE
|
|
||||||
];
|
|
||||||
|
|
||||||
if (allowedCommands.includes(cmd)) {
|
if (allowedCommands.includes(cmd)) {
|
||||||
return usernameOrig === user.username || usernameDest === user.username;
|
return usernameOrig === user.username || usernameDest === user.username;
|
||||||
@@ -530,4 +484,4 @@ class UserController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = UserController;
|
module.exports = UserController;
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ exports.checkVerification = async (req, res) => {
|
|||||||
// Controlla se è stato verificato
|
// Controlla se è stato verificato
|
||||||
const verified = !!(user.profile?.teleg_id && user.profile?.username_telegram);
|
const verified = !!(user.profile?.teleg_id && user.profile?.username_telegram);
|
||||||
|
|
||||||
res.json({
|
return res.json({
|
||||||
verified: verified,
|
verified: verified,
|
||||||
username_telegram: user.profile?.username_telegram || null,
|
username_telegram: user.profile?.username_telegram || null,
|
||||||
teleg_id: user.profile?.teleg_id || null,
|
teleg_id: user.profile?.teleg_id || null,
|
||||||
|
|||||||
@@ -37,21 +37,23 @@ function clearFailedAttempts(username) {
|
|||||||
*/
|
*/
|
||||||
function checkBlocked(req, res, next) {
|
function checkBlocked(req, res, next) {
|
||||||
const { username } = req.body;
|
const { username } = req.body;
|
||||||
|
|
||||||
|
console.log('checkBlocked');
|
||||||
|
|
||||||
if (!username) {
|
if (!username) {
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
message: 'Username mancante'
|
message: 'Username mancante',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUserBlocked(username)) {
|
if (isUserBlocked(username)) {
|
||||||
const text = `Utente bloccato. Riprova più tardi. (username=${username})`;
|
const text = `Utente bloccato. Riprova più tardi. (username=${username})`;
|
||||||
console.log(text);
|
console.log(text);
|
||||||
return res.status(403).json({
|
return res.status(403).json({
|
||||||
message: 'Utente bloccato. Riprova più tardi.'
|
message: 'Utente bloccato. Riprova più tardi.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,30 +94,30 @@ function rateLimitByIP(req, res, next) {
|
|||||||
const tools = require('../tools/general');
|
const tools = require('../tools/general');
|
||||||
const ip = tools.getiPAddressUser(req);
|
const ip = tools.getiPAddressUser(req);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
if (!requestCounts[ip]) {
|
if (!requestCounts[ip]) {
|
||||||
requestCounts[ip] = {
|
requestCounts[ip] = {
|
||||||
count: 1,
|
count: 1,
|
||||||
resetTime: now + REQUEST_WINDOW
|
resetTime: now + REQUEST_WINDOW,
|
||||||
};
|
};
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now > requestCounts[ip].resetTime) {
|
if (now > requestCounts[ip].resetTime) {
|
||||||
// Reset window
|
// Reset window
|
||||||
requestCounts[ip] = {
|
requestCounts[ip] = {
|
||||||
count: 1,
|
count: 1,
|
||||||
resetTime: now + REQUEST_WINDOW
|
resetTime: now + REQUEST_WINDOW,
|
||||||
};
|
};
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestCounts[ip].count >= MAX_REQUESTS) {
|
if (requestCounts[ip].count >= MAX_REQUESTS) {
|
||||||
return res.status(429).json({
|
return res.status(429).json({
|
||||||
message: 'Troppi tentativi. Riprova più tardi.'
|
message: 'Troppi tentativi. Riprova più tardi.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
requestCounts[ip].count++;
|
requestCounts[ip].count++;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
@@ -125,9 +127,8 @@ function rateLimitByIP(req, res, next) {
|
|||||||
*/
|
*/
|
||||||
function cleanupBlockedUsers() {
|
function cleanupBlockedUsers() {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
Object.keys(failedLoginAttempts).forEach(username => {
|
Object.keys(failedLoginAttempts).forEach((username) => {
|
||||||
if (typeof failedLoginAttempts[username] === 'number' &&
|
if (typeof failedLoginAttempts[username] === 'number' && failedLoginAttempts[username] < now) {
|
||||||
failedLoginAttempts[username] < now) {
|
|
||||||
delete failedLoginAttempts[username];
|
delete failedLoginAttempts[username];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -146,5 +147,5 @@ module.exports = {
|
|||||||
shouldBlockUser,
|
shouldBlockUser,
|
||||||
rateLimitByIP,
|
rateLimitByIP,
|
||||||
MAX_FAILED_ATTEMPTS,
|
MAX_FAILED_ATTEMPTS,
|
||||||
BLOCK_DURATION
|
BLOCK_DURATION,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -899,7 +899,7 @@ CircuitSchema.statics.sendCoins = async function (onlycheck, idapp, usernameOrig
|
|||||||
let myuserDest = await User.getUserByUsername(idapp, extrarec.dest);
|
let myuserDest = await User.getUserByUsername(idapp, extrarec.dest);
|
||||||
|
|
||||||
// Invia una email al destinatario !
|
// Invia una email al destinatario !
|
||||||
await sendemail.sendEmail_RisRicevuti(myuserDest.lang, myuserDest, myuserDest.email, idapp, paramsrec);
|
await sendemail.sendEmail_RisRicevuti(myuserDest.lang, myuserDest, myuserDest.email, idapp, paramsrec, extrarec);
|
||||||
} else if (extrarec.groupdest || extrarec.contoComDest) {
|
} else if (extrarec.groupdest || extrarec.contoComDest) {
|
||||||
const groupDestoContoCom = extrarec.groupdest
|
const groupDestoContoCom = extrarec.groupdest
|
||||||
? extrarec.groupdest
|
? extrarec.groupdest
|
||||||
@@ -1142,7 +1142,8 @@ CircuitSchema.statics.getCircuitMyProvince = async function (idapp, username) {
|
|||||||
CircuitSchema.statics.createCircuitIfNotExist = async function (req, idapp, province, card) {
|
CircuitSchema.statics.createCircuitIfNotExist = async function (req, idapp, province, card) {
|
||||||
const { User } = require('../models/user');
|
const { User } = require('../models/user');
|
||||||
|
|
||||||
const useradmin = shared_consts.USER_ADMIN_CIRCUITS;
|
const admins = shared_consts.USER_ADMIN_CIRCUITS;
|
||||||
|
const useradmin = shared_consts.USER_ADMIN_SINGOLO;
|
||||||
|
|
||||||
let myrec = null;
|
let myrec = null;
|
||||||
try {
|
try {
|
||||||
@@ -1174,7 +1175,7 @@ CircuitSchema.statics.createCircuitIfNotExist = async function (req, idapp, prov
|
|||||||
totTransato: 0,
|
totTransato: 0,
|
||||||
totCircolante: 0,
|
totCircolante: 0,
|
||||||
date_created: new Date(),
|
date_created: new Date(),
|
||||||
admins: useradmin.map((username) => ({ username })),
|
admins: admins.map((username) => ({ username })),
|
||||||
askManagerToEnter: false,
|
askManagerToEnter: false,
|
||||||
sendEmailAfterAskingToEnter: false,
|
sendEmailAfterAskingToEnter: false,
|
||||||
circuitoIndipendente: false,
|
circuitoIndipendente: false,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
375
src/router/users_router_new.js
Executable file
375
src/router/users_router_new.js
Executable file
@@ -0,0 +1,375 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
const UserController = require('../controllers/UserController');
|
||||||
|
const { authenticate, authenticate_noerror, authenticate_withUser } = require('../middleware/authenticate');
|
||||||
|
const { checkBlocked } = require('../middleware/securityMiddleware');
|
||||||
|
|
||||||
|
// Initialize controller
|
||||||
|
const userController = new UserController();
|
||||||
|
|
||||||
|
// ===== PUBLIC ROUTES =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register new user
|
||||||
|
* POST /users
|
||||||
|
*/
|
||||||
|
router.post('/', (req, res) => userController.register(req, res));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if username exists
|
||||||
|
* GET /users/:idapp/:username
|
||||||
|
*/
|
||||||
|
router.get('/:idapp/:username', (req, res) => userController.checkUsername(req, res));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User login
|
||||||
|
* POST /users/login
|
||||||
|
*/
|
||||||
|
router.post('/login', checkBlocked, (req, res) => userController.login(req, res));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh authentication token
|
||||||
|
* POST /users/newtok
|
||||||
|
*/
|
||||||
|
router.post('/newtok', (req, res) => userController.refreshToken(req, res));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user activities (public profile)
|
||||||
|
* POST /users/activities
|
||||||
|
*/
|
||||||
|
router.post('/activities', authenticate_noerror, (req, res) =>
|
||||||
|
userController.getProfile(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
// ===== AUTHENTICATED ROUTES =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user profile
|
||||||
|
* POST /users/profile
|
||||||
|
*/
|
||||||
|
router.post('/profile', authenticate, (req, res) =>
|
||||||
|
userController.getProfile(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user panel info (admin/manager only)
|
||||||
|
* POST /users/panel
|
||||||
|
*/
|
||||||
|
router.post('/panel', authenticate, (req, res) => {
|
||||||
|
const { User } = require('../models/user');
|
||||||
|
const server_constants = require('../tools/server_constants');
|
||||||
|
|
||||||
|
if (!req.user || (!User.isAdmin(req.user.perm) &&
|
||||||
|
!User.isManager(req.user.perm) &&
|
||||||
|
!User.isFacilitatore(req.user.perm))) {
|
||||||
|
return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({
|
||||||
|
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
||||||
|
msg: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
userController.getProfile(req, res);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update user balance
|
||||||
|
* POST /users/updatesaldo
|
||||||
|
*/
|
||||||
|
router.post('/updatesaldo', authenticate, (req, res) =>
|
||||||
|
userController.updateSaldo(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user's friends
|
||||||
|
* POST /users/friends
|
||||||
|
*/
|
||||||
|
router.post('/friends', authenticate, (req, res) =>
|
||||||
|
userController.getFriends(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute friend command
|
||||||
|
* POST /users/friends/cmd
|
||||||
|
*/
|
||||||
|
router.post('/friends/cmd', authenticate, (req, res) =>
|
||||||
|
userController.executeFriendCommand(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send command to user
|
||||||
|
* POST /users/sendcmd
|
||||||
|
*/
|
||||||
|
router.post('/sendcmd', authenticate, (req, res) => {
|
||||||
|
const usernameLogged = req.user.username;
|
||||||
|
const { idapp, usernameOrig, usernameDest, cmd, value } = req.body;
|
||||||
|
|
||||||
|
userController.userService.sendCommand(
|
||||||
|
req, idapp, usernameOrig, usernameDest, cmd, value
|
||||||
|
).then(result => res.send(result))
|
||||||
|
.catch(error => res.status(400).send({ error: error.message }));
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user's groups
|
||||||
|
* POST /users/groups
|
||||||
|
*/
|
||||||
|
router.post('/groups', authenticate, (req, res) =>
|
||||||
|
userController.getGroups(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute group command
|
||||||
|
* POST /users/groups/cmd
|
||||||
|
*/
|
||||||
|
router.post('/groups/cmd', authenticate, (req, res) => {
|
||||||
|
const usernameLogged = req.user.username;
|
||||||
|
const { idapp, usernameOrig, groupnameDest, cmd, value } = req.body;
|
||||||
|
|
||||||
|
userController.userService.executeGroupCommand(
|
||||||
|
idapp, usernameOrig, groupnameDest, cmd, value, usernameLogged
|
||||||
|
).then(result => res.send(result))
|
||||||
|
.catch(error => res.status(400).send({ error: error.message }));
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user's circuits
|
||||||
|
* POST /users/circuits
|
||||||
|
*/
|
||||||
|
router.post('/circuits', authenticate_withUser, (req, res) =>
|
||||||
|
userController.getCircuits(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute circuit command
|
||||||
|
* POST /users/circuits/cmd
|
||||||
|
*/
|
||||||
|
router.post('/circuits/cmd', authenticate, async (req, res) => {
|
||||||
|
const usernameLogged = req.user.username;
|
||||||
|
const { idapp, usernameOrig, circuitname, cmd, value, extrarec } = req.body;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await userController.userService.executeCircuitCommand(
|
||||||
|
idapp, usernameOrig, circuitname, cmd, value, usernameLogged, extrarec
|
||||||
|
);
|
||||||
|
res.send(result);
|
||||||
|
} catch (error) {
|
||||||
|
res.status(400).send({ error: error.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logout user
|
||||||
|
* DELETE /users/me/token
|
||||||
|
*/
|
||||||
|
router.delete('/me/token', authenticate_withUser, (req, res) =>
|
||||||
|
userController.logout(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set user permissions
|
||||||
|
* POST /users/setperm
|
||||||
|
*/
|
||||||
|
router.post('/setperm', authenticate, (req, res) =>
|
||||||
|
userController.setPermissions(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get last movements/transactions
|
||||||
|
* POST /users/lastmovs
|
||||||
|
*/
|
||||||
|
router.post('/lastmovs', authenticate, async (req, res) => {
|
||||||
|
const { nummov, nummov_uscita, idapp } = req.body;
|
||||||
|
const server_constants = require('../tools/server_constants');
|
||||||
|
const tools = require('../tools/general');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { Movement } = require('../models/movement');
|
||||||
|
|
||||||
|
let last_transactions = [];
|
||||||
|
if (nummov) {
|
||||||
|
last_transactions = await Movement.getLastN_Transactions(idapp, nummov, nummov_uscita);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({ code: server_constants.RIS_CODE_OK, last_transactions });
|
||||||
|
} catch (e) {
|
||||||
|
tools.mylogserr('Error lastmovs: ', e);
|
||||||
|
res.status(400).send();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set receive RIS flag
|
||||||
|
* POST /users/receiveris
|
||||||
|
*/
|
||||||
|
router.post('/receiveris', authenticate, async (req, res) => {
|
||||||
|
const username = req.user?.username || '';
|
||||||
|
const { groupname, idapp } = req.body;
|
||||||
|
const { User } = require('../models/user');
|
||||||
|
const { MyGroup } = require('../models/mygroup');
|
||||||
|
const server_constants = require('../tools/server_constants');
|
||||||
|
const tools = require('../tools/general');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!username) {
|
||||||
|
return res.send({ code: server_constants.RIS_CODE_ERR });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupname) {
|
||||||
|
await MyGroup.setReceiveRisGroup(idapp, groupname);
|
||||||
|
} else {
|
||||||
|
await User.setReceiveRis(idapp, username);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({ code: server_constants.RIS_CODE_OK });
|
||||||
|
} catch (err) {
|
||||||
|
tools.mylog('ERRORE IN receiveris: ' + err.message);
|
||||||
|
res.status(400).send();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List registration links
|
||||||
|
* POST /users/listlinkreg
|
||||||
|
*/
|
||||||
|
router.post('/listlinkreg', authenticate, async (req, res) => {
|
||||||
|
const username = req.user?.username || '';
|
||||||
|
const { idapp } = req.body;
|
||||||
|
const { User } = require('../models/user');
|
||||||
|
const server_constants = require('../tools/server_constants');
|
||||||
|
const tools = require('../tools/general');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!username) {
|
||||||
|
return res.send({ code: server_constants.RIS_CODE_ERR });
|
||||||
|
}
|
||||||
|
|
||||||
|
await User.setLinkReg(idapp, username);
|
||||||
|
res.send({ code: server_constants.RIS_CODE_OK });
|
||||||
|
} catch (err) {
|
||||||
|
tools.mylog('ERRORE IN listlinkreg: ' + err.message);
|
||||||
|
res.status(400).send();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ===== ADMIN ROUTES =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update user (admin only)
|
||||||
|
* PATCH /users/:id
|
||||||
|
*/
|
||||||
|
router.patch('/:id', authenticate, (req, res) => {
|
||||||
|
const { User } = require('../models/user');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const shared_consts = require('../tools/shared_nodejs');
|
||||||
|
const server_constants = require('../tools/server_constants');
|
||||||
|
const tools = require('../tools/general');
|
||||||
|
|
||||||
|
const id = req.params.id;
|
||||||
|
const body = _.pick(req.body.user, shared_consts.fieldsUserToChange());
|
||||||
|
|
||||||
|
tools.mylogshow('PATCH USER: ', id);
|
||||||
|
|
||||||
|
if (!User.isAdmin(req.user.perm)) {
|
||||||
|
return res.status(server_constants.RIS_CODE_ERR_UNAUTHORIZED).send({
|
||||||
|
code: server_constants.RIS_CODE_ERR_UNAUTHORIZED,
|
||||||
|
msg: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
User.findByIdAndUpdate(id, { $set: body })
|
||||||
|
.then((user) => {
|
||||||
|
tools.mylogshow(' USER TO MODIFY: ', user);
|
||||||
|
if (!user) {
|
||||||
|
return res.status(404).send();
|
||||||
|
}
|
||||||
|
res.send({ code: server_constants.RIS_CODE_OK, msg: '' });
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
tools.mylogserr('Error patch USER: ', e);
|
||||||
|
res.status(400).send();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute database operation (admin only)
|
||||||
|
* POST /users/dbop
|
||||||
|
*/
|
||||||
|
router.post('/dbop', authenticate, (req, res) =>
|
||||||
|
userController.executeDbOperation(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute user database operation
|
||||||
|
* POST /users/dbopuser
|
||||||
|
*/
|
||||||
|
router.post('/dbopuser', authenticate, async (req, res) => {
|
||||||
|
const { mydata, idapp } = req.body;
|
||||||
|
const server_constants = require('../tools/server_constants');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await userController.userService.executeUserDbOperation(
|
||||||
|
idapp,
|
||||||
|
mydata,
|
||||||
|
req.user.username
|
||||||
|
);
|
||||||
|
|
||||||
|
res.send({ code: server_constants.RIS_CODE_OK, ris: result });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get map information
|
||||||
|
* POST /users/infomap
|
||||||
|
*/
|
||||||
|
router.post('/infomap', authenticate, (req, res) =>
|
||||||
|
userController.getMapInfo(req, res)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Management telegram operations
|
||||||
|
* POST /users/mgt
|
||||||
|
*/
|
||||||
|
router.post('/mgt', authenticate_withUser, async (req, res) => {
|
||||||
|
const { mydata, idapp } = req.body;
|
||||||
|
const telegrambot = require('../telegram/telegrambot');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { nummsgsent, numrec, textsent, text } =
|
||||||
|
await telegrambot.sendMsgFromSiteToBotTelegram(idapp, req.user, mydata);
|
||||||
|
|
||||||
|
res.send({ numrec, nummsgsent, textsent, text });
|
||||||
|
} catch (e) {
|
||||||
|
res.status(400).send({ error: e.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// ===== TEST ROUTES (Development only) =====
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'development' || process.env.LOCALE === '1') {
|
||||||
|
router.post('/test1', async (req, res) => {
|
||||||
|
const { User } = require('../models/user');
|
||||||
|
const sendemail = require('../sendemail');
|
||||||
|
|
||||||
|
const user = await User.findOne({
|
||||||
|
idapp: 1,
|
||||||
|
username: 'paoloar77'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
await sendemail.sendEmail_Registration(
|
||||||
|
user.lang,
|
||||||
|
user.email,
|
||||||
|
user,
|
||||||
|
user.idapp,
|
||||||
|
user.linkreg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({ success: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -500,10 +500,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getPathEmail(idapp, email_template) {
|
getPathEmail(idapp, email_template) {
|
||||||
const RISO_TEMPLATES = ['reg_notifica_all_invitante'];
|
const RISO_TEMPLATES = ['reg_notifica_all_invitante', 'reg_email_benvenuto_ammesso'];
|
||||||
|
|
||||||
if (RISO_TEMPLATES.includes(email_template)) {
|
if (idapp === '13') {
|
||||||
return tools.RISO_STR_PATH + '/' + email_template;
|
if (RISO_TEMPLATES.includes(email_template)) {
|
||||||
|
return tools.RISO_STR_PATH + '/' + email_template;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 'defaultSite/' + email_template;
|
return 'defaultSite/' + email_template;
|
||||||
},
|
},
|
||||||
@@ -525,6 +527,8 @@ module.exports = {
|
|||||||
usernameInvitante: user.aportador_solidario,
|
usernameInvitante: user.aportador_solidario,
|
||||||
nomeInvitante: nomecognomeInvitante.trim(),
|
nomeInvitante: nomecognomeInvitante.trim(),
|
||||||
nomeInvitato: await User.getNameSurnameEUsernameByUsername(idapp, user.username),
|
nomeInvitato: await User.getNameSurnameEUsernameByUsername(idapp, user.username),
|
||||||
|
usernameInvitato: user.username,
|
||||||
|
emailInvitato: user.email,
|
||||||
user,
|
user,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -534,7 +538,7 @@ module.exports = {
|
|||||||
|
|
||||||
if (user.verified_email) {
|
if (user.verified_email) {
|
||||||
// se l'utente è già stato verificata la sua email, allora gli mando direttamente la email di invito.
|
// se l'utente è già stato verificata la sua email, allora gli mando direttamente la email di invito.
|
||||||
quale_email_inviare = 'reg_email_benvenuto_ammesso/' + lang;
|
quale_email_inviare = this.getPathEmail(idapp, 'reg_email_benvenuto_ammesso') + '/' + lang;
|
||||||
} else {
|
} else {
|
||||||
// altrimenti gli mando l'email con la richiesta di Verifica email
|
// altrimenti gli mando l'email con la richiesta di Verifica email
|
||||||
quale_email_inviare = tools.getpathregByIdApp(idapp, lang);
|
quale_email_inviare = tools.getpathregByIdApp(idapp, lang);
|
||||||
@@ -583,7 +587,7 @@ module.exports = {
|
|||||||
sendEmail_InvitaAmico: async function (lang, emailto, user, idapp, dati) {
|
sendEmail_InvitaAmico: async function (lang, emailto, user, idapp, dati) {
|
||||||
try {
|
try {
|
||||||
const nomecognomeInvitante = await User.getNameSurnameByUsername(idapp, dati.usernameInvitante, true);
|
const nomecognomeInvitante = await User.getNameSurnameByUsername(idapp, dati.usernameInvitante, true);
|
||||||
|
|
||||||
let mylocalsconf = {
|
let mylocalsconf = {
|
||||||
idapp,
|
idapp,
|
||||||
dataemail: await this.getdataemail(idapp),
|
dataemail: await this.getdataemail(idapp),
|
||||||
@@ -621,6 +625,7 @@ module.exports = {
|
|||||||
linkRegistrazione: this.getlinkInvitoReg(idapp, dati),
|
linkRegistrazione: this.getlinkInvitoReg(idapp, dati),
|
||||||
emailto: emailto,
|
emailto: emailto,
|
||||||
usernameInvitante: dati.usernameInvitante,
|
usernameInvitante: dati.usernameInvitante,
|
||||||
|
ammessoUtente: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ris = await this.sendEmail_base('reg_email_benvenuto_ammesso/' + lang, emailto, mylocalsconf, '');
|
const ris = await this.sendEmail_base('reg_email_benvenuto_ammesso/' + lang, emailto, mylocalsconf, '');
|
||||||
@@ -705,17 +710,19 @@ module.exports = {
|
|||||||
await this.sendEmail_base('resetpwd/' + lang, emailto, mylocalsconf, '');
|
await this.sendEmail_base('resetpwd/' + lang, emailto, mylocalsconf, '');
|
||||||
},
|
},
|
||||||
|
|
||||||
sendEmail_RisRicevuti: async function (lang, userDest, emailto, idapp, myrec) {
|
sendEmail_RisRicevuti: async function (lang, userDest, emailto, idapp, myrec, extrarec) {
|
||||||
console.log('sendEmail_RisRicevuti');
|
console.log('sendEmail_RisRicevuti');
|
||||||
|
|
||||||
let mylocalsconf = {
|
let mylocalsconf = {
|
||||||
idapp,
|
idapp,
|
||||||
|
baseurl: tools.getHostByIdApp(idapp),
|
||||||
dataemail: await this.getdataemail(idapp),
|
dataemail: await this.getdataemail(idapp),
|
||||||
locale: lang,
|
locale: lang,
|
||||||
nomeapp: tools.getNomeAppByIdApp(idapp),
|
nomeapp: tools.getNomeAppByIdApp(idapp),
|
||||||
strlinksito: tools.getHostByIdApp(idapp),
|
strlinksito: tools.getHostByIdApp(idapp),
|
||||||
emailto: emailto,
|
emailto: emailto,
|
||||||
qty: myrec.qty,
|
qty: myrec.qty,
|
||||||
|
saldoAttuale: extrarec.saldoDest,
|
||||||
mittente: decode(myrec.mittente),
|
mittente: decode(myrec.mittente),
|
||||||
nomecircuito: decode(myrec.nomecircuito),
|
nomecircuito: decode(myrec.nomecircuito),
|
||||||
transactionDate: tools.getstrDate_DD_MM_YYYY(myrec.transactionDate),
|
transactionDate: tools.getstrDate_DD_MM_YYYY(myrec.transactionDate),
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class AuthService {
|
|||||||
*/
|
*/
|
||||||
async authenticate(idapp, username, password, req) {
|
async authenticate(idapp, username, password, req) {
|
||||||
try {
|
try {
|
||||||
|
console.log('STO FACENDO LOGIN...');
|
||||||
// Check if user is blocked
|
// Check if user is blocked
|
||||||
if (this.isUserBlocked(username)) {
|
if (this.isUserBlocked(username)) {
|
||||||
const text = `Utente bloccato. Riprova più tardi. (username=${username})`;
|
const text = `Utente bloccato. Riprova più tardi. (username=${username})`;
|
||||||
@@ -24,13 +25,15 @@ class AuthService {
|
|||||||
error: true,
|
error: true,
|
||||||
status: 403,
|
status: 403,
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
message: text
|
message: text,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find user by credentials
|
// Find user by credentials
|
||||||
const user = await User.findByCredentials(idapp, username, password);
|
const user = await User.findByCredentials(idapp, username, password);
|
||||||
|
|
||||||
|
console.log('user', user);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return await this._handleFailedLogin(idapp, username, req);
|
return await this._handleFailedLogin(idapp, username, req);
|
||||||
}
|
}
|
||||||
@@ -44,27 +47,25 @@ class AuthService {
|
|||||||
// Prepare user data to send
|
// Prepare user data to send
|
||||||
const userToSend = this._prepareUserData(user);
|
const userToSend = this._prepareUserData(user);
|
||||||
|
|
||||||
|
console.log('userToSend', userToSend);
|
||||||
|
|
||||||
// Check subscription
|
// Check subscription
|
||||||
const subsExistonDb = await this._checkSubscription(
|
const subsExistonDb = await this._checkSubscription(user._id, req.get('User-Agent'));
|
||||||
user._id,
|
|
||||||
req.get('User-Agent')
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
error: false,
|
error: false,
|
||||||
token,
|
token,
|
||||||
refreshToken,
|
refreshToken,
|
||||||
user: userToSend,
|
user: userToSend,
|
||||||
subsExistonDb
|
subsExistonDb,
|
||||||
};
|
};
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in authenticate:', error.message);
|
console.error('Error in authenticate:', error.message);
|
||||||
return {
|
return {
|
||||||
error: true,
|
error: true,
|
||||||
status: 400,
|
status: 400,
|
||||||
code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC,
|
code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC,
|
||||||
message: error.message
|
message: error.message,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,7 +79,7 @@ class AuthService {
|
|||||||
return {
|
return {
|
||||||
error: true,
|
error: true,
|
||||||
status: 400,
|
status: 400,
|
||||||
message: 'Refresh token mancante'
|
message: 'Refresh token mancante',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ class AuthService {
|
|||||||
return {
|
return {
|
||||||
error: true,
|
error: true,
|
||||||
status: 403,
|
status: 403,
|
||||||
message: 'Refresh token non valido'
|
message: 'Refresh token non valido',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,15 +98,14 @@ class AuthService {
|
|||||||
return {
|
return {
|
||||||
error: false,
|
error: false,
|
||||||
token,
|
token,
|
||||||
refreshToken: newRefreshToken
|
refreshToken: newRefreshToken,
|
||||||
};
|
};
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in refreshToken:', error.message);
|
console.error('Error in refreshToken:', error.message);
|
||||||
return {
|
return {
|
||||||
error: true,
|
error: true,
|
||||||
status: 500,
|
status: 500,
|
||||||
message: 'Errore interno del server'
|
message: 'Errore interno del server',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,8 +128,7 @@ class AuthService {
|
|||||||
*/
|
*/
|
||||||
isUserBlocked(username) {
|
isUserBlocked(username) {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
return this.failedLoginAttempts[username] &&
|
return this.failedLoginAttempts[username] && this.failedLoginAttempts[username] > now;
|
||||||
this.failedLoginAttempts[username] > now;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,15 +147,17 @@ class AuthService {
|
|||||||
const loginCheck = await User.tooManyLoginWrong(idapp, username, true);
|
const loginCheck = await User.tooManyLoginWrong(idapp, username, true);
|
||||||
|
|
||||||
if (loginCheck.troppilogin) {
|
if (loginCheck.troppilogin) {
|
||||||
const text = `Troppe richieste di Login ERRATE: ${username} [IP: ${tools.getiPAddressUser(req)}] Tentativi: ${loginCheck.retry_pwd}`;
|
const text = `Troppe richieste di Login ERRATE: ${username} [IP: ${tools.getiPAddressUser(req)}] Tentativi: ${
|
||||||
|
loginCheck.retry_pwd
|
||||||
|
}`;
|
||||||
await telegrambot.sendMsgTelegramToTheManagers(idapp, text);
|
await telegrambot.sendMsgTelegramToTheManagers(idapp, text);
|
||||||
console.log('/login', text);
|
console.log('/login', text);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
error: true,
|
error: true,
|
||||||
status: 400,
|
status: 400,
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
message: text
|
message: text,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,15 +183,17 @@ class AuthService {
|
|||||||
// Block user after max attempts
|
// Block user after max attempts
|
||||||
if (this.failedLoginAttempts[username] >= this.MAX_FAILED_ATTEMPTS) {
|
if (this.failedLoginAttempts[username] >= this.MAX_FAILED_ATTEMPTS) {
|
||||||
this.blockUser(username);
|
this.blockUser(username);
|
||||||
const text = `Troppi tentativi di accesso falliti. Utente bloccato (${username}) [IP: ${tools.getiPAddressUser(req)}]`;
|
const text = `Troppi tentativi di accesso falliti. Utente bloccato (${username}) [IP: ${tools.getiPAddressUser(
|
||||||
|
req
|
||||||
|
)}]`;
|
||||||
tools.mylogshow(text);
|
tools.mylogshow(text);
|
||||||
await telegrambot.sendMsgTelegramToTheManagers(idapp, text);
|
await telegrambot.sendMsgTelegramToTheManagers(idapp, text);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
error: true,
|
error: true,
|
||||||
status: 403,
|
status: 403,
|
||||||
code: server_constants.RIS_CODE_ERR,
|
code: server_constants.RIS_CODE_ERR,
|
||||||
message: text
|
message: text,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +201,7 @@ class AuthService {
|
|||||||
error: true,
|
error: true,
|
||||||
status: 401,
|
status: 401,
|
||||||
code: server_constants.RIS_CODE_LOGIN_ERR,
|
code: server_constants.RIS_CODE_LOGIN_ERR,
|
||||||
message: 'Credenziali non valide'
|
message: 'Credenziali non valide',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +213,7 @@ class AuthService {
|
|||||||
const shared_consts = require('../tools/shared_nodejs');
|
const shared_consts = require('../tools/shared_nodejs');
|
||||||
const userToSend = new User();
|
const userToSend = new User();
|
||||||
|
|
||||||
shared_consts.fieldsUserToChange().forEach(field => {
|
shared_consts.fieldsUserToChange().forEach((field) => {
|
||||||
userToSend[field] = user[field];
|
userToSend[field] = user[field];
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -226,7 +229,7 @@ class AuthService {
|
|||||||
const subscription = await Subscription.findOne({
|
const subscription = await Subscription.findOne({
|
||||||
userId,
|
userId,
|
||||||
access: 'auth',
|
access: 'auth',
|
||||||
browser: userAgent
|
browser: userAgent,
|
||||||
}).lean();
|
}).lean();
|
||||||
|
|
||||||
return !!subscription;
|
return !!subscription;
|
||||||
@@ -237,4 +240,4 @@ class AuthService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = AuthService;
|
module.exports = AuthService;
|
||||||
|
|||||||
@@ -447,6 +447,7 @@ const txt = {
|
|||||||
MSG_APORTADOR_USER_REGISTERED: emo.FIRE + ' Si è appena Registrato "%s" (n. %s)\nInvitato da %s',
|
MSG_APORTADOR_USER_REGISTERED: emo.FIRE + ' Si è appena Registrato "%s" (n. %s)\nInvitato da %s',
|
||||||
MSG_APORTADOR_ASK_CONFIRM:
|
MSG_APORTADOR_ASK_CONFIRM:
|
||||||
'🆕💥 🧍♂️ %s si sta registrando su %s e ti chiede di poter entrare. Confermi di conoscerla ?',
|
'🆕💥 🧍♂️ %s si sta registrando su %s e ti chiede di poter entrare. Confermi di conoscerla ?',
|
||||||
|
MSG_APORTADOR_INVITED_REGISTERED: '🆕💥 🧍♂️ Complimenti! Il tuo invitato %s si è appena registrato su %s !',
|
||||||
MSG_ACCEPT_NEWENTRY_INGROUP: '❇️👥 🧍♂️ Accetta Ingresso nel GRUPPO %s:',
|
MSG_ACCEPT_NEWENTRY_INGROUP: '❇️👥 🧍♂️ Accetta Ingresso nel GRUPPO %s:',
|
||||||
MSG_FRIENDS_NOT_ACCEPTED_CONFIRMED: '🚫 Hai rifiutato la richiesta di Amicizia di %s !',
|
MSG_FRIENDS_NOT_ACCEPTED_CONFIRMED: '🚫 Hai rifiutato la richiesta di Amicizia di %s !',
|
||||||
MSG_HANDSHAKE_NOT_ACCEPTED_CONFIRMED: '🚫 Hai rifiutato la richiesta di Stretta di mano di %s !',
|
MSG_HANDSHAKE_NOT_ACCEPTED_CONFIRMED: '🚫 Hai rifiutato la richiesta di Stretta di mano di %s !',
|
||||||
@@ -795,7 +796,6 @@ const MyTelegramBot = {
|
|||||||
text = printf(getstr(langdest, 'MSG_APORTADOR_USER_REGISTERED'), nome, numutenti, aportador);
|
text = printf(getstr(langdest, 'MSG_APORTADOR_USER_REGISTERED'), nome, numutenti, aportador);
|
||||||
}
|
}
|
||||||
} else if (phase === this.phase.INVITA_AMICO) {
|
} else if (phase === this.phase.INVITA_AMICO) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let addtext = '';
|
let addtext = '';
|
||||||
@@ -903,25 +903,31 @@ const MyTelegramBot = {
|
|||||||
// Non chiedi la verifica Registrazione
|
// Non chiedi la verifica Registrazione
|
||||||
await setVerifiedReg(myuser.idapp, myuser.lang, myuser.username, userDest);
|
await setVerifiedReg(myuser.idapp, myuser.lang, myuser.username, userDest);
|
||||||
} else {
|
} else {
|
||||||
msg_notifpush = getstr(langdest, 'MSG_APORTADOR_ASK_CONFIRM', myuser.username, nomeapp);
|
if (myuser.verified_by_aportador) {
|
||||||
domanda = getstr(langdest, 'MSG_APORTADOR_ASK_CONFIRM', myuser.username, nomeapp) + '<br>' + struserinfomsg;
|
msg_notifpush = getstr(langdest, 'MSG_APORTADOR_INVITED_REGISTERED', myuser.username, nomeapp);
|
||||||
|
domanda =
|
||||||
keyb = cl.getInlineKeyboard(myuser.lang, [
|
getstr(langdest, 'MSG_APORTADOR_INVITED_REGISTERED', myuser.username, nomeapp) + '<br>' + struserinfomsg;
|
||||||
{
|
} else {
|
||||||
text: '✅ Ammetti ' + myuser.username,
|
msg_notifpush = getstr(langdest, 'MSG_APORTADOR_ASK_CONFIRM', myuser.username, nomeapp);
|
||||||
callback_data: InlineConferma.RISPOSTA_SI + myfunc + tools.SEP + myuser.username + tools.SEP + userDest,
|
domanda = getstr(langdest, 'MSG_APORTADOR_ASK_CONFIRM', myuser.username, nomeapp) + '<br>' + struserinfomsg;
|
||||||
},
|
keyb = cl.getInlineKeyboard(myuser.lang, [
|
||||||
/*{
|
{
|
||||||
|
text: '✅ Ammetti ' + myuser.username,
|
||||||
|
callback_data: InlineConferma.RISPOSTA_SI + myfunc + tools.SEP + myuser.username + tools.SEP + userDest,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
/*{
|
||||||
text: '🚫 Rifiuta ' + myuser.username,
|
text: '🚫 Rifiuta ' + myuser.username,
|
||||||
callback_data: InlineConferma.RISPOSTA_NO + myfunc + tools.SEP + myuser.username + tools.SEP + userDest,
|
callback_data: InlineConferma.RISPOSTA_NO + myfunc + tools.SEP + myuser.username + tools.SEP + userDest,
|
||||||
}, */
|
}, */
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
send_notif = true;
|
send_notif = true;
|
||||||
} else if (myfunc === shared_consts.CallFunz.VERIFICA_TELEGRAM) {
|
} else if (myfunc === shared_consts.CallFunz.VERIFICA_TELEGRAM) {
|
||||||
if (telegid > 0) {
|
if (telegid > 0) {
|
||||||
cl.setPhotoProfile(myuser, telegid, false);
|
cl.setPhotoProfile(myuser, telegid, false);
|
||||||
|
|
||||||
|
|
||||||
const rismsg = await MsgTemplate.getMsgByLang(
|
const rismsg = await MsgTemplate.getMsgByLang(
|
||||||
idapp,
|
idapp,
|
||||||
myuser,
|
myuser,
|
||||||
@@ -930,6 +936,23 @@ const MyTelegramBot = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await cl.sendMsgLog(telegid, rismsg.body);
|
await cl.sendMsgLog(telegid, rismsg.body);
|
||||||
|
|
||||||
|
// Invia notifica Teelgram all'Invitante che il suo invitato si è Verificato con Telegram.
|
||||||
|
userDest = myuser.aportador_solidario;
|
||||||
|
let useraportador = await User.getUserShortDataByUsername(idapp, userDest);
|
||||||
|
|
||||||
|
|
||||||
|
const rismsg2 = await MsgTemplate.getMsgByLang(
|
||||||
|
idapp,
|
||||||
|
myuser,
|
||||||
|
shared_consts.TypeMsgTemplate.MSG_VERIFICA_TELEGRAM_COMPLETATA_NOTIF_INVITANTE,
|
||||||
|
myuser.lang
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const telegidInvitante = useraportador.profile.teleg_id;
|
||||||
|
|
||||||
|
await cl.sendMsgLog(telegidInvitante, rismsg2.body);
|
||||||
}
|
}
|
||||||
} else if (myfunc === shared_consts.CallFunz.RICHIESTA_GRUPPO) {
|
} else if (myfunc === shared_consts.CallFunz.RICHIESTA_GRUPPO) {
|
||||||
msg_notifpush = printf(getstr(langdest, 'MSG_ACCEPT_NEWENTRY_INGROUP'), name);
|
msg_notifpush = printf(getstr(langdest, 'MSG_ACCEPT_NEWENTRY_INGROUP'), name);
|
||||||
@@ -1091,6 +1114,7 @@ const MyTelegramBot = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
askConfirmationUserFriend: async function (idapp, myfunc, myuser, userDest = '', username = '') {
|
askConfirmationUserFriend: async function (idapp, myfunc, myuser, userDest = '', username = '') {
|
||||||
try {
|
try {
|
||||||
const cl = getclTelegByidapp(idapp);
|
const cl = getclTelegByidapp(idapp);
|
||||||
@@ -1255,22 +1279,7 @@ const MyTelegramBot = {
|
|||||||
let title = '';
|
let title = '';
|
||||||
let msg = '';
|
let msg = '';
|
||||||
|
|
||||||
if (mydata.tipomsg === tools.TipoMsg.SEND_LINK_CHAT_DONATORI) {
|
if (mydata.tipomsg === tools.TipoMsg.SEND_MSG || mydata.tipomsg === tools.TipoMsg.SEND_MSG_SINGOLO) {
|
||||||
if (sonosognatore)
|
|
||||||
msg = printf(
|
|
||||||
tools.gettranslate('SEND_LINK_CHAT_SOGNATORE', lang),
|
|
||||||
user.name,
|
|
||||||
mydata.navemediatore.riga + '.' + mydata.navemediatore.col,
|
|
||||||
mydata.msgpar1
|
|
||||||
);
|
|
||||||
else
|
|
||||||
msg = printf(
|
|
||||||
tools.gettranslate('SEND_LINK_CHAT_DONATORI', lang),
|
|
||||||
user.name,
|
|
||||||
mydata.navemediatore.riga + '.' + mydata.navemediatore.col,
|
|
||||||
mydata.msgpar1
|
|
||||||
);
|
|
||||||
} else if (mydata.tipomsg === tools.TipoMsg.SEND_MSG || mydata.tipomsg === tools.TipoMsg.SEND_MSG_SINGOLO) {
|
|
||||||
if (!!mydata.username_mitt) {
|
if (!!mydata.username_mitt) {
|
||||||
msg = '[' + tools.gettranslate('MSG_SEND_FROM', lang) + ' ' + mydata.username_mitt + ']:' + tools.ACAPO;
|
msg = '[' + tools.gettranslate('MSG_SEND_FROM', lang) + ' ' + mydata.username_mitt + ']:' + tools.ACAPO;
|
||||||
}
|
}
|
||||||
@@ -1285,32 +1294,6 @@ const MyTelegramBot = {
|
|||||||
if (cl) {
|
if (cl) {
|
||||||
msg = await tools.convertSpecialTags(rec.user, msg);
|
msg = await tools.convertSpecialTags(rec.user, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!!mydata.flotta) {
|
|
||||||
// SOSTITUISCI LE PAROLE CHIAVI
|
|
||||||
if (!!mydata.flotta.date_start)
|
|
||||||
msg = msg.replace('{date_start}', tools.getstrDateLongTot(new Date(mydata.flotta.date_start), user.lang));
|
|
||||||
if (!!mydata.flotta.date_close)
|
|
||||||
msg = msg.replace('{date_close}', tools.getstrDateLongTot(new Date(mydata.flotta.date_close), user.lang));
|
|
||||||
if (!!mydata.flotta.link_superchat) msg = msg.replace('{link_superchat}', mydata.flotta.link_superchat);
|
|
||||||
if (!!mydata.flotta.tutor1) msg = msg.replace('{tutor1}', mydata.flotta.tutor1);
|
|
||||||
if (!!mydata.flotta.tutor2) msg = msg.replace('{tutor2}', mydata.flotta.tutor2);
|
|
||||||
if (!!mydata.flotta.tutor3) msg = msg.replace('{tutor3}', mydata.flotta.tutor3);
|
|
||||||
if (!!mydata.flotta.tutorslo) msg = msg.replace('{tutorslo}', mydata.flotta.tutorslo);
|
|
||||||
if (!!mydata.flotta.sognatore_nomecognome) msg = msg.replace('{sognatore}', mydata.flotta.sognatore_nomecognome);
|
|
||||||
if (!!mydata.flotta.sognatore_nomecognome)
|
|
||||||
msg = msg.replace(
|
|
||||||
'{flotta}',
|
|
||||||
mydata.flotta.riga +
|
|
||||||
'.' +
|
|
||||||
Math.ceil(mydata.flotta.col_prima / 8) +
|
|
||||||
' - ' +
|
|
||||||
mydata.flotta.riga +
|
|
||||||
'.' +
|
|
||||||
Math.ceil(mydata.flotta.col_ultima / 8)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return { body: msg, title };
|
return { body: msg, title };
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1926,7 +1909,7 @@ class Telegram {
|
|||||||
risp = 'Siiiii ! Davvero! ' + emo.DREAM;
|
risp = 'Siiiii ! Davvero! ' + emo.DREAM;
|
||||||
} else if (MsgBot.PAROLACCE.find((rec) => testo.indexOf(rec) > -1)) {
|
} else if (MsgBot.PAROLACCE.find((rec) => testo.indexOf(rec) > -1)) {
|
||||||
risp = "Da te non me l'aspettavo proprio !! " + emo.INNOCENT + emo.CROSS_ROSSA;
|
risp = "Da te non me l'aspettavo proprio !! " + emo.INNOCENT + emo.CROSS_ROSSA;
|
||||||
// } else if (MsgBot.OK.find((rec) => testo.indexOf(rec) > -1)) {
|
// } else if (MsgBot.OK.find((rec) => testo.indexOf(rec) > -1)) {
|
||||||
// risp = '👍🏻';
|
// risp = '👍🏻';
|
||||||
} else if (MsgBot.CUORE.find((rec) => testo.indexOf(rec) > -1)) {
|
} else if (MsgBot.CUORE.find((rec) => testo.indexOf(rec) > -1)) {
|
||||||
risp = '❤️💚💜';
|
risp = '❤️💚💜';
|
||||||
@@ -3332,27 +3315,27 @@ class Telegram {
|
|||||||
if (!msg.from.username) {
|
if (!msg.from.username) {
|
||||||
rec.cmdAfterVerified === shared_consts.CallFunz.VERIFICA_TELEGRAM;
|
rec.cmdAfterVerified === shared_consts.CallFunz.VERIFICA_TELEGRAM;
|
||||||
} else {
|
} else {
|
||||||
await this.verificaTelegramCompleted(msg);
|
await this.verificaTelegramCompleted(msg, recuser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async verificaTelegramCompleted(msg) {
|
async verificaTelegramCompleted(msg, recuser) {
|
||||||
try {
|
try {
|
||||||
const rec = this.getRecInMem(msg);
|
const rec = this.getRecInMem(msg);
|
||||||
const id = msg.chat.id;
|
|
||||||
const recuser = this.getRecInMemById(id);
|
|
||||||
|
|
||||||
if (recuser) {
|
if (rec && recuser) {
|
||||||
await User.setUsernameTelegram(
|
await User.setUsernameTelegram(
|
||||||
this.idapp,
|
this.idapp,
|
||||||
recuser.user._id,
|
recuser._id,
|
||||||
msg.from.username || '',
|
msg.from.username || '',
|
||||||
msg.from.first_name || '',
|
msg.from.first_name || '',
|
||||||
msg.from.last_name || ''
|
msg.from.last_name || ''
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
rec.status = Status.VERIFIED;
|
rec.status = Status.VERIFIED;
|
||||||
rec.datemenu_updated = null;
|
rec.datemenu_updated = null;
|
||||||
rec.menuDb = null;
|
rec.menuDb = null;
|
||||||
@@ -4595,7 +4578,6 @@ if (true) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Invia una email alla persona che è stata ammessa
|
// Invia una email alla persona che è stata ammessa
|
||||||
|
|
||||||
|
|
||||||
await local_sendMsgTelegram(user.idapp, data.username, msgOrig);
|
await local_sendMsgTelegram(user.idapp, data.username, msgOrig);
|
||||||
await local_sendMsgTelegram(user.idapp, data.userDest, msgDest);
|
await local_sendMsgTelegram(user.idapp, data.userDest, msgDest);
|
||||||
|
|||||||
@@ -2145,7 +2145,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
getTelegramKeyByIdApp: function (idapp) {
|
getTelegramKeyByIdApp: function (idapp) {
|
||||||
if (this.MYAPPS.length === 0) {
|
if (this.MYAPPS.length === 0) {
|
||||||
console.error('❌ this.MYAPPS VUOTI!!', this.MYAPPS);
|
console.error('❌ this.MYAPPS VUOTI!!', this.MYAPPS);
|
||||||
@@ -3942,7 +3941,7 @@ module.exports = {
|
|||||||
try {
|
try {
|
||||||
return await this.readfilecontent(__dirname + '/../version.txt');
|
return await this.readfilecontent(__dirname + '/../version.txt');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return ''
|
return '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -4450,12 +4449,34 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getNomeCognomeEUserNameByUser(user) {
|
getNomeCognomeEUserNameByUser(user) {
|
||||||
let nome = `${user.name} ${user.surname} (${user.username})`;
|
if (!user) return '';
|
||||||
if (!user.name) {
|
|
||||||
nome = user.username;
|
const name = user.name?.trim() || '';
|
||||||
|
const surname = user.surname?.trim() || '';
|
||||||
|
const username = user.username?.trim() || '';
|
||||||
|
|
||||||
|
// Se ci sono nome e cognome
|
||||||
|
if (name && surname) {
|
||||||
|
return username ? `${name} ${surname} (${username})` : `${name} ${surname}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nome;
|
// Se c'è solo il nome
|
||||||
|
if (name) {
|
||||||
|
return username ? `${name} (${username})` : name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se c'è solo il cognome
|
||||||
|
if (surname) {
|
||||||
|
return username ? `${surname} (${username})` : surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se c'è solo username
|
||||||
|
if (username) {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nessun dato disponibile
|
||||||
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
sulServer() {
|
sulServer() {
|
||||||
@@ -4527,31 +4548,45 @@ module.exports = {
|
|||||||
try {
|
try {
|
||||||
if (!msg) return msg;
|
if (!msg) return msg;
|
||||||
|
|
||||||
if (!!user) {
|
if (user) {
|
||||||
|
// Usa replaceAll() per sostituire TUTTE le occorrenze (non solo la prima)
|
||||||
if (msg.includes('{host}')) {
|
if (msg.includes('{host}')) {
|
||||||
msg = msg.replace('{host}', this.getHostByIdApp(user.idapp));
|
msg = msg.replaceAll('{host}', this.getHostByIdApp(user.idapp));
|
||||||
|
}
|
||||||
|
if (msg.includes('{appname}')) {
|
||||||
|
msg = msg.replaceAll('{appname}', this.getNomeAppByIdApp(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.replaceAll('{username}', user.username || '');
|
||||||
|
msg = msg.replaceAll('{name}', user.name || user.username || '');
|
||||||
|
msg = msg.replaceAll('{surname}', user.surname || '');
|
||||||
|
msg = msg.replaceAll('{urlunsubscribe_user}', this.getUnsubsribeUrl_User(user));
|
||||||
|
msg = msg.replaceAll('{aportador_solidario}', user.aportador_solidario || '');
|
||||||
|
|
||||||
msg = msg.replace('{aportador_solidario}', user.aportador_solidario ? user.aportador_solidario : '');
|
// Usa optional chaining per evitare errori se user.profile è undefined
|
||||||
if (!!user.profile.link_payment) msg = msg.replace('{link_paypalme}', user.profile.link_payment);
|
if (user.profile?.link_payment) {
|
||||||
if (!!user.profile.revolut) msg = msg.replace('{revolut}', user.profile.revolut);
|
msg = msg.replaceAll('{link_paypalme}', user.profile.link_payment);
|
||||||
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?.revolut) {
|
||||||
if (!!user.profile.email_paypal) msg = msg.replace('{email_paypal}', user.profile.email_paypal);
|
msg = msg.replaceAll('{revolut}', user.profile.revolut);
|
||||||
if (!!user.profile.note_payment) msg = msg.replace('{note_payment}', user.profile.note_payment);
|
}
|
||||||
|
if (user.profile?.payeer_id) {
|
||||||
|
msg = msg.replaceAll('{payeer_id}', user.profile.payeer_id);
|
||||||
|
}
|
||||||
|
if (user.profile?.advcash_id) {
|
||||||
|
msg = msg.replaceAll('{advcash_id}', user.profile.advcash_id);
|
||||||
|
}
|
||||||
|
if (user.profile?.email_paypal) {
|
||||||
|
msg = msg.replaceAll('{email_paypal}', user.profile.email_paypal);
|
||||||
|
}
|
||||||
|
if (user.profile?.note_payment) {
|
||||||
|
msg = msg.replaceAll('{note_payment}', user.profile.note_payment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const cl = getclTelegByidapp(user.idapp);
|
msg = msg.replaceAll('{link_chathelp}', this.HELP_CHAT);
|
||||||
msg = msg.replace('{link_chathelp}', this.HELP_CHAT);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.error('Errore in convertSpecialTags:', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
@@ -4965,7 +5000,7 @@ module.exports = {
|
|||||||
mystr = i18n.__(
|
mystr = i18n.__(
|
||||||
'DATE_1DAY',
|
'DATE_1DAY',
|
||||||
this.getstrDateLong(myevent.dateTimeStart),
|
this.getstrDateLong(myevent.dateTimeStart),
|
||||||
this.getstrTime(myevent.dateTimeStart),
|
this.getstrTime(myevent.dateTimeStart)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
mystr = i18n.__(
|
mystr = i18n.__(
|
||||||
@@ -6305,7 +6340,6 @@ module.exports = {
|
|||||||
|
|
||||||
getTokenRandom() {
|
getTokenRandom() {
|
||||||
return crypto.randomBytes(32).toString('hex');
|
return crypto.randomBytes(32).toString('hex');
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async ensureDir(fullnamepath) {
|
async ensureDir(fullnamepath) {
|
||||||
|
|||||||
@@ -597,6 +597,7 @@ module.exports = {
|
|||||||
MSG_BENV_REGISTRATO: 2020,
|
MSG_BENV_REGISTRATO: 2020,
|
||||||
MSG_INVITE_WHATSAPP: 2040,
|
MSG_INVITE_WHATSAPP: 2040,
|
||||||
MSG_VERIFICA_TELEGRAM_COMPLETATA: 2050,
|
MSG_VERIFICA_TELEGRAM_COMPLETATA: 2050,
|
||||||
|
MSG_VERIFICA_TELEGRAM_COMPLETATA_NOTIF_INVITANTE: 2060,
|
||||||
},
|
},
|
||||||
|
|
||||||
TypeSend: {
|
TypeSend: {
|
||||||
|
|||||||
Reference in New Issue
Block a user