vtenext ce 20.04.3: FIX SEC apply 20250714, 20250814; backport htaccess, misc; remove sass-cache

This commit is contained in:
Manuel Tagliapietra 2025-08-20 12:58:45 +02:00
parent b3ec2162f9
commit cfc8ecb208
416 changed files with 1316 additions and 760 deletions

View File

@ -1,26 +1,50 @@
<IfModule mod_expires.c>
<FilesMatch "\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt|ico)$">
ExpiresActive On
ExpiresDefault "access plus 10 years"
</FilesMatch>
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
# crmv@272658
<Files "composer.*">
# disable access to composer files, to avoid library enumeration
Order Allow,Deny
Deny from all
</Files>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*\.(js|css))$ smartoptimizer/?$1
# crmv@301301
# disable the server signature for server generated pages
# beware: this is not hiding the header "Server"
ServerSignature Off
<IfModule mod_expires.c>
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*\.(js|css|html?|xml|txt))$ smartoptimizer/?$1
</IfModule>
<IfModule !mod_expires.c>
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt|ico))$ smartoptimizer/?$1
# crmv@343310
<IfModule mod_mime.c>
<IfModule mod_headers.c>
<FilesMatch "site.webmanifest$">
Header set Content-Type "application/manifest+json"
</FilesMatch>
</IfModule>
</IfModule>
<FilesMatch "\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt|ico)$">
FileETag none
</FilesMatch>
# crmv@343310e
# Enable this if you want to use smartoptimizer (can be buggy with some files)
#
# <IfModule mod_expires.c>
# <FilesMatch "\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt|ico)$">
# ExpiresActive On
# ExpiresDefault "access plus 10 years"
# </FilesMatch>
# </IfModule>
# <IfModule mod_rewrite.c>
# RewriteEngine On
#
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule ^(.*\.(js|css))$ smartoptimizer/?$1
#
# <IfModule mod_expires.c>
# RewriteCond %{REQUEST_FILENAME} -f
# RewriteRule ^(.*\.(js|css|html?|xml|txt))$ smartoptimizer/?$1
# </IfModule>
#
# <IfModule !mod_expires.c>
# RewriteCond %{REQUEST_FILENAME} -f
# RewriteRule ^(.*\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt|ico))$ smartoptimizer/?$1
# </IfModule>
# </IfModule>
# <FilesMatch "\.(gif|jpg|jpeg|png|swf|css|js|html?|xml|txt|ico)$">
# FileETag none
# </FilesMatch>

View File

@ -15,13 +15,21 @@ function vte_get_labels($username, $language, $module){
$language = $user->default_language;
}
$query = "SELECT label,trans_label
FROM sdk_language
WHERE language = ? ";
if($module != ''){
$query .= " AND module = '$module' ";
// crmv@341207
$query = "
SELECT label,trans_label
FROM sdk_language
WHERE language = ?
";
$params = [$language];
if ($module != '') {
$query .= " AND module = ? ";
$params[] = $module;
}
$res = $adb->pquery($query, array($language));
$res = $adb->pquery($query, $params);
// crmv@341207e
$labels = Array();

View File

@ -1,252 +1 @@
<p align="center"><font size="2"><b>INFORMATIVA PRIVACY FINALIZZATA ALL&rsquo;AUTORIZZAZIONE AL TRATTAMENTO DI DATI PERSONALI</b></font></p>
<p align="center">&nbsp;</p>
<p align="center"><font size="2"><b>Ai sensi del combinato disposto del Decreto Legislativo 30 giugno 2003, n. 196 recante &ldquo;Codice in materia di protezione dei dati personali&rdquo; (Testo Unico in materia di Privacy) </b></font></p>
<p align="center"><font size="2"><b>e del Regolamento (UE) 2016/679 del Parlamento Europeo e del Consiglio del 27 aprile 2016 </b></font></p>
<p align="center"><font size="2"><b>relativo alla protezione delle persone fisiche con riguardo al trattamento dei dati personali</b></font></p>
<p align="center"><font size="2"><b>nonch&eacute; alla libera circolazione di tali dati </b></font><font size="2"><u><b>da qui in poi anche soltanto &ldquo;GDPR</b></u></font><font size="2"><b>&rdquo;</b></font></p>
<p>&nbsp;</p>
<p align="center">&nbsp;</p>
<p align="center"><b>P R E M E S S O</b></p>
<p>&nbsp;</p>
<ol>
<li>
<p align="justify"><font size="2">che il GDPR, pubblicato nella Gazzetta Ufficiale dell&rsquo;Unione Europea (GUUE) L. 119 del 4 maggio 2016 e, ai sensi dell&rsquo;art. 99 del GDPR, &egrave; entrato in vigore il 25 maggio 2016 e si applicher&agrave; obbligatoriamente in ciascuno Stato membro a far data dal 25 maggio 2018;</font></p>
</li>
</ol>
<p align="justify">&nbsp;</p>
<ol start="2">
<li>
<p align="justify"><font size="2">che, fino all&rsquo;emanazione di provvedimenti diretti ad adeguare il quadro normativo nazionale alle disposizioni del Regolamento UE n. 679/2016 (GDPR), si rende necessaria, anche, l&rsquo;applicazione del Codice della Privacy (D.lgs.n.196/2003), ancorch&eacute;, nei limiti di quanto ci&ograve; non risulter&agrave; incompatibile con le previsioni contenute nel GDPR stesso;</font></p>
</li>
</ol>
<p>&nbsp;</p>
<ol start="3">
<li>
<p align="justify"><font size="2">che, pertanto, fermo restando quanto gi&agrave; previsto e disciplinato dal D.lgs.n.196/2003, il GDPR, con le eccezioni previste all&rsquo;articolo 2, trova applicazione al trattamento interamente o parzialmente automatizzato di dati personali e al trattamento non automatizzato di dati personali contenuti in un archivio o destinati a figurarvi;</font></p>
</li>
</ol>
<p align="justify">&nbsp;</p>
<ol start="4">
<li>
<p align="justify"><font size="2">che, secondo quanto previsto dall&rsquo;</font><font size="2"><u>art. 5 GDPR</u></font><font size="2"> (&ldquo;</font><font size="2"><i><b>Principi applicabili al trattamento di dati personali</b></i></font><font size="2">&rdquo;), i dati personali dell&rsquo;interessato sono trattati secondo principi di</font></p>
</li>
</ol>
<p align="justify">&nbsp;</p>
<ul>
<li>
<p align="justify"><font size="2">di</font><font size="2"><b> liceit&agrave;</b></font><font size="2"> ovvero rispetto delle norme; di </font><font size="2"><b>correttezza </b></font><font size="2">ovvero rispetto di norme etiche, deontologiche non codificate; e di</font><font size="2"><b> trasparenza </b></font><font size="2">ovvero garanzia di consapevolezza dell&rsquo;interessato, tracciabilit&agrave; del dato e </font><font size="2"><i>disclosure</i></font><font size="2"> in ogni momento a richiesta dell&rsquo;interessato (lettera a); </font></p>
</li>
<li>
<p align="justify"><font size="2">di &ldquo;</font><font size="2"><b>limitazione della finalit&agrave;</b></font><font size="2">&rdquo; ovvero raccolti per finalit&agrave; determinate, esplicite e legittime oltre che successivamente trattati con modalit&agrave; non incompatibili con tali finalit&agrave; (lettera b); </font></p>
</li>
<li>
<p align="justify"><font size="2">di &ldquo;</font><font size="2"><b>minimizzazione dei dati</b></font><font size="2">&rdquo; ovvero raccolti in modo adeguato, pertinente e limitato a quanto necessario rispetto alle finalit&agrave; per le quali gli stessi dati sono trattati (lettera c); </font></p>
</li>
<li>
<p align="justify"><font size="2">di &ldquo;</font><font size="2"><b>esattezza</b></font><font size="2">&rdquo; ovvero raccolti in modo esatto e, se necessario, aggiornati oltre che cancellati o rettificati in caso di loro accertata inesattezza (lettera d); </font></p>
</li>
<li>
<p align="justify"><font size="2">di &ldquo;</font><font size="2"><b>limitazione della conservazione</b></font><font size="2">&rdquo; ovvero conservati in una forma che consenta l&rsquo;identificazione degli interessati per un arco di tempo non superiore a quello funzionale al conseguimento delle finalit&agrave; per le quali gli stessi dati sono trattati (lettera e); </font></p>
</li>
<li>
<p align="justify"><font size="2">di &ldquo;</font><font size="2"><b>integrit&agrave; e riservatezza</b></font><font size="2">&rdquo; ovvero trattati in modo da garantire una adeguata sicurezza dei dati personali, compresa la loro protezione attraverso misure tecniche e organizzative adeguate, da trattamenti non autorizzati o illeciti o dalla perdita, distruzione o dal danno accidentali (lettera f);</font></p>
</li>
</ul>
<p>&nbsp;</p>
<ol start="5">
<li>
<p align="justify"><font size="2">che, in particolare, il trattamento &egrave; &ldquo;</font><font size="2"><b>lecito</b></font><font size="2">&rdquo; se, e nella misura in cui, cfr. </font><font size="2"><u>art. 6 GDPR</u></font><font size="2"> (&ldquo;</font><font size="2"><i><b>Liceit&agrave; del trattamento</b></i></font><font size="2">&rdquo;) ricorra almeno una delle seguenti condizioni:</font></p>
</li>
</ol>
<p align="justify">&nbsp;</p>
<ul>
<li>
<p align="justify"><font size="2">l&#39;interessato ha espresso il consenso al trattamento dei propri dati personali per una o pi&ugrave; specifiche finalit&agrave; (lettera a); </font></p>
</li>
<li>
<p align="justify"><font size="2">il trattamento &egrave; necessario all&#39;esecuzione di un contratto di cui l&#39;interessato &egrave; parte o all&#39;esecuzione di misure precontrattuali adottate su richiesta dello stesso (lettera b); </font></p>
</li>
<li>
<p align="justify"><font size="2">il trattamento &egrave; necessario per adempiere un obbligo legale al quale &egrave; soggetto il titolare del trattamento (lettera c); </font></p>
</li>
<li>
<p align="justify"><font size="2">il trattamento &egrave; necessario per la salvaguardia degli interessi vitali dell&#39;interessato o di un&#39;altra persona fisica (lettera d);</font></p>
</li>
<li>
<p align="justify"><font size="2">il trattamento &egrave; necessario per l&#39;esecuzione di un compito di interesse pubblico o connesso all&#39;esercizio di pubblici poteri di cui &egrave; investito il titolare del trattamento (lettera e); </font></p>
</li>
<li>
<p align="justify"><font size="2">il trattamento &egrave; necessario per il perseguimento del legittimo interesse del titolare del trattamento o di terzi, a condizione che non prevalgano gli interessi o i diritti e le libert&agrave; fondamentali dell&#39;interessato che richiedono la protezione dei dati personali, in particolare se l&#39;interessato &egrave; un minore (lettera f).</font></p>
</li>
</ul>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2">tutto quanto sopra premesso, in ottemperanza al disposto normativo di cui all&rsquo;</font><font size="2"><u>art. 13</u></font><font size="2"> (&ldquo;</font><font size="2"><i><b>Informazioni da fornire qualora i dati personali siano raccolti presso l&rsquo;interessato</b></i></font><font size="2">&rdquo;)</font><font size="2"><i> </i></font><font size="2">&ndash; Sezione 2 (&ldquo;</font><font size="2"><i><b>Informazioni e accesso ai dati personali</b></i></font><font size="2">&rdquo;) del GDPR, e di cui all&rsquo;</font><font size="2"><u>art. 13</u></font><font size="2"> (&ldquo;</font><font size="2"><i><b>Informativa</b></i></font><font size="2">&rdquo;) del D.lgs.n.196/2003 </font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2"><b>Identificazione del &ldquo;Titolare del Trattamento&rdquo;</b></font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2">(cfr. definizione &ldquo;</font><font size="2"><u><b>Titolare del trattamento</b></u></font><font size="2">&rdquo; punto 7 &ndash; art. 4 &ldquo;Definizioni&rdquo; GDPR: &ldquo;</font><font size="2"><i>persona fisica o giuridica, autorit&agrave; pubblica, il servizio o altro organismo che, singolarmente o insieme ad altri, determina le finalit&agrave; e i mezzi del trattamento di dati personali</i></font><font size="2">&rdquo; e definizione &ldquo;</font><font size="2"><u><b>Titolare</b></u></font><font size="2">&rdquo; lettera f) &ndash; art. 4 &ldquo;Definizioni&rdquo; D.lgs.n.196/2003: &ldquo;</font><font size="2"><i>la persona fisica, la persona giuridica, la pubblica amministrazione e qualsiasi altro ente associazione od organismo, cui competono anche unitamente a ad altro titolare, le decisioni in ordine alle finalit&agrave;, alle modalit&agrave; del trattamento di dati personali e agli strumenti utilizzati, ivi compreso il profilo della sicurezza</i></font><font size="2">&rdquo;): </font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2"><b>Oggetto e Modalit&agrave; del Trattamento</b></font><font size="2">: </font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2">(cfr. definizione &ldquo;</font><font size="2"><u><b>Trattamento</b></u></font><font size="2">&rdquo; &ndash; </font><font size="2"><u>art. 4 &ldquo;Definizioni&rdquo; GDPR</u></font><font size="2">: &ldquo;</font><font size="2"><i>qualsiasi operazione o insieme di operazioni, compiute con o senza l&rsquo;ausilio di processi automatizzati e applicati a dati personali o insiemi di dati personali, come la raccolta, la registrazione, l&rsquo;organizzazione, la strutturazione, la conservazione, l&rsquo;adattamento o la modifica, l&rsquo;estrazione, la consultazione, l&rsquo;uso, la comunicazione meditante trasmissione, diffusione o qualsiasi altra forma di messa a disposizione, il raffronto o l&rsquo;interconnessione, la limitazione, la cancellazione o la distruzione</i></font><font size="2">&rdquo; e definizione &ldquo;</font><font size="2"><u><b>Trattamento</b></u></font><font size="2">&rdquo; &ndash; </font><font size="2"><u>lettera a) art. 4, D.lgs.n.196/2003</u></font><font size="2">: &ldquo;</font><font size="2"><i>qualunque operazione o complesso di operazioni, effettuati anche senza l&rsquo;ausilio di strumenti elettronici, concernenti la raccolta, la registrazione, l&rsquo;organizzazione, la conservazione, la consultazione, l&rsquo;elaborazione, la modificazione, la selezione, l&rsquo;estrazione, il raffronto, l&rsquo;utilizzo, l&rsquo;interconnessione, il blocco, la comunicazione, la diffusione, la cancellazione e la distruzione di dati, anche, se non registrati in una banca dati</i></font><font size="2">&rdquo; cfr. definizione di &ldquo;</font><font size="2"><u><b>Dato Personale</b></u></font><font size="2">&rdquo; </font><font size="2"><u>punto 1 &ndash; art. 4 &ldquo;Definizioni&rdquo; GDPR</u></font><font size="2">: &ldquo;</font><font size="2"><i>qualsiasi informazione riguardante una persona identificata o identificabile (&ldquo;interessato&rdquo;) considerandosi per &ldquo;identificabile&rdquo; la persona fisica che pu&ograve; essere identificata, direttamente o indirettamente, con particolare riferimento a un identificativo come il nome, un numero di identificazione, dati relativi all&rsquo;ubicazione, un identificativo online o a uno o pi&ugrave; elementi caratteristici della sua identit&agrave; fisica, fisiologica, generica, psichica, economica, culturale o sociale</i></font><font size="2">&rdquo;);</font><font color="#ff0000"><font size="2"> </font></font><font size="2">e definizione &ldquo;</font><font size="2"><u><b>Dato Personale</b></u></font><font size="2">&rdquo; &ndash; </font><font size="2"><u>lettera b), art. 4, D.lgs.n.196/2003</u></font><font size="2">: &ldquo;</font><font size="2"><i>qualunque informazione relativa a persona fisica, persona giuridica, ente od associazione, identificati o identificabili, anche indirettamente, mediante riferimento a qualsiasi altra informazione, ivi compreso un numero di identificazione personale</i></font><font size="2">&rdquo;;</font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2">Il titolare tratta i dati personali identificativi forniti dall&rsquo;interessato.</font></p>
<p align="justify"><font size="2">Il trattamento dei dati personali &egrave; realizzato sulla base delle operazioni indicate all&rsquo;articolo 4, n.2), GDPR e dall&rsquo;art. 4, lettera a), D.lgs.n.196/2003 e precisamente: raccolta, anche, attraverso l&rsquo;ausilio di strumenti elettronici ed automatizzati; registrazione per scopi determinati, espliciti e legittimi ed utilizzo in ulteriori operazioni di trattamento, comunque, compatibili con tali scopi; organizzazione, conservazione, consultazione, elaborazione, modificazione, selezione, estrazione, raffronto, utilizzo, interconnessione, blocco, comunicazione, cancellazione e distruzione dei dati. </font></p>
<p align="justify"><font size="2">I dati verranno trattati nel rispetto della sicurezza e riservatezza necessaire e saranno sottoposti a trattamento sia cartaceo che elettronico e/o automatizzato. </font></p>
<p align="justify"><font size="2">Il Titolare tratter&agrave; i dati personali per il tempo necessario per adempiere alle finalit&agrave; di cui sopra avendo cura di conservarli, comunque, nei limiti di quanto di seguito specificato. </font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2"><b>Finalit&agrave; del trattamento a cui sono destinati i dati personali</b></font><font size="2">: </font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2">I dati vengono qui raccolti e trattati:</font></p>
<p align="justify">&nbsp;</p>
<ol type="a">
<li>
<p align="justify"><font size="2"><u><b>senza consenso espresso</b></u></font><font size="2"> (cfr. art. 24, D.lgs.n.196/2003 e cfr. art. 6 GDPR), per le seguenti finalit&agrave; di Servizio:</font></p>
</li>
</ol>
<p align="justify">&nbsp;</p>
<ul>
<li>
<p align="justify"><font size="2">concludere i contratti per i servizi del Titolare </font></p>
</li>
<li>
<p align="justify"><font size="2">adempiere agli obblighi precontrattuali, contrattuali e fiscali derivanti da rapporti in essere con l&rsquo;interessato;</font></p>
</li>
<li>
<p align="justify"><font size="2">adempiere agli obblighi previsti dalla legge, da un regolamento, dalla normativa comunitaria o da un ordine dell&rsquo;Autorit&agrave;;</font></p>
</li>
<li>
<p align="justify"><font size="2">prevenire o scoprire attivit&agrave; fraudolente o abusi dannosi per il sito web;</font></p>
</li>
<li>
<p align="justify"><font size="2">esercitare i diritti del Titolare, ad esempio il diritto di difesa in giudizio.</font></p>
</li>
</ul>
<p align="justify">&nbsp;</p>
<ol start="2" type="a">
<li>
<p align="justify"><font size="2"><u><b>solo previo specifico e distinto consenso</b></u></font><font size="2"> (cfr. art. 7 GDPR), per le seguenti finalit&agrave; di Marketing:</font></p>
</li>
</ol>
<p align="justify">&nbsp;</p>
<ul>
<li>
<p align="justify"><font size="2">inviare via e-mail, posta e/o sms e/o contatti telefonici, newsletter, comunicazioni commerciali e/o materiale pubblicitario su prodotti o servizi offerti dal Titolare e rilevazione del grado di soddisfazione sulla qualit&agrave; dei servizi offerti, segnalando che, ove l&rsquo;interessato fosse gi&agrave; nostro cliente, potremo inviare comunicazioni commerciali relative a servizi e prodotti del Titolare analoghi a quelli di cui l&rsquo;interessato ha gi&agrave; usufruito, salvo opposizione (cfr. art. 21 GDPR);</font></p>
</li>
<li>
<p align="justify"><font size="2">inviare a mezzo e-mail, posta e/o sms e/o contatti telefonici, comunicazioni commerciali e/o promozionali di soggetti terzi (ad esempio: business partner, compagnie assicurative, etc.);</font></p>
</li>
</ul>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2"><b>Precisazioni in ordine al trattamento per &ldquo;</b></font><font size="2"><i><b>Finalit&agrave; di Marketing</b></i></font><font size="2"><b>&rdquo; e di &ldquo;</b></font><font size="2"><i><b>Profilazione</b></i></font><font size="2"><b>&rdquo;</b></font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2">A beneficio dell&rsquo;interessato, si precisa quanto segue:</font></p>
<p align="justify">&nbsp;</p>
<ol type="A">
<li>
<p align="justify"><font size="2">I dati personali raccolti saranno trattati anche per perseguire finalit&agrave; di promozione commerciale, comunicazione pubblicitaria, sollecitazione a comportamenti di acquisto, ricerche di mercato, sondaggi (anche telefonici, on-line o mediante formulari), elaborazioni statistiche (in forma identificativa), altre ricerche campionarie di marketing in senso lato di prodotti e/o servizi riferibili alla Societ&agrave; (di seguito, complessivamente, &ldquo;</font><font size="2"><i><b>Trattamento per Finalit&agrave; di Marketing</b></i></font><font size="2">&rdquo;) sia attraverso marketing &ldquo;generico&rdquo; sia &ldquo;</font><font size="2"><i><b>profilato</b></i></font><font size="2">&rdquo; </font><font size="2">conseguente cio&egrave; all&rsquo; &ldquo;</font><font size="2"><i><b>attivit&agrave; di profilazione</b></i></font><font size="2">&rdquo;</font><font size="2">(</font><font size="2">cfr. definizione &ldquo;</font><font size="2"><u><b>Profilazione</b></u></font><font size="2">&rdquo; &ndash; art. 4 &ldquo;Definizioni&rdquo;: &ldquo;</font><font size="2"><i>qualsiasi forma di trattamento automatizzato di dati personali consistente nell&rsquo;utilizzo di tali dati personali per valutare determinati aspetti personali relativi a una persona fisica </i></font><font size="2">[&hellip;]&rdquo;)</font></p>
</li>
<li>
<p align="justify"><font size="2">In ogni caso, anche laddove l&rsquo;interessato abbia prestato il consenso, rester&agrave; comunque libero in ogni momento di </font><font size="2"><u><b>revocarlo</b></u></font><font size="2">, modificando le impostazioni dei consensi nell&rsquo;area &ldquo;</font><font size="2"><b>Comunicazione e Privacy</b></font><font size="2">&rdquo; del sito. A seguito della ricezione di tale richiesta di </font><font size="2"><i>opt-out</i></font><font size="2">, il Titolare del Trattamento proceder&agrave; tempestivamente alla rimozione e cancellazione dei dati dai database utilizzati per il &ldquo;</font><font size="2"><i><b>Trattamento per Finalit&agrave; di Marketing</b></i></font><font size="2">&rdquo; e di &ldquo;</font><font size="2"><i><b>Profilazione</b></i></font><font size="2">&rdquo; e informer&agrave; per le medesime finalit&agrave; di cancellazione eventuali terzi cui i dati siano stati comunicati.</font></p>
</li>
<li>
<p align="justify"><font size="2">Nel caso sia richiesta &ndash; per le finalit&agrave; sopra illustrate &ndash; l&rsquo;indicazione del numero di utenza telefonica dell&rsquo;interessato e questi abbia prestato il consenso opzionale e specifico (che copre anche il trattamento di tale dato personale) per le finalit&agrave; di promozione commerciale, di marketing e di profilazione sopra illustrate, il Titolare del Trattamento informa l&rsquo;interessato che potr&agrave; legalmente trattare l&rsquo;utenza telefonica per scopi marketing e di profilazione anche se essa risulti iscritta al Registro Pubblico delle Opposizioni, in quanto tratta da fonte diversa dagli elenchi telefonici pubblici e coperta da specifico consenso, salvo il diritto di opposizione successiva al trattamento ove sia formalmente revocato il consenso.</font></p>
</li>
<li>
<p align="justify"><font size="2">Si informa specificatamente e separatamente, come richiesto dall&rsquo;art. 21 del GDPR che l&#39;interessato ha il diritto di opporsi in qualsiasi momento al trattamento dei dati personali che lo riguardano effettuato per tali finalit&agrave; e che qualora l&#39;interessato si opponga al trattamento per finalit&agrave; di marketing diretto e profilazione, i dati personali non potranno pi&ugrave; essere oggetto di trattamento per tali finalit&agrave;.</font></p>
</li>
</ol>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2"><b>Diritti dell&rsquo;interessato</b></font><font size="2">: </font></p>
<p align="justify">&nbsp;</p>
<p align="justify"><font size="2">In conformit&agrave; a quanto previsto dall&rsquo;art. 7, D.lgs.n.196/2003 e GDPR l&rsquo;interessato potr&agrave; esercitare i seguenti diritti</font></p>
<p>&nbsp;</p>
<ul>
<li>
<p align="justify"><font size="2">chiedere al titolare del trattamento l&#39;</font><font size="2"><u><b>accesso ai dati personali</b></u></font><font size="2"> onde poter avere conferma che sia o meno in corso un trattamento di dati personali che lo riguardano e in tal caso, ottenere tutte le necessarie informazioni secondo quanto meglio previsto e disciplinato dall&rsquo;</font><font size="2"><u>articolo 15</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Diritto di accesso dell&rsquo;interessato</b></i></font><font size="2">&rdquo; GDPR, e articolo 7, comma 1, D.lgs.n.196/2003;</font></p>
</li>
<li>
<p align="justify"><font size="2">chiedere al titolare del trattamento la </font><font size="2"><u><b>rettifica dei dati personali</b></u></font><font size="2"> inesatti che lo riguardano come anche l&rsquo;integrazione di quelli incompleti secondo quanto meglio previsto e disciplinato dall&rsquo;</font><font size="2"><u>articolo 16</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Diritto di rettifica</b></i></font><font size="2">&rdquo; GDPR e articolo 7, comma 3, lettera a), D.lgs.n.196/2003;</font></p>
</li>
<li>
<p align="justify"><font size="2">chiedere al titolare del trattamento la </font><font size="2"><u><b>cancellazione dei dati personali</b></u></font><font size="2"> che lo riguardano nell&rsquo;eventualit&agrave; in cui i dati non sono pi&ugrave; necessari rispetto alle finalit&agrave; per le quali sono stati raccolti o altrimenti trattati (lettera a); l&rsquo;interessato abbia revocato il consenso o non sussiste fondamento giuridico per il trattamento (lettera b); l&rsquo;interessato si sia opposto al trattamento ex art. 21, paragrafi 1 o 2, e non sussistano motivi prevalenti per procedere, comunque, al trattamento (lettera c); il trattamento sia illecito (lettera d); la cancellazione dei dati costituisca adempimento di obbligo legale a cui &egrave; soggetto il titolare del trattamento (lettera e); laddove sussista l&rsquo;ipotesi prevista dall&rsquo;articolo 8, paragrafo 1 (lettera f), il tutto &ndash; in ogni caso &ndash; secondo quanto meglio previsto e disciplinato dall&rsquo;</font><font size="2"><u>articolo 17</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Diritto alla cancellazione (&ldquo;diritto all&rsquo;oblio&rdquo;)</b></i></font><font size="2"> GDPR e articolo 7, comma 3, lettera b), D.lgs.n.196/2003;</font></p>
</li>
<li>
<p align="justify"><font size="2">ottenere dal titolare del trattamento la </font><font size="2"><u><b>limitazione del trattamento</b></u></font><font size="2"> stesso allorquando: l&rsquo;interessato contesti l&rsquo;esattezza dei dati personali (in questo caso nei limiti del tempo necessario a verificare l&rsquo;esattezza di tali dati &ndash; lettera a); in ipotesi di trattamento illecito, l&rsquo;interessato si opponga &ndash; per&ograve; &ndash; alla cancellazione dei dati chiedendo, invece, che ne sia limitato l&rsquo;utilizzo (lettera b); a prescindere dal fatto che il titolare del trattamento non ne abbia pi&ugrave; bisogno per i fini del trattamento stesso, l&rsquo;interessato abbia necessit&agrave; di mantenere il dato per finalit&agrave; di accertamento, esercizio o difesa in sede giudiziaria (lettera c); l&rsquo;interessato si sia opposto al trattamento ex art. 21, paragrafo 1, in attesa della verifica sull&rsquo;eventuale prevalenza dei motivi legittimi del titolare rispetto a quelli dell&rsquo;interessato (lettera d), il tutto &ndash; in ogni caso &ndash; secondo quanto meglio previsto e disciplinate all&rsquo;</font><font size="2"><u>articolo 18</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Diritto di limitazione di trattamento</b></i></font><font size="2">&rdquo;;</font></p>
</li>
<li>
<p align="justify"><font size="2">in qualsiasi momento, per motivi connessi alla sua particolare situazione, </font><font size="2"><u><b>opporsi al trattamento</b></u></font><font size="2"> dei dati personali che lo riguardano, ai sensi dell&rsquo;articolo 6, paragrafo 1, lettere e) o f), compresa la </font><font size="2"><b>profilazione</b></font><font size="2"> sulla base di tali disposizioni, oltre che nel caso di trattamento dei dati per finalit&agrave; di marketing compresa, anche, in questo caso la profilazione nella misura in cui sia connessa a tale marketing diretto. Il tutto, in ogni caso, secondo quanto meglio previsto e disciplinato all&rsquo;</font><font size="2"><u>articolo 21</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Diritto di opposizione</b></i></font><font size="2">&rdquo; GDPR e articolo 7, comma 4, lettere a) e b), D.lgs.n.196/2003;</font></p>
</li>
<li>
<p align="justify"><font size="2">ottenere la </font><font size="2"><u><b>portabilit&agrave; dei dati</b></u></font><font size="2"> secondo quanto meglio previsto e disciplinate all&rsquo;</font><font size="2"><u>articolo 20</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Diritto alla portabilit&agrave; dei dati</b></i></font><font size="2">&rdquo;;</font></p>
</li>
<li>
<p align="justify"><font size="2">in qualsiasi momento, </font><font size="2"><u><b>revocare il proprio consenso</b></u></font><font size="2"> al trattamento dei dati</font><font size="2"> senza che ci&ograve; possa pregiudicare le liceit&agrave; del trattamento basato sul consenso prima della revoca. </font><font size="2">Il tutto, in ogni caso, secondo quanto meglio previsto e disciplinato dall&rsquo;</font><font size="2"><u>articolo 7</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Condizioni per il consenso</b></i></font><font size="2">&rdquo;.</font></p>
</li>
<li>
<p align="justify"><font size="2">proporre reclamo ad una Autorit&agrave; di controllo con il compito di sorvegliare l&rsquo;applicazione del GDPR al fine di tutelare i diritti e le libert&agrave; fondamenti delle persone fisiche con riguardo al trattamento dei dati personali.</font><font size="2"> Il tutto, in ogni caso, secondo quanto meglio previsto e disciplinato dagli </font><font size="2"><u>articoli 51 e segg.</u></font><font size="2"> &ldquo;</font><font size="2"><i><b>Autorit&agrave; di controllo</b></i></font><font size="2">&rdquo;;</font></p>
</li>
</ul>
<p>&nbsp;</p>
Before usage read: https://usermanual.vtenext.com/books/user-manual-vtenext-2205/page/71-how-to-create-contact-campaigns

View File

@ -8,106 +8,219 @@
class RequestHandler {
// crmv@177677
/**
* Return a "unique" id for each requests
* Remember: not guaranteed to be 100% unique, but enough for common use
*/
static public function getId() {
static $requestId = null;
if (is_null($requestId)) {
global $application_unique_key;
$cliflag = (php_sapi_name() == 'cli' ? 'C' : 'W');
$prefix = substr($application_unique_key, 0, 2) . $cliflag;
$requestId = uniqid($prefix, true);
}
return $requestId;
}
// crmv@177677e
// crmv@177677
/**
* Return a "unique" id for each requests
* Remember: not guaranteed to be 100% unique, but enough for common use
*/
static public function getId() {
static $requestId = null;
if (is_null($requestId)) {
global $application_unique_key;
$cliflag = (php_sapi_name() == 'cli' ? 'C' : 'W');
$prefix = substr($application_unique_key, 0, 2) . $cliflag;
$requestId = uniqid($prefix, true);
}
return $requestId;
}
// crmv@177677e
static public function processCompressedRequest() {
$compressedData = $_REQUEST['compressedData'] ?? '';
static public function processCompressedRequest() {
$compressedData = $_REQUEST['compressedData'] ?? '';
if ($compressedData === 'true' && isset($_FILES['payload'])) {
if ($_FILES['payload']['error'] != 0) throw new Exception('File upload error');
if ($compressedData === 'true' && isset($_FILES['payload'])) {
if ($_FILES['payload']['error'] != 0) throw new Exception('File upload error');
$fmt = $_REQUEST['compressFormat'];
$serial = $_REQUEST['serializeFormat'];
$fmt = $_REQUEST['compressFormat'];
$serial = $_REQUEST['serializeFormat'];
// uncompress
if ($fmt === 'gzip') {
$zp = gzopen($_FILES['payload']['tmp_name'], 'rb');
if ($zp) {
$rawdata = '';
while (!gzeof($zp)) {
$rawdata .= gzread($zp, 10000);
}
gzclose($zp);
} else {
throw new Exception('Unable to open compressed data');
}
} else {
throw new Exception('Unknown compression format');
}
// uncompress
if ($fmt === 'gzip') {
$zp = gzopen($_FILES['payload']['tmp_name'], 'rb');
if ($zp) {
$rawdata = '';
while (!gzeof($zp)) {
$rawdata .= gzread($zp, 10000);
}
gzclose($zp);
} else {
throw new Exception('Unable to open compressed data');
}
} else {
throw new Exception('Unknown compression format');
}
// decode
$payload = null;
if ($serial === 'serialize') {
// beware, this is still subjected to max_input_vars :(
// see http://php.net/manual/en/function.parse-str.php#108642
parse_str($rawdata, $payload);
} elseif ($serial === 'json') {
$payload = json_decode($rawdata, true);
} else {
throw new Exception('Unknown serialization format');
}
// decode
$payload = null;
if ($serial === 'serialize') {
// beware, this is still subjected to max_input_vars :(
// see http://php.net/manual/en/function.parse-str.php#108642
parse_str($rawdata, $payload);
} elseif ($serial === 'json') {
$payload = json_decode($rawdata, true);
} else {
throw new Exception('Unknown serialization format');
}
// merge with request
if (is_array($payload)) {
// crmv@162674
// Using replace to keep numeric keys
$_REQUEST = array_replace($_REQUEST, $payload);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_POST = array_replace($_POST, $payload);
}
// crmv@162674e
}
}
}
// merge with request
if (is_array($payload)) {
// crmv@162674
// Using replace to keep numeric keys
$_REQUEST = array_replace($_REQUEST, $payload);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_POST = array_replace($_POST, $payload);
}
// crmv@162674e
}
}
}
static public function outputRedirect($url, $rformat = null) {
if (!$rformat) $rformat = $_REQUEST['responseFormat'];
static public function outputRedirect($url, $rformat = null) {
if (!$rformat) $rformat = $_REQUEST['responseFormat'];
if ($rformat === 'json') {
$result = array('success' => true, 'redirect' => $url);
header('Content-type: application/json');
echo json_encode($result);
exit();
}
if ($rformat === 'json') {
$result = array('success' => true, 'redirect' => $url);
header('Content-type: application/json');
echo json_encode($result);
exit();
}
header("Location: $url");
}
header("Location: $url");
}
// crmv@171581
static public function getCSRFToken() {
$VP = VTEProperties::getInstance();
if ($VP->getProperty('security.csrf.enabled')) {
$VTECSRF = new VteCsrf();
return $VTECSRF->csrf_get_tokens();
} else {
return '';
}
}
// crmv@171581
static public function getCSRFToken() {
$VP = VTEProperties::getInstance();
if ($VP->getProperty('security.csrf.enabled')) {
$VTECSRF = new VteCsrf();
return $VTECSRF->csrf_get_tokens();
} else {
return '';
}
}
static public function validateCSRFToken() {
$VP = VTEProperties::getInstance();
if ($VP->getProperty('security.csrf.enabled')) {
$VTECSRF = new VteCsrf();
return $VTECSRF->csrf_check();
} else {
return true;
}
}
// crmv@171581e
static public function validateCSRFToken() {
$VP = VTEProperties::getInstance();
if ($VP->getProperty('security.csrf.enabled')) {
$VTECSRF = new VteCsrf();
return $VTECSRF->csrf_check();
} else {
return true;
}
}
// crmv@171581e
//crmv@211287
static public function paramGet($name){
return $_GET[$name];
}
static public function paramPost($name){
return $_POST[$name];
}
static public function param($name){
return $_REQUEST[$name];
}
static public function filterIntParam($value){
return intval($value);
}
static public function filterStringParam($value, $maxLength=100){
return substr(strip_tags($value), 0, $maxLength);
}
static public function filterHtmlParam($value){
return vtlib_purify($value);
}
static public function filterFloatParam($value){
return floatval($value);
}
static public function filterBoolParam($value){
return filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
static public function filterModuleParam($value){
return preg_replace("/[^a-zA-Z0-9_\-\s]/", '', $value);//allow only letters, numbers and '-' '_' ' '
}
static public function paramInt($name){
return self::filterIntParam(self::param($name));
}
static public function paramString($name, $maxLength = 100){
return self::filterStringParam(self::param($name), $maxLength);
}
static public function paramFloat($name){
return self::filterFloatParam(self::param($name));
}
static public function paramHtml($name){
return self::filterHtmlParam(self::param($name));
}
static public function paramBool($name){
return self::filterBoolParam(self::param($name));
}
static public function paramGetInt($name){
return self::filterIntParam(self::paramGet($name));
}
static public function paramGetString($name, $maxLength = 100){
return self::filterStringParam(self::paramGet($name), $maxLength);
}
static public function paramGetFloat($name){
return self::filterFloatParam(self::paramGet($name));
}
static public function paramGetHtml($name){
return self::filterHtmlParam(self::paramGet($name));
}
static public function paramGetBool($name){
return self::filterBoolParam(self::paramGet($name));
}
static public function paramPostInt($name){
return self::filterIntParam(self::paramPost($name));
}
static public function paramPostString($name, $maxLength = 100){
return self::filterStringParam(self::paramPost($name), $maxLength);
}
static public function paramPostFloat($name){
return self::filterFloatParam(self::paramPost($name));
}
static public function paramPostHtml($name){
return self::filterHtmlParam(self::paramPost($name));
}
static public function paramPostBool($name){
return self::filterBoolParam(self::paramPost($name));
}
static public function paramModule($name){
return self::filterModuleParam(self::param($name));
}
static public function paramAction($name){
return self::filterModuleParam(self::param($name));
}
static public function paramField($name){
return self::filterModuleParam(self::param($name));
}
static public function paramParentTab($name){
return self::filterModuleParam(self::param($name));
}
//crmv@211287
}

View File

@ -9,7 +9,7 @@ function getUserAuthtokenKey($type,$user_id,$seconds_to_expire, $securetoken = f
global $adb;
emptyUserAuthtokenKey($type,$user_id);
//crmv@29377
//genera un token più sicuro
//genera un token pi? sicuro
if ($securetoken){
$authToken = md5(crypt(strval(microtime(true)+(mt_rand(0, 10000) / 10.0)).strval($user_id).$type)); // crmv@179766
} else {
@ -26,23 +26,25 @@ function getUserAuthtokenKey($type,$user_id,$seconds_to_expire, $securetoken = f
}
}
function validateUserAuthtokenKey($type,$key) {
// crmv@341733: always check key as string, move check into query
function validateUserAuthtokenKey($type, $key) {
global $adb;
$tmp = Zend_Json::decode(base64_decode($key));
$user_id = (int)$tmp['userid'];
$token = $tmp['token'];
$sql_d = "delete from vte_userauthtoken where type=? and userid=? and expiretime < ?";
$result_d = $adb->pquery($sql_d,array($type,$user_id,time()));
$sql = "select * from vte_userauthtoken where type=? and userid=? and expiretime >= ?";
$result = $adb->pquery($sql,array($type,$user_id,time()));
if($result != null && isset($result) && $adb->num_rows($result)>0){
$token_saved = $adb->query_result($result,0,'token');
if ($token_saved == $token) {
return $user_id;
}
$token = strval($tmp['token']);
$sql_d = "delete from vte_userauthtoken where type = ? and userid = ? and expiretime < ?";
$result_d = $adb->pquery($sql_d, [$type, $user_id, time()]);
$sql = "select * from vte_userauthtoken where type = ? and userid = ? and token = ? and expiretime >= ?";
$result = $adb->pquery($sql, [$type, $user_id, $token, time()]);
if ($result && $adb->num_rows($result) > 0) {
return $user_id;
}
return false;
}
// crmv@341733e
function emptyUserAuthtokenKey($type,$user_id) {
global $adb;

View File

@ -4,9 +4,11 @@
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
require_once('include/utils/utils.php');
require_once("modules/Calendar/calendarLayout.php");
require_once("modules/Calendar/Calendar.php");
global $theme,$mod_strings,$app_strings, $current_language,$currentModule,$current_user;
global $adb, $table_prefix;
@ -178,7 +180,10 @@ if((isset($_REQUEST['type']) && $_REQUEST['type'] !='') || (isset($_REQUEST['n_t
echo constructTodoListView($todo_list,$calendar_arr,$subtab,$navigation_arr)."####".getTodoInfo($calendar_arr,'listcnt');
}
} elseif($type == 'view') {
require_once('modules/Calendar/'.$_REQUEST['file'].'.php');
// crmv@345820
$reqfile = preg_replace("/[^a-zA-Z0-9_\-\/]/", '', $_REQUEST['file']);
require_once("modules/Calendar/{$reqfile}.php");
// crmv@345820e
} else {
die("View option is not defined");
}

View File

@ -26,6 +26,9 @@ if ($theme === 'next') {
}
// crmv@187406e
include("modules/Calendar/wdCalendar/$file.php");
// crmv@345820
$file = preg_replace("/[^a-zA-Z0-9_\-\/]/", '', $file);
include("modules/Calendar/wdCalendar/{$file}.php");
// crmv@345820e
//crmv@17001e
?>

View File

@ -19,15 +19,15 @@ if($_REQUEST['fax_error'] != '')
}
//added to select the module in combobox of compose-popup
if(isset($_REQUEST['par_module']) && $_REQUEST['par_module']!=''){
$smarty->assign('select_module',$_REQUEST['par_module']);
$smarty->assign('select_module',RequestHandler::paramModule("par_module"));//crmv@211287
}
elseif(isset($_REQUEST['pmodule']) && $_REQUEST['pmodule']!='') {
$smarty->assign('select_module',$_REQUEST['pmodule']);
$smarty->assign('select_module',RequestHandler::paramModule("pmodule"));//crmv@211287
}
if(isset($_REQUEST['record']) && $_REQUEST['record'] !='')
{
$focus->id = $_REQUEST['record'];
$focus->id = RequestHandler::paramInt("record");//crmv@211287
$focus->mode = 'edit';
$focus->retrieve_entity_info($_REQUEST['record'],"Fax");
if(isset($_REQUEST['forward']) && $_REQUEST['forward'] != '')
@ -63,36 +63,53 @@ if($_REQUEST["internal_mailer"] == "true") {
$rec_id = $_REQUEST["rec_id"];
$fieldname = $_REQUEST["fieldname"];
//crmv@345820
function get_entity_fax($modulename, $fieldname, $id, $html = false) {
global $current_user;
$fail = '';
if ($modulename == 'Users') {
if (!preg_match('/^phone/', $fieldname)) {
return $fail;
}
} elseif (isPermitted($modulename, 'DetailView', $id) !== 'yes') {
return $fail;
} elseif (!in_array(getFieldVisibilityPermission($modulename, $current_user->id, $fieldname), [0, '0'], true)) {
return $fail;
}
$fieldinfo = FieldUtils::getField($modulename, $fieldname);
if (!$fieldinfo) {
return $fail;
}
$tablename = $fieldinfo['tablename'];
switch ($modulename) {
case "Users": $keycol = "id"; break;
case "Leads": $keycol = "leadaddressid"; break;
case "Contacts": $keycol = "contactid"; break;
case "Accounts": $keycol = "accountid"; break;
case "Vendors": $keycol = "vendorid"; break;
default: return $fail;
}
return getSingleFieldValue($tablename, $fieldinfo['columnname'], $keycol, $id, $html) ?? $fail;
}
//crmv@345820e
//added for getting list-ids to compose email popup from list view(Accounts,Contacts,Leads)
if(isset($_REQUEST['field_id']) && strlen($_REQUEST['field_id']) != 0) {
if($_REQUEST['par_module'] == "Users")
$id_list = $_REQUEST['rec_id'].'@'.'-1|';
else
$id_list = $_REQUEST['rec_id'].'@'.$_REQUEST['field_id'].'|';
$id_list = RequestHandler::paramString("rec_id").'@'.RequestHandler::paramString("field_id").'|';//crmv@211287
$smarty->assign("IDLISTS", $id_list);
}
if($rec_type == "record_id") {
$type = $_REQUEST['par_module'];
//check added for email link in user detail view
// crmv@64542
$modInstance = CRMEntity::getInstance($type);
if(substr($fieldname,0,2)=="cf")
$tablename = $modInstance->customFieldTable[0];
else
$tablename = $modInstance->table_name;
// crmv@64542e
if($type == "Users")
$q = "select $fieldname from $tablename where id=?";
elseif($type == "Leads")
$q = "select $fieldname from $tablename where leadaddressid=?";
elseif ($type == "Contacts")
$q = "select $fieldname from $tablename where contactid=?";
elseif ($type == "Accounts")
$q = "select $fieldname from $tablename where accountid=?";
elseif ($type == "Vendors")
$q = "select $fieldname from $tablename where vendorid=?";
$to_fax = $adb->query_result($adb->pquery($q, array($rec_id)),0,$fieldname);
$to_fax = get_entity_fax($type, $fieldname, $rec_id, true); //crmv@345820
} elseif ($rec_type == "email_addy") {
$to_fax = $_REQUEST["email_addy"];
}
@ -140,15 +157,15 @@ if (isset($_REQUEST['parent_type']))
}
if (isset($_REQUEST['filename']) && $_REQUEST['isDuplicate'] != 'true')
{
$focus->filename = $_REQUEST['filename'];
$focus->filename = RequestHandler::paramString("filename");
}
elseif (is_null($focus->parent_type))
{
$focus->parent_type = $app_list_strings['record_type_default_key'];
}
$smarty->assign("ENTITY_ID", $_REQUEST["record"]);
$smarty->assign("ENTITY_TYPE",$_REQUEST["fax_directing_module"]);
$smarty->assign("ENTITY_ID", RequestHandler::paramInt("record"));//crmv@211287
$smarty->assign("ENTITY_TYPE",RequestHandler::paramModule("fax_directing_module"));//crmv@211287
$smarty->assign("OLD_ID", $old_id );
//Display the FCKEditor or not? -- configure $FCKEDITOR_DISPLAY in config.php
$smarty->assign("FCKEDITOR_DISPLAY",$FCKEDITOR_DISPLAY);

View File

@ -19,6 +19,8 @@ require_once('include/home.php');
$homeObj=new Homestuff;
$widgetTypes = ['URL','SDKIframe','Iframe','Charts','Module','RSS','Default']; // crmv@345820
Zend_Json::$useBuiltinEncoderDecoder = true;
$widgetInfoList = Zend_Json::decode($_REQUEST['widgetInfoList']);
$widgetHTML = array();
@ -28,9 +30,21 @@ $smarty->assign("APP",$app_strings);
$smarty->assign("THEME", $theme);
$smarty->assign("IMAGE_PATH",$image_path);
// crmv@345820
$accessibleWidgets = [];
$homedetails = $homeObj->getHomePageFrame();
if (!empty($homedetails)) {
foreach($homedetails as $homedetail) {
$accessibleWidgets[] = $homedetail['Stuffid'];
}
}
// crmv@345820e
foreach ($widgetInfoList as $widgetInfo) {
$widgetType = $widgetInfo['widgetType'];
$widgetId = $widgetInfo['widgetId'];
$widgetType = array_intersect([$widgetInfo['widgetType']], $widgetTypes)[0] ?? ''; // crmv@345820
$widgetId = intval($widgetInfo['widgetId']); // crmv@345820
if (!in_array($widgetId, $accessibleWidgets)) continue; // crmv@345820
if($widgetType == 'URL'){
$url = $homeObj->getWidgetURL($widgetId);
if(strpos($url, "://") === false){
@ -106,5 +120,7 @@ foreach ($widgetInfoList as $widgetInfo) {
$html .= $smarty->fetch("Home/HomeBlock.tpl");
$widgetHTML[$widgetId] = $html;
}
header('Content-Type: application/json'); // crmv@345820
echo Zend_JSON::encode($widgetHTML);
?>

View File

@ -31,11 +31,11 @@ class Import_ListView_Controller {
$viewer = new Import_UI_Viewer();
$ownerId = $userInputObject->get('foruser');
$ownerId = intval($userInputObject->get('foruser')); // crmv@341226
$owner = CRMEntity::getInstance('Users');
$owner->id = $ownerId;
$owner->retrieve_entity_info($ownerId, 'Users');
if(!is_admin($user) && $user->id != $owner->id) {
if (!is_admin($user) && $user->id !== $owner->id) { // crmv@341226
$viewer->display('OperationNotPermitted.tpl', 'VteCore');
exit;
}

View File

@ -49,7 +49,7 @@ class Import_Utils {
public static function getImportFilePath($user) {
$importDirectory = self::getImportDirectory();
return $importDirectory. "IMPORT_".$user->id;
return $importDirectory. "IMPORT_".intval($user->id); // crmv@341226
}
@ -82,7 +82,7 @@ class Import_Utils {
public static function getDbTableName($user) {
$configReader = new ConfigReader('modules/Import/config.inc', 'ImportConfig');
$userImportTablePrefix = $configReader->getConfig('userImportTablePrefix');
return $userImportTablePrefix . $user->id;
return $userImportTablePrefix . intval($user->id); // crmv@341226
}
public static function showErrorPage($errorMessage, $errorDetails=false, $customActions=false) {

View File

@ -29,7 +29,7 @@ if ($_REQUEST['morph_mode'] == 'installation' || VteSession::get('morph_mode') =
if ($enterprise_mode == 'VTENEXTCE') { // crmv@192073
// recalc application_unique_key
$application_unique_key = md5(time() + rand(1,9999999) + md5($root_directory));
$application_unique_key = md5(time() . rand(1,9999999) . md5($root_directory));
$configInc = file_get_contents('config.inc.php');
$configInc = preg_replace('/^\$application_unique_key.*$/m', "\$application_unique_key = '{$application_unique_key}';", $configInc);
if (is_writable('config.inc.php')) file_put_contents('config.inc.php', $configInc);

View File

@ -13,6 +13,12 @@ if ($_REQUEST['mode'] == 'save' && $_REQUEST['avatar'] != '') {
$focus->id = $record;
$focus->mode = 'edit';
$focus->column_fields['avatar'] = $_REQUEST['avatar'];
// crmv@341228
if (!$focus->filterOrDenySave()) {
RequestHandler::outputRedirect("index.php?module=Users&action=Logout");
exit;
}
// crmv@341228e
$focus->save("Users");
echo "<script>

View File

@ -40,6 +40,13 @@ if (!isset($root_directory)) {
chdir($root_directory);
}
// crmv@345820
if (strpos(getenv('SCRIPT_FILENAME'),$root_directory.'modules/Touch/ws.php') === false) {
header("HTTP/1.1 403 Forbidden");
exit();
}
// crmv@345820e
global $current_user;
require_once('modules/Touch/Touch.php');

View File

@ -28,6 +28,10 @@ foreach($recDirs as $recDir){
foreach($recData as $id => $files){
foreach($files as $file){
//skip this one, since it's deleted after the update
if ($file == 'cron/modules/com_vtiger_workflow/com_vtiger_workflow.service.php') {
continue;
}
$fileData = file_exists($file) ? file_get_contents($file) : false;
if($fileData){
foreach($words as $word){

View File

@ -22,7 +22,7 @@ if ($res) {
foreach($resultSet as $index => $value ){
//can be edited, it is in this format in case you need to edit strings in other formats
//può essere modificato, è in questo formato nel caso in cui sia necessario modificare le stringhe in altri formati
if (str_contains($value, 'vTiger')) {
if (strpos($value, 'vTiger') !== false) {
$value2 = str_replace('vTiger',"vte",$value);
}
else{

View File

@ -0,0 +1,13 @@
<?php
/* new release 20.04.3 */
global $enterprise_current_version, $enterprise_mode;
SDK::setLanguageEntries('APP_STRINGS', 'LBL_BROWSER_TITLE', array(
'it_it'=>"$enterprise_mode $enterprise_current_version",
'en_us'=>"$enterprise_mode $enterprise_current_version",
'de_de'=>"$enterprise_mode $enterprise_current_version",
'nl_nl'=>"$enterprise_mode $enterprise_current_version",
'pt_br'=>"$enterprise_mode $enterprise_current_version")
);

View File

@ -15,18 +15,7 @@ if($ajaxaction == "DETAILVIEW")
$tablename = $_REQUEST["tableName"];
$fieldname = $_REQUEST["fldName"];
//crmv@74565
if(strtolower($current_user->is_admin) == 'off' && $current_user->id != $crmid){
$log->fatal("SECURITY:Non-Admin ". $current_user->id . " attempted to change settings for user:". $crmid);
header("Location: index.php?module=Users&action=Logout");
exit;
}
if(strtolower($current_user->is_admin) == 'off' && $fieldname == 'is_admin'){
$log->fatal("SECURITY:Non-Admin ". $current_user->id . " attempted to change is_admin settings for user: ". $crmid);
header("Location: index.php?module=Users&action=Logout");
exit;
}
//crmv@74565e
// crmv@341228: moved to Users::filterOrDenySave()
$fieldvalue = utf8RawUrlDecode($_REQUEST["fieldValue"]);
if($crmid != "")
@ -48,9 +37,16 @@ if($ajaxaction == "DETAILVIEW")
$modObj->id = $crmid;
$modObj->mode = "edit";
$modObj->save($currentModule);
// crmv@341228
if (!$modObj->filterOrDenySave()) {
RequestHandler::outputRedirect("index.php?module=Users&action=Logout"); // crmv@150748
exit;
}
$modObj->save($currentModule);
// crmv@341228e
if($modObj->id != "") {
echo ":#:SUCCESS";
echo ":#:SUCCESS";
} else {
echo ":#:FAILURE";
}

View File

@ -3,9 +3,15 @@
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
//crmv@35153
// crmv@35153 crmv@341231
global $current_user;
if (!is_admin($current_user)) {
header('HTTP/1.0 403 Forbidden');
include('modules/Users/403error.html');
exit;
}
$record = vtlib_purify($_REQUEST['record']);
echo getUserName($record);
exit;
//crmv@35153e
?>

View File

@ -16,37 +16,150 @@ class RecoverPwd {
private $max_recover_attempts_window = 3600; // seconds
private $max_recover_attempts_sleep = 3600; // seconds
// crmv@341733
// crmv@273083
private static function alignTime($seconds = null) {
static $timestamp1 = null;
if ($timestamp1 === null || $seconds === null) {
$timestamp1 = microtime(true);
return;
}
$timestamp2 = microtime(true);
$u_elapsed = intdiv($timestamp2 - $timestamp1, 1000); // 1 billionth to 1 millionth
$u_remain = ($seconds * 1000000) - $u_elapsed;
if ($u_remain > 0)
usleep($u_remain);
$timestamp1 = null;
}
// crmv@273083e
private function trackAttemptPermitted(int $incr, string $force_status = null): bool {
global $adb;
$ip = getIP();
$type = 'password_recovery';
$now = date('Y-m-d H:i:s');
$user = CRMEntity::getInstance('Users');
$result = $adb->pquery("select * from {$user->track_login_table} where ip = ? and type = ?", [$ip, $type]);
if ($result && $adb->num_rows($result) > 0) {
$id = $adb->query_result($result, 0, 'id');
$attempts = $adb->query_result($result, 0, 'attempts') + $incr;
$current_status = $adb->query_result($result, 0, 'status');
$first_attempt = $adb->query_result($result, 0, 'first_attempt');
$last_attempt = $adb->query_result($result, 0, 'last_attempt');
$update = [
'last_attempt' => $now,
'attempts' => $attempts,
'status' => $current_status,
];
if ($incr > 0) {
if ($current_status == 'L') { // locked
if ((time() - strtotime($last_attempt)) >= $this->max_recover_attempts_sleep) {
// new attempt after 1 hour from the last attempt -> reset
$update['first_attempt'] = $now;
$update['attempts'] = $incr;
$update['status'] = '';
}
} else {
if ((time() - strtotime($first_attempt)) >= $this->max_recover_attempts_window) {
// new attempt after 1 hour from the first attempt -> reset
$update['first_attempt'] = $now;
$update['attempts'] = $incr;
}
}
if ($update['attempts'] >= $this->max_recover_attempts) {
// too many attempts in any case
$update['status'] = 'L';
}
}
if ($incr > 0 || $force_status !== null) {
$update['status'] = $force_status ?? $update['status'];
$query = "update {$user->track_login_table} set " . implode('=?,', array_keys($update)) . "=? where id = ?";
$adb->pquery($query, [$update, $id]);
}
return ($update['status'] == '');
} elseif ($incr == 0) {
return true;
}
// insert
$params = [
$adb->getUniqueID($user->track_login_table),
0,
$now,
$now,
$ip,
$type,
1,
$force_status ?? ''
];
$adb->pquery("insert into {$user->track_login_table} (id, userid, first_attempt, last_attempt, ip, type, attempts, status) values (" . generateQuestionMarks($params) . ")", $params);
return ($force_status ?: '') == '';
}
// crmv@341733e
// crmv@341733
public function process(&$request, &$post) {
global $default_charset;
$action = $request['action'];
$this->alignTime();
$smarty = $this->initSmarty();
header('Content-Type: text/html; charset=' . $default_charset);
if ($action == 'change_password') {
$body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
// check ban
if (!$this->trackAttemptPermitted(0)) {
$body = $this->tooManyAttempts();
} elseif ($action == 'change_password') {
$body = $this->displayChangePwd($smarty, $post['key'], $post['new_password'], $post['confirm_new_password']);
} elseif ($action == 'recover') {
$body = $this->displayRecoverLandingPage($smarty, $request['key']);
} elseif ($action == 'recover1') {
$body = $this->displayRecover($smarty, $request['key']);
$body = $this->displayRecover($smarty, $post['key']);
} elseif ($action == 'send') {
$body = $this->displaySend($smarty, $post['user_name']);
} elseif ($action == 'change_old_pwd') {
$body = $this->displayChangeOldPwd($smarty, $request['key']);
} elseif ($action == 'change_old_pwd_send') {
$body = $this->displayChangeOldPwdSend($smarty, $post['key'], $post['old_password'], $post['new_password']);
// increase attempt
} elseif (!$this->trackAttemptPermitted(1)) {
$body = $this->tooManyAttempts();
} else {
$body = $this->displayMainForm($smarty);
}
$this->alignTime(5);
$smarty->assign('BODY', $body);
$smarty->display('Recover.tpl');
}
// crmv@341733e
public function initSmarty() {
global $current_language, $default_language, $theme, $enterprise_website;
global $current_language, $default_language, $theme, $default_theme, $enterprise_website; // crmv@231010
$current_language = $default_language;
if (!$theme) $theme = $default_theme; // crmv@231010
$smarty = new VteSmarty();
$smarty->assign('PATH','../');
@ -55,23 +168,35 @@ class RecoverPwd {
$smarty->assign('ENTERPRISE_WEBSITE', $enterprise_website);
$smarty->assign('TITLE', getTranslatedString('LBL_RECOVER_EMAIL_SUBJECT', 'Users'));
// crmv@231010
$TU = ThemeUtils::getInstance();
$backgroundColor = $TU->getLoginBackgroundColor();
$backgroundImage = $TU->getLoginBackgroundImage();
if (!empty($backgroundColor)) $smarty->assign('BACKGROUND_COLOR', $backgroundColor);
if (!empty($backgroundImage['path'])) $smarty->assign('BACKGROUND_IMAGE', $backgroundImage['path']);
// crmv@231010e
return $smarty;
}
public function displayMainForm($smarty) {
// crmv@341733
public function tooManyAttempts() {
global $site_URL;
$permitted = $this->track();
if (!$permitted) {
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_TOO_MANY_ATTEMPTS','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_TOO_MANY_ATTEMPTS','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
return $description;
}
return $description;
}
// crmv@341733e
public function displayMainForm($smarty) {
global $site_URL;
// crmv@206770_3.2
$description = '<form action="" onSubmit="if(checkRecoverForm()){ VteJS_DialogBox.block(); } else { return false; }" method="POST" autocomplete="off">
@ -109,98 +234,36 @@ class RecoverPwd {
return $description;
}
function track() {
global $adb;
$ip = getIP();
$type = 'password_recovery';
$now = date('Y-m-d H:i:s');
$user = CRMEntity::getInstance('Users');
$result = $adb->pquery("select * from {$user->track_login_table} where ip = ? and type = ?",array($ip, $type));
if ($result && $adb->num_rows($result) > 0) {
$id = $adb->query_result($result,0,'id');
$attempts = $adb->query_result($result,0,'attempts') + 1;
$current_status = $adb->query_result($result,0,'status');
$first_attempt = $adb->query_result($result,0,'first_attempt');
$last_attempt = $adb->query_result($result,0,'last_attempt');
$update = [
'last_attempt' => $now,
'attempts' => $attempts,
'status' => $current_status,
];
if ($current_status == 'L') {
// new attempt after 1 hour from the last attempt -> reset
if ((time() - strtotime($last_attempt)) >= $this->max_recover_attempts_sleep) {
$update['first_attempt'] = $now;
$update['attempts'] = 1;
$update['status'] = '';
}
} else {
// new attempt in 1 hour from the first attempt
if ((time() - strtotime($first_attempt)) < $this->max_recover_attempts_window) {
if ($attempts >= $this->max_recover_attempts) {
$update['status'] = 'L';
}
} else {
// new attempt after 1 hour from the first attempt -> reset
$update['first_attempt'] = $now;
$update['attempts'] = 1;
}
}
$query = "update {$user->track_login_table} set ".implode('=?,',array_keys($update))."=? where id = ?";
$adb->pquery($query,array($update, $id));
return ($update['status'] == '');
} else {
$params = array(
$adb->getUniqueID($user->track_login_table),
0,
$now,
$now,
$ip,
$type,
1,
''
);
$adb->pquery("insert into {$user->track_login_table} (id, userid, first_attempt, last_attempt, ip, type, attempts, status) values (".generateQuestionMarks($params).")",$params);
}
return true;
}
public function displaySend($smarty, $username) {
global $site_URL, $current_user;
if (empty($username)) return $this->displayError($smarty);
if (empty($username)) return $this->displayError($smarty);
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $current_user->retrieve_user_id($username);
$current_user->retrieve_entity_info($current_user->id, 'Users');
$current_language = $current_user->column_fields['default_language'];
$success = true;
$success = false;
$key = getUserAuthtokenKey($this->user_auth_token_type,$current_user->id,$this->user_auth_seconds_to_expire,true);
if ($key !== false) {
$link = "<a href='$site_URL/hub/rpwd.php?action=recover&key=$key'>".getTranslatedString('LBL_HERE','APP_STRINGS')."</a>";
$body = getTranslatedString('Dear','HelpDesk').' '.$username.',<br><br>';
$body .= sprintf(getTranslatedString('LBL_RECOVER_EMAIL_BODY1','Users'),getIP()).' '.$link.' '.getTranslatedString('LBL_RECOVER_EMAIL_BODY2','Users'); // crmv@193845
$body .= '<br><br>'.getTranslatedString("LBL_REGARDS",'HelpDesk').',<br>'.getTranslatedString("LBL_TEAM",'HelpDesk');
$success = $this->sendMail($current_user->column_fields['email1'], getTranslatedString('LBL_RECOVER_EMAIL_SUBJECT','Users'), $body);
}
$description = '
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $current_user->retrieve_user_id($username);
if (!empty($current_user->id)) {
$current_user->retrieve_entity_info($current_user->id, 'Users');
$current_language = $current_user->column_fields['default_language'];
$key = getUserAuthtokenKey($this->user_auth_token_type,$current_user->id,$this->user_auth_seconds_to_expire,true);
if ($key !== false) {
$link = "<a href='$site_URL/hub/rpwd.php?action=recover&key=$key'>".getTranslatedString('LBL_HERE','APP_STRINGS')."</a>";
$body = getTranslatedString('Dear','HelpDesk').' '.$username.',<br><br>';
$body .= sprintf(getTranslatedString('LBL_RECOVER_EMAIL_BODY1','Users'),getIP()).' '.$link.' '.getTranslatedString('LBL_RECOVER_EMAIL_BODY2','Users'); // crmv@193845
$body .= '<br><br>'.getTranslatedString("LBL_REGARDS",'HelpDesk').',<br>'.getTranslatedString("LBL_TEAM",'HelpDesk');
$success = $this->sendMail($current_user->column_fields['email1'], getTranslatedString('LBL_RECOVER_EMAIL_SUBJECT','Users'), $body);
}
}
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString(($success)?'LBL_RECOVER_MAIL_SENT':'LBL_RECOVER_MAIL_ERROR','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
return $description;
return $description;
}
@ -244,7 +307,8 @@ class RecoverPwd {
return $description;
}
public function displayRecover($smarty, $key) {
// crmv@341733: do not remove the key, pass it to next step; do not trim passwords; errmsg
public function displayRecover($smarty, $key, $errmsg = null) {
global $current_user, $site_URL;
$user_id = validateUserAuthtokenKey($this->user_auth_token_type,$key);
@ -259,20 +323,24 @@ class RecoverPwd {
return $description;
}
// remove the token the first time I load the page
emptyUserAuthtokenKey($this->user_auth_token_type,$user_id);
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $user_id;
$current_user->retrieve_entity_info($current_user->id, 'Users');
$login_link = "<a href='$site_URL'>" . getTranslatedString('LBL_HERE', 'Calendar') . "</a>";
$description = '';
// crmv@206770_3.2
$description = '
if ($errmsg) {
// global $default_charset;
// $errmsg = htmlentities($errmsg, ENT_NOQUOTES, $default_charset, false);
$description .= "<div class='alert alert-danger'>{$errmsg}</div>";
}
$description .= '
<form action="" onsubmit="VteJS_DialogBox.block();" name="ChangePassword" method="POST" autocomplete="off">
<input type="hidden" name="__csrf_token" value="'.RequestHandler::getCSRFToken().'">
<input type="hidden" name="action" value="change_password">
<input type="hidden" name="user_name" value="'.$current_user->column_fields['user_name'].'">
<input type="hidden" name="key" value="'.$key.'">
<table class="table borderless">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_SYSTEM1','Users').' <b>'.$current_user->column_fields['user_name'].'</b> '.getTranslatedString('LBL_RECOVERY_SYSTEM2','Users').' '.$login_link.' '.getTranslatedString('LBL_RECOVERY_SYSTEM3','Users').'</td></tr>
@ -304,15 +372,15 @@ class RecoverPwd {
</form>
<script>
function set_password(form) {
if (trim(form.new_password.value) == "") {
if (form.new_password.value == "") {
alert("'.getTranslatedString('ERR_ENTER_NEW_PASSWORD','Users').'");
return false;
}
if (trim(form.confirm_new_password.value) == "") {
if (form.confirm_new_password.value == "") {
alert("'.getTranslatedString('ERR_ENTER_CONFIRMATION_PASSWORD','Users').'");
return false;
}
if (trim(form.new_password.value) == trim(form.confirm_new_password.value)) {
if (form.new_password.value === form.confirm_new_password.value) {
form.submit();
return true;
}
@ -325,16 +393,35 @@ class RecoverPwd {
return $description;
}
// crmv@341733e
public function displayChangePwd($smarty, $username, $newpwd) {
// crmv@341733: validate key and password fields
public function displayChangePwd($smarty, $key, $newpwd, $confirmpwd) {
global $site_URL, $current_user;
global $adb, $table_prefix;
$user_id = validateUserAuthtokenKey($this->user_auth_token_type,$key);
if ($user_id === false) {
$description = '
<table border="0" cellpadding="5" cellspacing="0" width="100%" align="center" class="small">
<tr><td colspan="2">'.getTranslatedString('LBL_RECOVERY_SESSION_EXPIRED','Users').'</td></tr>
<tr height="25px"><td colspan="2"></td></tr>
<tr height="25px"><td colspan="2" align="right"><input type="button" class="crmbutton small edit" value="'.getTranslatedString('LBL_SIGN_IN','APP_STRINGS').'" onclick="location.href=\''.$site_URL.'\'" /></td></tr>
</table>';
return $description;
}
if (strval($newpwd) !== strval($confirmpwd)) {
return $this->displayRecover($smarty, $key, stripslashes(getTranslatedString('ERR_REENTER_PASSWORDS','Users')));
}
// removed validateUserAuthtokenKey, there is already the CSRFT check in rpwd.php
$current_user = CRMEntity::getInstance('Users');
$current_user->id = $current_user->retrieve_user_id($username);
$current_user->retrieve_entity_info($current_user->id,'Users');
$current_user->id = $user_id;
$current_user->retrieve_entity_info($current_user->id, 'Users');
//crmv@28327
if (!$current_user->checkPasswordCriteria($newpwd,$current_user->column_fields)) {
@ -386,7 +473,7 @@ class RecoverPwd {
emptyUserAuthtokenKey($this->user_auth_token_type,$current_user->id);
//crmv@35153e
} else {
$current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true);
$current_user->change_password('oldpwd', $confirmpwd, true, true);
emptyUserAuthtokenKey($this->user_auth_token_type,$current_user->id);
$description = '
@ -400,7 +487,9 @@ class RecoverPwd {
return $description;
}
// crmv@341733e
// crmv@341733: do not trim passwords
public function displayChangeOldPwd($smarty, $key) {
global $site_URL, $current_user;
global $adb, $table_prefix;
@ -464,19 +553,19 @@ class RecoverPwd {
</form>
<script type="text/javascript">
function set_password(form) {
if (trim(form.old_password.value) == "") {
if (form.old_password.value == "") {
alert("'.getTranslatedString('ERR_ENTER_OLD_PASSWORD','Users').'");
return false;
}
if (trim(form.new_password.value) == "") {
if (form.new_password.value == "") {
alert("'.getTranslatedString('ERR_ENTER_NEW_PASSWORD','Users').'");
return false;
}
if (trim(form.confirm_new_password.value) == "") {
if (form.confirm_new_password.value == "") {
alert("'.getTranslatedString('ERR_ENTER_CONFIRMATION_PASSWORD','Users').'");
return false;
}
if (trim(form.new_password.value) == trim(form.confirm_new_password.value)) {
if (form.new_password.value === form.confirm_new_password.value) {
form.submit();
return true;
} else {
@ -488,6 +577,7 @@ class RecoverPwd {
return $description;
}
// crmv@341733e
public function displayChangeOldPwdSend($smarty, $key, $oldPassword, $newPassword) {
global $site_URL, $current_user;

View File

@ -3,216 +3,199 @@
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
// crmv@341228: rewrite and format, move checks to Users::save()
require_once('modules/Users/Users.php');
$log =& LoggerManager::getLogger('index');
require_once('include/logging.php');
require_once('include/utils/UserInfoUtil.php');
global $adb, $table_prefix, $current_user;
global $adb;
global $table_prefix;
$user_name = $_REQUEST['userName'];
if(isset($_REQUEST['status']) && $_REQUEST['status'] != '')
$_REQUEST['status']=$_REQUEST['status'];
else
$_REQUEST['status']='Active';
if(isset($_REQUEST['dup_check']) && $_REQUEST['dup_check'] != '')
{
$user_query = "SELECT user_name FROM ".$table_prefix."_users WHERE user_name =?";
$user_result = $adb->pquery($user_query, array($user_name));
$group_query = "SELECT groupname FROM ".$table_prefix."_groups WHERE groupname =?";
$group_result = $adb->pquery($group_query, array($user_name));
if($adb->num_rows($user_result) > 0) {
echo $mod_strings['LBL_USERNAME_EXIST'];
die;
} elseif($adb->num_rows($group_result) > 0) {
echo $mod_strings['LBL_GROUPNAME_EXIST'];
die;
} else {
echo 'SUCCESS';
die;
}
}
if (isset($_POST['record']) && !is_admin($current_user) && $_POST['record'] != $current_user->id) echo ("Unauthorized access to user administration.");
elseif (!isset($_POST['record']) && !is_admin($current_user)) echo ("Unauthorized access to user administration.");
$log = &LoggerManager::getLogger('index');
$is_admin = is_admin($current_user);
$focus = CRMEntity::getInstance('Users');
if(isset($_REQUEST["record"]) && $_REQUEST["record"] != '')
{
$focus->mode='edit';
$focus->id = $_REQUEST["record"];
}
else
{
$focus->mode='';
$focus->mode = '';
if (($_REQUEST["record"] ?? '') !== '') {
$focus->mode = 'edit';
$focus->id = RequestHandler::paramInt("record");
}
if($_REQUEST['deleteImage'] == 'true') {
$focus->id = $_REQUEST['recordid'];
$focus->deleteImage();
echo "SUCCESS";
exit;
if (empty($_REQUEST['status'])) {
$_REQUEST['status'] = 'Active';
}
if($_REQUEST['changepassword'] == 'true'){
$focus->retrieve_entity_info($_REQUEST['record'],'Users');
$focus->id = $_REQUEST['record'];
if (isset($_REQUEST['new_password'])) {
$new_pass = $_POST['new_password'];
$new_passwd = $_POST['new_password'];
$new_pass = md5($new_pass);
$old_pass = $_POST['old_password'];
$uname = $_POST['user_name'];
if (!$focus->change_password($_REQUEST['old_password'], $_REQUEST['new_password'])) {
header("Location: index.php?action=Error&module=Users&error_string=".urlencode($focus->error_string));
exit;
}
$mode = null;
foreach (['dup_check', 'deleteImage', 'changepassword'] as $k) {
if (($_REQUEST[$k] ?? '') !== '') {
$mode = $k;
break;
}
}
//save user Image
if(!$_REQUEST['changepassword'] == 'true'){
if(strtolower($current_user->is_admin) == 'off' && $current_user->id != $focus->id){
$log->fatal("SECURITY:Non-Admin ". $current_user->id . " attempted to change settings for user:". $focus->id);
header("Location: index.php?module=Users&action=Logout");
exit;
}
if(strtolower($current_user->is_admin) == 'off' && isset($_POST['is_admin']) && strtolower($_POST['is_admin']) == 'on'){
$log->fatal("SECURITY:Non-Admin ". $current_user->id . " attempted to change is_admin settings for user:". $focus->id);
header("Location: index.php?module=Users&action=Logout");
exit;
}
if (!isset($_POST['is_admin'])) $_REQUEST["is_admin"] = 'off';
//Code contributed by mike crowe for rearrange the home page and tab
if (!isset($_POST['deleted'])) $_REQUEST["deleted"] = '0';
if (!isset($_POST['homeorder']) || $_POST['homeorder'] == "" ) $_REQUEST["homeorder"] = 'ILTI,QLTQ,ALVT,PLVT,CVLVT,HLT,OLV,GRT,OLTSO';
if(isset($_REQUEST['internal_mailer']) && $_REQUEST['internal_mailer'] == 'on')
$focus->column_fields['internal_mailer'] = 1;
else
$focus->column_fields['internal_mailer'] = 0;
if(VteSession::hasKey('internal_mailer') && VteSession::get('internal_mailer') != $focus->column_fields['internal_mailer'])
VteSession::set('internal_mailer', $focus->column_fields['internal_mailer']);
setObjectValuesFromRequest($focus);
// crmv@42024 - translate separators
$focus->column_fields['decimal_separator'] = $focus->convertToSeparatorValue($focus->column_fields['decimal_separator']);
$focus->column_fields['thousands_separator'] = $focus->convertToSeparatorValue($focus->column_fields['thousands_separator']);
// crmv@42024e
if(empty($focus->column_fields['roleid']) && !empty($_POST['user_role'])) {
$focus->column_fields['roleid'] = $_POST['user_role'];
}
$focus->save("Users"); //crmv@22622
$return_id = $focus->id;
//crmv@17001
if($_REQUEST['mode'] == 'create') {
$sql = "update ".$table_prefix."_users set hour_format=? where id=?";
$adb->pquery($sql, array('24', $focus->id));
}
//crmv@17001e
if (isset($_POST['user_name']) && isset($_POST['new_password'])) {
$new_pass = $_POST['new_password'];
$new_passwd = $_POST['new_password'];
$new_pass = md5($new_pass);
$uname = $_POST['user_name'];
if (!$focus->change_password($_POST['confirm_new_password'], $_POST['new_password'])) {
header("Location: index.php?action=Error&module=Users&error_string=".urlencode($focus->error_string));
exit;
}
}
if(isset($focus->id) && $focus->id != ''){
if(isset($_POST['group_name']) && $_POST['group_name'] != ''){
updateUsers2GroupMapping($_POST['group_name'],$focus->id);
switch ($mode) {
case 'dup_check':
if (!$is_admin) {
echo 'Unauthorized';
exit;
}
}
$user_name = $_REQUEST['userName'] ?? '';
$user_query = "SELECT user_name FROM " . $table_prefix . "_users WHERE user_name =?";
$user_result = $adb->pquery($user_query, [$user_name]);
$group_query = "SELECT groupname FROM " . $table_prefix . "_groups WHERE groupname =?";
$group_result = $adb->pquery($group_query, [$user_name]);
if ($adb->num_rows($user_result) > 0) {
echo $mod_strings['LBL_USERNAME_EXIST'];
} elseif ($adb->num_rows($group_result) > 0) {
echo $mod_strings['LBL_GROUPNAME_EXIST'];
} else {
echo 'SUCCESS';
}
exit;
case 'deleteImage':
if (!$focus->filterOrDenySave()) {
echo 'Unauthorized';
exit;
}
$focus->id = $_REQUEST['recordid'];
$focus->deleteImage();
echo "SUCCESS";
exit;
case 'changepassword':
if (!$focus->filterOrDenySave()) {
echo 'Unauthorized';
exit;
}
$focus->retrieve_entity_info($_REQUEST['record'], 'Users');
$focus->id = $_REQUEST['record'];
if (!isset($_POST['new_password'])) {
exit;
}
$new_passwd = $_POST['new_password'];
if (!$focus->change_password('', $new_passwd, true, true)) {
RequestHandler::outputRedirect("index.php?action=Error&module=Users&error_string=" . urlencode($focus->error_string)); // crmv@150748
exit;
}
break;
default:
// normal save
$_REQUEST["is_admin"] = $_POST['is_admin'] ?? 'off';
$_REQUEST["deleted"] = $_POST['deleted'] ?? '0';
$_REQUEST["homeorder"] = $_POST['homeorder'] ?? ''; // crmv@283757
$_REQUEST["roleid"] = ($_POST['roleid'] ?? null) ?: ($_POST['user_role'] ?? null) ?: '';
$focus->column_fields['internal_mailer'] = intval(($_REQUEST['internal_mailer'] ?? '') === 'on');
if (VteSession::hasKey('internal_mailer') && VteSession::get('internal_mailer') != $focus->column_fields['internal_mailer'])
VteSession::set('internal_mailer', $focus->column_fields['internal_mailer']);
setObjectValuesFromRequest($focus);
// crmv@42024 - translate separators
$focus->column_fields['decimal_separator'] = $focus->convertToSeparatorValue($focus->column_fields['decimal_separator']);
$focus->column_fields['thousands_separator'] = $focus->convertToSeparatorValue($focus->column_fields['thousands_separator']);
// crmv@42024e
if (!$focus->filterOrDenySave()) {
RequestHandler::outputRedirect("index.php?module=Users&action=Logout"); // crmv@150748
exit;
}
$focus->save("Users"); //crmv@22622
$return_id = $focus->id;
//crmv@17001
if($_REQUEST['mode'] == 'create') {
$sql = "update ".$table_prefix."_users set hour_format=? where id=?";
$adb->pquery($sql, array('24', $focus->id));
}
//crmv@17001e
if (($focus->id ?? '') != '' && ($_POST['group_name'] ?? '') != '') {
updateUsers2GroupMapping($_POST['group_name'], $focus->id);
}
// crmv@187823
if ($_REQUEST['mode'] == 'create') {
$focus->initCalendarSharing();
} else {
$shareduser_ids = array_filter(explode(";", $_REQUEST['shar_userid']));
$shareduserocc_ids = array_filter(explode(";", $_REQUEST['sharocc_userid']));
$shownduser_ids = array_filter(explode(";", $_REQUEST['shown_userid']));
$focus->updateCalendarSharing($shareduser_ids, $shareduserocc_ids, $shownduser_ids);
}
// crmv@187823e
break;
}
//crmv@20209
if(!$_REQUEST['changepassword'] == 'true') {
// crmv@187823
if ($_REQUEST['mode'] == 'create') {
$focus->initCalendarSharing();
} else {
$shareduser_ids = array_filter(explode(";", $_REQUEST['shar_userid']));
$shareduserocc_ids = array_filter(explode(";", $_REQUEST['sharocc_userid']));
$shownduser_ids = array_filter(explode(";", $_REQUEST['shown_userid']));
$focus->updateCalendarSharing($shareduser_ids, $shareduserocc_ids, $shownduser_ids);
}
// crmv@187823e
}
//crmv@20209e
$return_module = "Users";
$return_action = "DetailView";
if(isset($_POST['return_module']) && $_POST['return_module'] != "") $return_module = vtlib_purify($_REQUEST['return_module']);
else $return_module = "Users";
if(isset($_POST['return_action']) && $_POST['return_action'] != "") $return_action = vtlib_purify($_REQUEST['return_action']);
else $return_action = "DetailView";
if(isset($_POST['return_id']) && $_POST['return_id'] != "") $return_id = vtlib_purify($_REQUEST['return_id']);
if(isset($_REQUEST['activity_mode'])) $activitymode = '&activity_mode='.vtlib_purify($_REQUEST['activity_mode']);
if(isset($_POST['parenttab'])) $parenttab = getParentTab();
if (($_POST['return_module'] ?? '') != "") $return_module = vtlib_purify($_REQUEST['return_module']);
if (($_POST['return_action'] ?? '') != "") $return_action = vtlib_purify($_REQUEST['return_action']);
if (($_POST['return_id'] ?? '') != "") $return_id = vtlib_purify($_REQUEST['return_id']);
$log->debug("Saved record with id of ".$return_id);
if (isset($_REQUEST['activity_mode'])) $activitymode = '&activity_mode=' . vtlib_purify($_REQUEST['activity_mode']);
if (isset($_POST['parenttab'])) $parenttab = getParentTab();
//Asha: Added Check to see if the mode is User Creation and if yes, then sending the email notification to the User with Login details.
if($_REQUEST['mode'] == 'create') {
$log->debug("Saved record with id of " . $return_id);
if ($_REQUEST['mode'] == 'create') {
global $app_strings, $mod_strings, $default_charset;
require_once('modules/Emails/mail.php');
$user_emailid = $focus->column_fields['email1'];
require_once('modules/Emails/mail.php');
$user_emailid = $focus->column_fields['email1'];
$subject = $mod_strings['User Login Details'];
$email_body = $app_strings['MSG_DEAR']." ". $focus->column_fields['last_name'] .",<br><br>";
$email_body .= $app_strings['LBL_PLEASE_CLICK'] . " <a href='" . $site_URL . "' target='_blank'>"
. $app_strings['LBL_HERE'] . "</a> " . $mod_strings['LBL_TO_LOGIN'] . "<br><br>";
$email_body .= $mod_strings['LBL_USER_NAME'] . " : " . $focus->column_fields['user_name'] . "<br>";
//crmv@36525
if (!($focus->column_fields['use_ldap'] == '1' || $focus->column_fields['use_ldap'] == 'on')){
$subject = $mod_strings['User Login Details'];
$email_body = $app_strings['MSG_DEAR']." ". $focus->column_fields['last_name'] .",<br><br>";
$email_body .= $app_strings['LBL_PLEASE_CLICK'] . " <a href='" . $site_URL . "' target='_blank'>"
. $app_strings['LBL_HERE'] . "</a> " . $mod_strings['LBL_TO_LOGIN'] . "<br><br>";
$email_body .= $mod_strings['LBL_USER_NAME'] . " : " . $focus->column_fields['user_name'] . "<br>";
//crmv@36525
if (!($focus->column_fields['use_ldap'] == '1' || $focus->column_fields['use_ldap'] == 'on')) {
$email_body .= $mod_strings['LBL_PASSWORD'] . " : " . $focus->column_fields['user_password'] . "<br>";
}
//crmv@36525 e
$email_body .= $mod_strings['LBL_ROLE_NAME'] . " : " . getRoleName($_POST['user_role']) . "<br>";
$email_body .= "<br>" . $app_strings['MSG_THANKS'] . "<br>" . $current_user->user_name;
}
//crmv@36525e
$email_body .= $mod_strings['LBL_ROLE_NAME'] . " : " . getRoleName($_POST['user_role']) . "<br>";
$email_body .= "<br>" . $app_strings['MSG_THANKS'] . "<br>" . $current_user->user_name;
$mail_status = send_mail('Users',$user_emailid,$HELPDESK_SUPPORT_NAME,$HELPDESK_SUPPORT_EMAIL_ID,$subject,$email_body);
$mail_status = send_mail('Users', $user_emailid, $HELPDESK_SUPPORT_NAME, $HELPDESK_SUPPORT_EMAIL_ID, $subject, $email_body);
if($mail_status != 1) {
$mail_status_str = $user_emailid."=".$mail_status."&&&";
if ($mail_status != 1) {
$mail_status_str = $user_emailid . "=" . $mail_status . "&&&";
$error_str = getMailErrorString($mail_status_str);
}
//crmv@25466
/*
$iframes = SDK::getHomeIframes();
if (!empty($iframes)) {
foreach ($iframes as $ifr) {
SDK::setHomeIframe($ifr['size'], $ifr['url'], $ifr['stufftitle'], $return_id, $ifr['iframe']);
}
}
*/
//crmv@25466e
$focus->saveLastChangePassword($focus->id); //crmv@28327
}
//crmv@29617
if(isset($_REQUEST['notification_module_settings']) && $_REQUEST['notification_module_settings'] == 'yes') {
if (($_REQUEST['notification_module_settings'] ?? '') === 'yes') {
$ModNotificationsFocus = ModNotifications::getInstance(); // crmv@164122
$ModNotificationsFocus->saveModuleSettings($focus->id,$_REQUEST);
$ModNotificationsFocus->saveModuleSettings($focus->id, $_REQUEST);
}
//crmv@29617e
if ($return_module == 'Calendar' && $return_action == 'index')
$location = "Location: index.php?action=".vtlib_purify($return_action)."&module=".vtlib_purify($return_module);
else
$location = "Location: index.php?action=".vtlib_purify($return_action)."&module=".vtlib_purify($return_module)."&record=".vtlib_purify($return_id);
if($_REQUEST['modechk'] != 'prefview') {
$location .= "&parenttab=".vtlib_purify($parenttab);
//crmv@230349
if ($return_module == 'Calendar' && $return_action == 'index')
$location = "index.php?action=" . vtlib_purify($return_action) . "&module=" . vtlib_purify($return_module);
else
$location = "index.php?action=" . vtlib_purify($return_action) . "&module=" . vtlib_purify($return_module) . "&record=" . vtlib_purify($return_id);
//crmv@230349e
if ($_REQUEST['modechk'] != 'prefview') {
$location .= "&parenttab=" . vtlib_purify($parenttab);
}
if ($error_str != '') {
$user = $focus->column_fields['user_name'];
$user = $focus->column_fields['user_name'];
$location .= "&user=$user&$error_str";
}
header($location);
RequestHandler::outputRedirect($location); // crmv@150748
?>
// crmv@341228e

View File

@ -1684,6 +1684,45 @@ class Users extends CRMEntity { //crmv@392267
// crmv@74560e
// crmv@341228
public function filterOrDenySave(): bool {
global $log, $current_user;
if (php_sapi_name() === 'cli' || ($current_user && is_admin($current_user))) {
return true;
}
if ($this->mode != 'edit') {
$log->fatal("SECURITY: Non-Admin {$current_user->id} attempted to create a new user {$this->id}.");
return false;
}
if (!$current_user || $current_user->id != $this->id) {
$ulabel = $current_user ? "Non-Admin {$current_user->id}" : "Unset user";
$log->fatal("SECURITY: {$ulabel} attempted to change some settings for user {$this->id}.");
return false;
}
$old = CRMEntity::getInstance('Users');
$old->id = $this->id;
$old->mode = 'edit';
$old->retrieve_entity_info_no_html($this->id, 'Users');
// require_once 'data/VTEntityDelta.php';
// $delta = new VTEntityDelta();
// $delta->setOldEntity('Users', $this->id, VTEntityData::fromCRMEntity($old));
// $delta->setNewEntity('Users', $this->id, VTEntityData::fromCRMEntity($this));
// $delta->computeDelta('Users', $this->id);
// $delta = $delta->getEntityDelta('Users', $this->id);
// deny self changes and from upper roles
static $denied_fields = ['is_admin', 'roleid', 'user_name', 'email1', 'status', 'currency_id'];
foreach ($denied_fields as $fname) {
$this->column_fields[$fname] = $old->column_fields[$fname];
}
return true;
}
// crmv@341228e
/** Function to save the user information into the database
* @param $module -- module name:: Type varchar

View File

@ -3,16 +3,46 @@
* SPDX-FileCopyrightText: 2009-2020 Vtenext S.r.l. <info@vtenext.com>
* SPDX-License-Identifier: AGPL-3.0-only
************************************/
/* crmv@170283 */
header("Access-Control-Allow-Headers: content-type, accept, authorization");
header("Access-Control-Allow-Methods: POST"); // GET, OPTIONS
header("Access-Control-Allow-Origin: *");
/* crmv@170283 crmv@255566 crmv@203130 */
require('../../config.inc.php');
chdir($root_directory);
// crmv@246249
require_once('include/MaintenanceMode.php');
if (MaintenanceMode::check()) {
MaintenanceMode::displayRestApi();
exit();
}
// crmv@246249e
require_once('include/utils/utils.php');
SDK::getUtils();
$allowHeaders = ['Authorization', 'Content-Type']; // crmv@341216
$VP = VTEProperties::getInstance();
if ($VP->get('performance.app_debug')) {
$allowHeaders = array_merge($allowHeaders, [
'Touch-Session-Id', 'Touch-Check-Time',
'Touch-Version-Id', 'X-App-Package',
'X-App-Version', 'X-Otp',
]);
}
header("Access-Control-Allow-Headers: " . implode(', ', $allowHeaders));
header("Access-Control-Allow-Credentials: true"); // crmv@341216
header("Access-Control-Allow-Methods: POST, OPTIONS"); // GET
header("Access-Control-Allow-Origin: *");
// crmv@341219
header("X-Frame-Options: DENY"); // REST API are not frame-able by default
header("X-Content-Type-Options: nosniff");
header("Content-Security-Policy: frame-ancestors 'none'");
// crmv@341219e
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') die();
$contentType = '';
if (function_exists('getallheaders')) {
$http_headers = getallheaders();
@ -77,13 +107,46 @@ use RestService\Server;
require_once('include/RestApi/v1/VTERestApi.php');
$restApi = VTERestApi::getInstance();
$server = Server::create('/vtews', $restApi);
// $server->setDebugMode(true); // prints the debug trace, line number and file if a exception has been thrown.
$methods = $restApi->getMethods();
if (!empty($methods)) {
foreach($methods as $row) {
$server->addPostRoute($row['rest_name'],$row['rest_name']);
// crmv@341217
global $adb, $root_directory;
/** @var PearDatabase $adb */
// must be always set to false, otherwise sensitive stack traces with vte path will be returned
$adb->setDieOnError(false);
// must be always set to false, otherwise uncaught errors will generate sensitive messages with the sql query and database info
$adb->setExceptOnError(false);
// this will also catch fatal errors and parse errors, also avoiding xdebug pages
try {
$server = Server::create('/vtews', $restApi);
// $server->setDebugMode(true); // prints the debug trace, line number and file if a exception has been thrown.
$methods = $restApi->getMethods();
if (!empty($methods)) {
foreach($methods as $row) {
$server->addPostRoute($row['rest_name'],$row['rest_name']);
}
}
$server->run();
} catch (\Error $e) {
$strip = function($x) use (&$root_directory) { return str_replace($root_directory, '', $x); };
$err = [
'success' => false,
'error' => $e->getCode(),
'message' => $e->getMessage(),
'file' => $strip($e->getFile()),
// 'trace' => array_map($strip, $e->getTrace()),
];
if (!$server) {
header("Content-Type: application/json; charset=UTF-8", true, 500);
echo Zend_Json::encode($err);
return;
}
$server->getClient()->sendResponse('500', $err);
}
$server->run();
// crmv@341217e

Some files were not shown because too many files have changed in this diff Show More