From aa2bfa5ddba112c2af6e758f8ec9a2d4312e13f0 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Sun, 3 Jan 2021 18:41:25 +0100 Subject: [PATCH 01/15] =?UTF-8?q?Am=C3=A9lioration=20journalisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/module/user/user.php | 222 ++++++++++++++++++-------------------- 1 file changed, 107 insertions(+), 115 deletions(-) diff --git a/core/module/user/user.php b/core/module/user/user.php index 5d465942..930fdfc4 100755 --- a/core/module/user/user.php +++ b/core/module/user/user.php @@ -333,6 +333,7 @@ class user extends common { */ public function login() { // Soumission du formulaire + $logStatus = ''; if($this->isPost()) { // Lire Id du compte $userId = $this->getInput('userLoginId', helper::FILTER_ID, true); @@ -341,137 +342,128 @@ class user extends common { $this->getData(['config','connect','captcha']) AND password_verify($this->getInput('userLoginCaptcha', helper::FILTER_INT), $this->getInput('userLoginCaptchaResult') ) === false ) { - //self::$inputNotices['userLoginCaptcha'] = 'Incorrect'; - $notification = 'Captcha incorrect !'; - // Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec - if ($this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) { - $this->setData(['user',$userId,'connectFail',$this->getdata(['user',$userId,'connectFail']) + 1 ]); - } - // Cas 2 la limite du nombre de connexion est atteinte : placer le timer - if ( $this->getdata(['user',$userId,'connectFail']) == $this->getData(['config', 'connect', 'attempt']) ) { - $this->setData(['user',$userId,'connectTimeout', time()]); - } - // Cas 3 le délai de bloquage court - if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time() ) { - $notification = 'Accès bloqué ' . ($this->getData(['config', 'connect', 'timeout']) / 60) . ' minutes.'; - } - // Valeurs en sortie - $this->addOutput([ - 'notification' => $notification - ]); + $captcha = false; } else { - /** - * Aucun compte existant - */ - if ( !$this->getData(['user', $userId])) { - //Stockage de l'IP - $this->setData([ - 'blacklist', - $userId, - [ - 'connectFail' => $this->getData(['blacklist',$userId,'connectFail']) + 1, - 'lastFail' => time(), - 'ip' => helper::getIp() - ] + $captcha = true; + } + /** + * Aucun compte existant + */ + if ( !$this->getData(['user', $userId])) { + $logStatus = 'Compte inconnu'; + //Stockage de l'IP + $this->setData([ + 'blacklist', + $userId, + [ + 'connectFail' => $this->getData(['blacklist',$userId,'connectFail']) + 1, + 'lastFail' => time(), + 'ip' => helper::getIp() + ] + ]); + // Verrouillage des IP + $ipBlackList = helper::arrayCollumn($this->getData(['blacklist']), 'ip'); + if ( $this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt']) + AND in_array($this->getData(['blacklist',$userId,'ip']),$ipBlackList) ) { + $logStatus = 'Compte inconnu verrouillé'; + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Compte verrouillé', + 'redirect' => helper::baseUrl(), + 'state' => false ]); - // Verrouillage des IP - $ipBlackList = helper::arrayCollumn($this->getData(['blacklist']), 'ip'); - if ( $this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt']) - AND in_array($this->getData(['blacklist',$userId,'ip']),$ipBlackList) ) { - // Valeurs en sortie + } else { + // Valeurs en sortie + $this->addOutput([ + 'notification' => 'Captcha, identifiant ou mot de passe incorrects' + ]); + } + /** + * Le compte existe + */ + } else { + // Cas 4 : le délai de blocage est dépassé et le compte est au max - Réinitialiser + if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time() + AND $this->getData(['user',$userId,'connectFail']) === $this->getData(['config', 'connect', 'attempt']) ) { + $this->setData(['user',$userId,'connectFail',0 ]); + $this->setData(['user',$userId,'connectTimeout',0 ]); + } + // Check la présence des variables et contrôle du blocage du compte si valeurs dépassées + // Vérification du mot de passe et du groupe + if ( + ( $this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) ) < time() + AND $this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt']) + AND password_verify($this->getInput('userLoginPassword', helper::FILTER_STRING_SHORT, true), $this->getData(['user', $userId, 'password'])) + AND $this->getData(['user', $userId, 'group']) >= self::GROUP_MEMBER + AND $captcha === true + ) { + // RAZ + $this->setData(['user',$userId,'connectFail',0 ]); + $this->setData(['user',$userId,'connectTimeout',0 ]); + // Expiration + $expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0; + $c = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? 'true' : 'false'; + setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false) , '', helper::isHttps(), true); + setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true); + setcookie('ZWII_USER_LONGTIME', $c, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true); + // Accès multiples avec le même compte + $this->setData(['user',$userId,'accessCsrf',$_SESSION['csrf']]); + // Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur + if( + $this->getData(['config', 'maintenance']) + AND $this->getData(['user', $userId, 'group']) < self::GROUP_ADMIN + ) { $this->addOutput([ - 'notification' => 'Compte verrouillé', + 'notification' => 'Seul un administrateur peut se connecter lors d\'une maintenance', 'redirect' => helper::baseUrl(), 'state' => false ]); } else { + $logStatus = 'Connexion réussie'; // Valeurs en sortie $this->addOutput([ - 'notification' => 'Identifiant ou mot de passe incorrects' + 'notification' => 'Bienvenue ' . $this->getData(['user',$userId,'firstname']) . ' ' . $this->getData(['user',$userId,'lastname']) , + 'redirect' => helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2))), + 'state' => true ]); } - /** - * Le compte existe - */ - } else { - // Cas 4 : le délai de blocage est dépassé et le compte est au max - Réinitialiser - if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time() - AND $this->getData(['user',$userId,'connectFail']) === $this->getData(['config', 'connect', 'attempt']) ) { - $this->setData(['user',$userId,'connectFail',0 ]); - $this->setData(['user',$userId,'connectTimeout',0 ]); + // Sinon notification d'échec + } else { + $notification = 'Captcha, identifiant ou mot de passe incorrects'; + $logStatus = $captcha === true ? 'Erreur de mot de passe' : 'Erreur de captcha'; + // Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec + if ($this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) { + $this->setData(['user',$userId,'connectFail',$this->getdata(['user',$userId,'connectFail']) + 1 ]); } - // Check la présence des variables et contrôle du blocage du compte si valeurs dépassées - // Vérification du mot de passe et du groupe - if ( - ( $this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) ) < time() - AND $this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt']) - AND password_verify($this->getInput('userLoginPassword', helper::FILTER_STRING_SHORT, true), $this->getData(['user', $userId, 'password'])) - AND $this->getData(['user', $userId, 'group']) >= self::GROUP_MEMBER - ) { - // RAZ - $this->setData(['user',$userId,'connectFail',0 ]); - $this->setData(['user',$userId,'connectTimeout',0 ]); - // Expiration - $expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0; - $c = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? 'true' : 'false'; - setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false) , '', helper::isHttps(), true); - setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true); - setcookie('ZWII_USER_LONGTIME', $c, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true); - // Accès multiples avec le même compte - $this->setData(['user',$userId,'accessCsrf',$_SESSION['csrf']]); - // Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur - if( - $this->getData(['config', 'maintenance']) - AND $this->getData(['user', $userId, 'group']) < self::GROUP_ADMIN - ) { - $this->addOutput([ - 'notification' => 'Seul un administrateur peut se connecter lors d\'une maintenance', - 'redirect' => helper::baseUrl(), - 'state' => false - ]); - } else { - // Valeurs en sortie - $this->addOutput([ - 'notification' => 'Bienvenue ' . $this->getData(['user',$userId,'firstname']) . ' ' . $this->getData(['user',$userId,'lastname']) , - 'redirect' => helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2))), - 'state' => true - ]); - } - // Sinon notification d'échec - } else { - $notification = 'Identifiant ou mot de passe incorrects'; - // Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec - if ($this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) { - $this->setData(['user',$userId,'connectFail',$this->getdata(['user',$userId,'connectFail']) + 1 ]); - } - // Cas 2 la limite du nombre de connexion est atteinte : placer le timer - if ( $this->getdata(['user',$userId,'connectFail']) == $this->getData(['config', 'connect', 'attempt']) ) { - $this->setData(['user',$userId,'connectTimeout', time()]); - } - // Cas 3 le délai de bloquage court - if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time() ) { - $notification = 'Accès bloqué ' . ($this->getData(['config', 'connect', 'timeout']) / 60) . ' minutes.'; - } - // Journalisation - $dataLog = mb_detect_encoding(strftime('%d/%m/%y',time()), 'UTF-8', true) - ? strftime('%d/%m/%y',time()) . ';' . strftime('%R',time()) . ';' - : utf8_encode(strftime('%d/%m/%y',time())) . ';' . utf8_encode(strftime('%R',time())) . ';' ; - $dataLog .= helper::getIp() . ';'; - $dataLog .= $userId . ';' ; - $dataLog .= $this->getUrl() .';' ; - $dataLog .= 'échec de connexion' ; - $dataLog .= PHP_EOL; - if ($this->getData(['config','connect','log'])) { - file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND); - } - // Valeurs en sortie - $this->addOutput([ - 'notification' => $notification - ]); + // Cas 2 la limite du nombre de connexion est atteinte : placer le timer + if ( $this->getdata(['user',$userId,'connectFail']) == $this->getData(['config', 'connect', 'attempt']) ) { + $this->setData(['user',$userId,'connectTimeout', time()]); } + // Cas 3 le délai de bloquage court + if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time() ) { + $notification = 'Accès bloqué ' . ($this->getData(['config', 'connect', 'timeout']) / 60) . ' minutes.'; + } + + // Valeurs en sortie + $this->addOutput([ + 'notification' => $notification + ]); } } } + // Journalisation + $dataLog = mb_detect_encoding(strftime('%d/%m/%y',time()), 'UTF-8', true) + ? strftime('%d/%m/%y',time()) . ';' . strftime('%R',time()) . ';' + : utf8_encode(strftime('%d/%m/%y',time())) . ';' . utf8_encode(strftime('%R',time())) . ';' ; + $dataLog .= helper::getIp() . ';'; + $dataLog .= $this->getInput('userLoginId', helper::FILTER_ID, true) . ';' ; + $dataLog .= $this->getUrl() .';' ; + $dataLog .= $logStatus ; + $dataLog .= PHP_EOL; + if ($this->getData(['config','connect','log'])) { + file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND); + } + // Stockage des cookies if (!empty($_COOKIE['ZWII_USER_ID'])) { self::$userId = $_COOKIE['ZWII_USER_ID']; } From 18bfadec1fecdd5e5c7545b1e646364bb1cf67ae Mon Sep 17 00:00:00 2001 From: fredtempez Date: Sun, 3 Jan 2021 18:52:36 +0100 Subject: [PATCH 02/15] =?UTF-8?q?Pr=C3=A9fixe=20=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 4 +++- core/class/helper.class.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1cc36c74..bce9fdfd 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,8 +6,10 @@ Modifications : - Verrouillage des fichiers de données ouverts en écriture. - Message d'erreur littéral. - Sauvegarde des fichiers de données après un effacement et une écriture. + - Identifiant des noms de ressources (id de page , d'utilisateur, etc..) composés de nombres , remplacement du caractère de préfixe "i" par "_". - Google Analytics, option d'anonymisation. - - Procédure de connexion : les erreurs de captcha sont comptabilisées comme des échecs, allégement des messages d'information. + - Procédure de connexion : les erreurs de captcha sont comptabilisées comme des échecs, allégement des messages d'information. Echecs de connexion, informations plus précises dans le journal de connexion. + - TinyMCE : ajout des scripts possibles. Correction : - Notification de commentaire, remplacement du nom de la page par le titre de l'article. diff --git a/core/class/helper.class.php b/core/class/helper.class.php index 58613dc0..396208ec 100755 --- a/core/class/helper.class.php +++ b/core/class/helper.class.php @@ -273,7 +273,7 @@ class helper { } // Un ID ne peut pas être un entier, pour éviter les conflits avec le système de pagination if(intval($text) !== 0) { - $text = 'i' . $text; + $text = '_' . $text; } break; case self::FILTER_INT: From b9864fbfb841b061fefcf9960b9ea172ebf6e190 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Mon, 4 Jan 2021 17:33:38 +0100 Subject: [PATCH 03/15] =?UTF-8?q?login=20message=20erron=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/module/user/user.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/module/user/user.php b/core/module/user/user.php index 930fdfc4..00ce6831 100755 --- a/core/module/user/user.php +++ b/core/module/user/user.php @@ -456,7 +456,7 @@ class user extends common { ? strftime('%d/%m/%y',time()) . ';' . strftime('%R',time()) . ';' : utf8_encode(strftime('%d/%m/%y',time())) . ';' . utf8_encode(strftime('%R',time())) . ';' ; $dataLog .= helper::getIp() . ';'; - $dataLog .= $this->getInput('userLoginId', helper::FILTER_ID, true) . ';' ; + $dataLog .= $this->getInput('userLoginId', helper::FILTER_ID) . ';' ; $dataLog .= $this->getUrl() .';' ; $dataLog .= $logStatus ; $dataLog .= PHP_EOL; From bb782a7e8ff2dbc2c22f6c2d68a83ce8316d0f23 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Mon, 4 Jan 2021 17:54:47 +0100 Subject: [PATCH 04/15] Nom des fichiers de backup + htaccess --- CHANGES.md | 1 - core/class/jsondb/JsonDb.class.php | 2 +- site/data/.htaccess | 13 ++----------- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index bce9fdfd..f7791f23 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,7 +9,6 @@ Modifications : - Identifiant des noms de ressources (id de page , d'utilisateur, etc..) composés de nombres , remplacement du caractère de préfixe "i" par "_". - Google Analytics, option d'anonymisation. - Procédure de connexion : les erreurs de captcha sont comptabilisées comme des échecs, allégement des messages d'information. Echecs de connexion, informations plus précises dans le journal de connexion. - - TinyMCE : ajout des scripts possibles. Correction : - Notification de commentaire, remplacement du nom de la page par le titre de l'article. diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 23b8e5ac..2cb9d394 100755 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -133,7 +133,7 @@ class JsonDb extends \Prowebcraft\Dot } // Backup file if ($this->config['backup']) { - copy ($this->db, $this->db . '.back'); + copy ($this->db, str_replace('json' , 'back.json', $this->db)); } if ( is_writable($this->db) ) { // 3 essais diff --git a/site/data/.htaccess b/site/data/.htaccess index 2d900f16..ff0d5418 100755 --- a/site/data/.htaccess +++ b/site/data/.htaccess @@ -1,14 +1,5 @@ # Bloque l'accès aux données - + Order deny,allow Deny from all - - - Order deny,allow - Deny from all - -# Bloque l'accès htaccess - - Order deny,allow - Deny from all - \ No newline at end of file + \ No newline at end of file From c8a313687f0cf8243fa54248c386d5b199d4cae2 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Wed, 6 Jan 2021 14:33:52 +0100 Subject: [PATCH 05/15] change --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f7791f23..f767337f 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +10,7 @@ Modifications : - Google Analytics, option d'anonymisation. - Procédure de connexion : les erreurs de captcha sont comptabilisées comme des échecs, allégement des messages d'information. Echecs de connexion, informations plus précises dans le journal de connexion. - TinyMCE : ajout des scripts possibles. -Correction : +Corrections : - Notification de commentaire, remplacement du nom de la page par le titre de l'article. - Thème : couleur du texte au survol d'un bouton standard. From 37278e626f4145ed0742a52c7dedbbb75af96924 Mon Sep 17 00:00:00 2001 From: Fred Tempez Date: Wed, 6 Jan 2021 14:39:08 +0100 Subject: [PATCH 06/15] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'README.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index a8d8d670..28aff49b 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -![](https://img.shields.io/github/last-commit/fredtempez/ZwiiCMS/master) ![](https://img.shields.io/github/release-date/fredtempez/ZwiiCMS) # ZwiiCMS 10.3.13 From 52f59c10612b5984b6def4bfd7d05c77037b6ad6 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Wed, 6 Jan 2021 18:40:10 +0100 Subject: [PATCH 07/15] =?UTF-8?q?$i18nCurrent=20non=20d=C3=A9clar=C3=A9e?= =?UTF-8?q?=20=3F!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/core.php | 1 + 1 file changed, 1 insertion(+) diff --git a/core/core.php b/core/core.php index 6075821e..09c988aa 100755 --- a/core/core.php +++ b/core/core.php @@ -154,6 +154,7 @@ class common { ]; // Langue courante public static $i18nSite; + public static $i18nCurrent; public static $timezone; private $url = ''; // Données de site From 7be1dff6aad094e7238c26d27ff64d71bb272884 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Wed, 6 Jan 2021 19:31:55 +0100 Subject: [PATCH 08/15] Option d'activation ou de suppression des fichiers back.json qui deviennent backup.json --- core/class/jsondb/JsonDb.class.php | 4 ++-- core/core.php | 20 +++++++++++++++---- core/module/config/config.php | 19 +++++++++++------- core/module/config/view/advanced/advanced.php | 6 ++++++ core/module/install/ressource/defaultdata.php | 1 + 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 2cb9d394..978a813a 100755 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -132,8 +132,8 @@ class JsonDb extends \Prowebcraft\Dot touch($this->db); } // Backup file - if ($this->config['backup']) { - copy ($this->db, str_replace('json' , 'back.json', $this->db)); + if ($this->config['backup'] === true) { + copy ($this->db, str_replace('json' , 'backup.json', $this->db)); } if ( is_writable($this->db) ) { // 3 essais diff --git a/core/core.php b/core/core.php index 22f1d855..2e5bc281 100755 --- a/core/core.php +++ b/core/core.php @@ -44,7 +44,7 @@ class common { const ACCESS_TIMER = 1800; // Numéro de version - const ZWII_VERSION = '10.4.00.011'; + const ZWII_VERSION = '10.4.00.012'; const ZWII_UPDATE_CHANNEL = "v10"; public static $actions = []; @@ -168,10 +168,10 @@ class common { // Descripteur de données Entrées / Sorties // Liste ici tous les fichiers de données private $dataFiles = [ + 'config' => '', 'page' => '', 'module' => '', 'core' => '', - 'config' => '', 'page' => '', 'user' => '', 'theme' => '', @@ -198,13 +198,13 @@ class common { } // Instanciation de la classe des entrées / sorties - // Récupére les descripteurs + // Récupère les descripteurs foreach ($this->dataFiles as $keys => $value) { // Constructeur JsonDB $this->dataFiles[$keys] = new \Prowebcraft\JsonDb([ 'name' => $keys . '.json', 'dir' => $this->dataPath ($keys,self::$i18nCurrent), - 'backup' => true + 'backup' => $keys === 'config' ? true : $this->getData(['config','fileBackup']) ]);; } @@ -1565,6 +1565,18 @@ class common { $this->setData(['locale','metaDescription',$this->getData(['config','metaDescription'])]); $this->setData(['locale','title',$this->getData(['config','title'])]); + // Renommer les fichier de backup + if ($this->getInput('configAdvancedFileBackup', helper::FILTER_BOOLEAN) === false) { + $path = realpath('site/data'); + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) + { + echo "$filename
"; + if (strpos($filename,'back.json')) { + rename($filename, str_replace('back.json','backup.json',$filename)); + } + } + } + $this->setData(['core', 'dataVersion', 10400]); /** diff --git a/core/module/config/config.php b/core/module/config/config.php index 6b1c80b4..355e9393 100755 --- a/core/module/config/config.php +++ b/core/module/config/config.php @@ -485,6 +485,7 @@ class config extends common { [ 'analyticsId' => $this->getInput('configAdvancedAnalyticsId'), 'autoBackup' => $this->getInput('configAdvancedAutoBackup', helper::FILTER_BOOLEAN), + 'fileBackup' => $this->getInput('configAdvancedFileBackup', helper::FILTER_BOOLEAN), 'maintenance' => $this->getInput('configAdvancedMaintenance', helper::FILTER_BOOLEAN), 'cookieConsent' => $this->getInput('configAdvancedCookieConsent', helper::FILTER_BOOLEAN), 'favicon' => $this->getInput('configAdvancedFavicon'), @@ -525,7 +526,17 @@ class config extends common { ] ] ]); - + // Efface les fichiers de backup lorsque l'option est désactivée + if ($this->getInput('configAdvancedFileBackup', helper::FILTER_BOOLEAN) === false) { + $path = realpath('site/data'); + foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) + { + if (strpos($filename,'backup.json')) { + unlink($filename); + } + } + } + // Notice if(self::$inputNotices === []) { // Active la réécriture d'URL $rewrite = $this->getInput('rewrite', helper::FILTER_BOOLEAN); @@ -572,12 +583,6 @@ class config extends common { 'state' => $success ]); } - // Initialisation du screen - APPEL AUTO DESACTIVE POUR EVITER UN RALENTISSEMENT - /* - if (!file_exists(self::FILE_DIR.'source/screenshot.jpg')) { - $this->configMetaImage(); - } - */ // Valeurs en sortie $this->addOutput([ 'title' => 'Configuration avancée', diff --git a/core/module/config/view/advanced/advanced.php b/core/module/config/view/advanced/advanced.php index c6843756..7bcd6a4a 100644 --- a/core/module/config/view/advanced/advanced.php +++ b/core/module/config/view/advanced/advanced.php @@ -101,6 +101,12 @@ 'help' => '

Une archive contenant le dossier /site/data est copiée dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.

Les fichiers du site ne sont pas sauvegardés automatiquement.

' ]); ?> +
+ $this->getData(['config', 'fileBackup']), + 'help' => '

Un fichier .backup.json est généré à chaque édition ou effacement d\'une donnée. La désactivation entraîne la suppression de ces fichiers.

' + ]); ?> +
diff --git a/core/module/install/ressource/defaultdata.php b/core/module/install/ressource/defaultdata.php index c6ef26dd..3527fa2a 100755 --- a/core/module/install/ressource/defaultdata.php +++ b/core/module/install/ressource/defaultdata.php @@ -4,6 +4,7 @@ class init extends common { 'config' => [ 'analyticsId' => '', 'autoBackup' => true, + 'fileBackup' => true, 'autoUpdate' => true, 'autoUpdateHtaccess' => false, 'cookieConsent' => true, From f8683cc9e6f384a945c4516612ae007c61c2facf Mon Sep 17 00:00:00 2001 From: fredtempez Date: Thu, 7 Jan 2021 09:48:53 +0100 Subject: [PATCH 09/15] .backup marqueur du backup --- README.md | 7 ++++--- core/core.php | 2 +- core/module/config/config.php | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e09fe264..71521879 100755 --- a/README.md +++ b/README.md @@ -74,9 +74,9 @@ Pour revenir à la version 8, renommez ce fichier "data.json". [R] fr Dossier localisé [F] page.json Données des pages [F] module.json Données des modules de pages - [F] admin.css Thème de la partie administration - [F] admin.json Données de la partie administration - [F] blacklist.json Données de connexion des comptes inconnus + [F] admin.css Thème des pages d'administration + [F] admin.json Données de thème des pages d'administration + [F] blacklist.json Journalisation des tentatives de connexion avec des comptes inconnus [F] config.json Configuration du site [F] core.json Configuration du noyau [F] custom.css Feuille de style de la personnalisation avancée @@ -84,6 +84,7 @@ Pour revenir à la version 8, renommez ce fichier "data.json". [F] theme.css Thème du site [F] theme.json Données du site [F] user.json Données des utilisateurs + [F] .backup Marqueur de la sauvegarde des fichiers si présent [R] file Répertoire d'upload du gestionnaire de fichiers [R] source Ressources diverses [R] thumb Miniatures des images diff --git a/core/core.php b/core/core.php index 2e5bc281..7b08cac5 100755 --- a/core/core.php +++ b/core/core.php @@ -204,7 +204,7 @@ class common { $this->dataFiles[$keys] = new \Prowebcraft\JsonDb([ 'name' => $keys . '.json', 'dir' => $this->dataPath ($keys,self::$i18nCurrent), - 'backup' => $keys === 'config' ? true : $this->getData(['config','fileBackup']) + 'backup' => file_exists('site/data/.backup') ]);; } diff --git a/core/module/config/config.php b/core/module/config/config.php index 355e9393..04e381aa 100755 --- a/core/module/config/config.php +++ b/core/module/config/config.php @@ -535,6 +535,9 @@ class config extends common { unlink($filename); } } + if (file_exists('site/data/.backup')) unlink('site/data/.backup'); + } else { + touch('site/data/.backup'); } // Notice if(self::$inputNotices === []) { From 29036af835e109c623e6727199f4dc6f6d773715 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Thu, 7 Jan 2021 09:49:57 +0100 Subject: [PATCH 10/15] =?UTF-8?q?mail=20de=20notification=20nom=20erron?= =?UTF-8?q?=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/blog/blog.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/blog/blog.php b/module/blog/blog.php index 5cb40fb2..72331d3e 100755 --- a/module/blog/blog.php +++ b/module/blog/blog.php @@ -635,7 +635,7 @@ class blog extends common { $sent = $this->sendMail( $to, 'Nouveau commentaire déposé', - 'Bonjour' . ' ' . $user['firstname'] . ' ' . $user['lastname'] . ',

' . + 'Bonjour

' . 'L\'article ' . $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'title']) . ' a reçu un nouveau commentaire.

', '' ); From beff8b10120c1d7bace7a1b4d7828e38e61b8a6c Mon Sep 17 00:00:00 2001 From: fredtempez Date: Fri, 8 Jan 2021 10:37:56 +0100 Subject: [PATCH 11/15] =?UTF-8?q?marqueur=20filebackup=20=20pas=20dans=20l?= =?UTF-8?q?es=20donn=C3=A9es=20de=20site=20mais=20un=20fichier=20.backup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/core.php | 2 +- core/module/config/config.php | 1 - core/module/config/view/advanced/advanced.php | 2 +- core/module/install/ressource/defaultdata.php | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/core.php b/core/core.php index 7b08cac5..738b4fa8 100755 --- a/core/core.php +++ b/core/core.php @@ -44,7 +44,7 @@ class common { const ACCESS_TIMER = 1800; // Numéro de version - const ZWII_VERSION = '10.4.00.012'; + const ZWII_VERSION = '10.4.00.013'; const ZWII_UPDATE_CHANNEL = "v10"; public static $actions = []; diff --git a/core/module/config/config.php b/core/module/config/config.php index 04e381aa..85f34738 100755 --- a/core/module/config/config.php +++ b/core/module/config/config.php @@ -485,7 +485,6 @@ class config extends common { [ 'analyticsId' => $this->getInput('configAdvancedAnalyticsId'), 'autoBackup' => $this->getInput('configAdvancedAutoBackup', helper::FILTER_BOOLEAN), - 'fileBackup' => $this->getInput('configAdvancedFileBackup', helper::FILTER_BOOLEAN), 'maintenance' => $this->getInput('configAdvancedMaintenance', helper::FILTER_BOOLEAN), 'cookieConsent' => $this->getInput('configAdvancedCookieConsent', helper::FILTER_BOOLEAN), 'favicon' => $this->getInput('configAdvancedFavicon'), diff --git a/core/module/config/view/advanced/advanced.php b/core/module/config/view/advanced/advanced.php index 7bcd6a4a..06718e43 100644 --- a/core/module/config/view/advanced/advanced.php +++ b/core/module/config/view/advanced/advanced.php @@ -103,7 +103,7 @@
$this->getData(['config', 'fileBackup']), + 'checked' => file_exists('site/data/.backup'), 'help' => '

Un fichier .backup.json est généré à chaque édition ou effacement d\'une donnée. La désactivation entraîne la suppression de ces fichiers.

' ]); ?>
diff --git a/core/module/install/ressource/defaultdata.php b/core/module/install/ressource/defaultdata.php index 3527fa2a..c6ef26dd 100755 --- a/core/module/install/ressource/defaultdata.php +++ b/core/module/install/ressource/defaultdata.php @@ -4,7 +4,6 @@ class init extends common { 'config' => [ 'analyticsId' => '', 'autoBackup' => true, - 'fileBackup' => true, 'autoUpdate' => true, 'autoUpdateHtaccess' => false, 'cookieConsent' => true, From f22eda7e6d1b8f00dc390ac25d4347901720a5c2 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Fri, 8 Jan 2021 10:49:31 +0100 Subject: [PATCH 12/15] Blog notification --- module/blog/blog.php | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/module/blog/blog.php b/module/blog/blog.php index 72331d3e..110d92f0 100755 --- a/module/blog/blog.php +++ b/module/blog/blog.php @@ -81,13 +81,13 @@ class blog extends common { public static $articleConsent = [ self::EDIT_ALL => 'Tous les groupes', self::EDIT_GROUP => 'Groupe du propriétaire', - self::EDIT_OWNER => 'Propiétaire' + self::EDIT_OWNER => 'Propriétaire' ]; public static $users = []; - const BLOG_VERSION = '4.1'; + const BLOG_VERSION = '4.2'; /** * Flux RSS @@ -627,22 +627,28 @@ class blog extends common { foreach($this->getData(['user']) as $userId => $user) { if ($user['group'] >= $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'commentGroupNotification']) ) { $to[] = $user['mail']; + $firstname[] = $user['firstname']; + $lastname[] = $user['lastname']; } } // Envoi du mail $sent code d'erreur ou de réussite $notification = $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'commentApproved']) === true ? 'Commentaire déposé en attente d\'approbation': 'Commentaire déposé'; if ($this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'commentNotification']) === true) { - $sent = $this->sendMail( - $to, - 'Nouveau commentaire déposé', - 'Bonjour

' . - 'L\'article ' . $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'title']) . ' a reçu un nouveau commentaire.

', - '' - ); + $error = 0; + foreach($to as $key => $adress){ + $sent = $this->sendMail( + $adress, + 'Nouveau commentaire déposé', + 'Bonjour' . ' ' . $firstname[$key] . ' ' . $lastname[$key] . ',

' . + 'L\'article ' . $this->getData(['module', $this->getUrl(0), 'posts', $this->getUrl(1), 'title']) . ' a reçu un nouveau commentaire.

', + '' + ); + if( $sent === false) $error++; + } // Valeurs en sortie $this->addOutput([ 'redirect' => helper::baseUrl() . $this->getUrl() . '#comment', - 'notification' => ($sent === true ? $notification . '
Une notification a été envoyée.' : $notification . '
Erreur de notification : ' . $sent), + 'notification' => ($error === 0 ? $notification . '
Une notification a été envoyée.' : $notification . '
Erreur de notification : ' . $sent), 'state' => ($sent === true ? true : null) ]); From 78e6dd7adc85277663a23df191451dc3d9cfc395 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Fri, 8 Jan 2021 15:13:16 +0100 Subject: [PATCH 13/15] Remove Facebook fbclid --- core/core.js.php | 7 +++++++ core/core.php | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/core/core.js.php b/core/core.js.php index be5c6b9d..09bfb0dd 100755 --- a/core/core.js.php +++ b/core/core.js.php @@ -472,4 +472,11 @@ $(document).ready(function(){ $(changeIcon).addClass('zwiico-menu'); }; }); + + /** + * Remove ID Facebook from URL + */ + if(/^\?fbclid=/.test(location.search)) + location.replace(location.href.replace(/\?fbclid.+/, "")); + }); diff --git a/core/core.php b/core/core.php index 738b4fa8..95995258 100755 --- a/core/core.php +++ b/core/core.php @@ -561,7 +561,16 @@ class common { // Une partie de l'url else { $url = explode('/', $this->url); - return array_key_exists($key, $url) ? $url[$key] : null; + if (array_key_exists($key, $url) ) { + if (strpos($url[$key],'fbclid=') === false) { + $result = $url[$key]; + } else { + $result = $key === 0 ? $this->getData(['config','homePageId']) : ''; + } + } else { + $result = null; + } + return $result; } } From d6f97b03bba278cb6b8a1e8ca452efd8e43ad31a Mon Sep 17 00:00:00 2001 From: fredtempez Date: Fri, 8 Jan 2021 15:21:15 +0100 Subject: [PATCH 14/15] =?UTF-8?q?fbclid=20dans=20htaccess=20avec=20la=20r?= =?UTF-8?q?=C3=A9=C3=A9criture?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/module/config/config.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/module/config/config.php b/core/module/config/config.php index 85f34738..9da3c94f 100755 --- a/core/module/config/config.php +++ b/core/module/config/config.php @@ -552,6 +552,8 @@ class config extends common { PHP_EOL . '' . PHP_EOL . "\tRewriteEngine on" . PHP_EOL . + "\tRewriteCond %{QUERY_STRING} ^(.*)&?fbclid=[^&]+&?(.*)$ [NC]". PHP_EOL . + "\tRewriteRule ^/?(.*)$ /$1?%1%2 [R=301,L]". PHP_EOL . "\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL . "\tRewriteCond %{REQUEST_FILENAME} !-f" . PHP_EOL . "\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL . From 2ad68ca01da11e252c7a91e875466c7498792ca7 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Sat, 9 Jan 2021 11:32:44 +0100 Subject: [PATCH 15/15] changes --- CHANGES.md | 3 ++- core/core.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1fdfabb8..5b4873e3 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ ## version 10.4.00 - Modifications : + - Filtrage des URL générées par facebook (FBCLID) occasionnant une erreur 404 - Captcha arithmétique, activation recommandée dans la configuration. - Module User - Pour les articles de blog et de news, choix de la signature, nom+prenom ; nom+prenom ; id ; pseudo @@ -15,9 +16,9 @@ - Approbation des commentaires - Gestion des thèmes : - Bouton de réinitialisation avec confirmation - - Traduction automatique dans la langue du navigateur. - Amélioration de la structure du flux RSS. + ## Version 10.3.13 Modifications : - Système de données (JsonDB) : diff --git a/core/core.php b/core/core.php index 95995258..e56a08de 100755 --- a/core/core.php +++ b/core/core.php @@ -1937,7 +1937,7 @@ class core extends common { $access = false; } } - // Empêcher l'accès aux page désactivée par URL directe + // Empêcher l'accès aux pages désactivées par URL directe if ( ( $this->getData(['page', $this->getUrl(0),'disable']) === true AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') ) OR (