From 1ef15e232b2e397c5325951f04927da9ee4726ef Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 9 Jan 2014 23:32:50 +0100 Subject: Numéro de version 0.7-dev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'README.md') diff --git a/README.md b/README.md index e25de9468..973ce5f12 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Il permet de gérer plusieurs utilisateurs, et dispose d’un mode de lecture an * Site officiel : http://freshrss.org * Démo : http://marienfressinaud.fr/projets/freshrss/ * Développeur : Marien Fressinaud -* Version actuelle : 0.7-beta4 +* Version actuelle : 0.7-dev * Date de publication 2014-01-xx * License [GNU AGPL 3](http://www.gnu.org/licenses/agpl-3.0.html) -- cgit v1.2.3 From c7a28e836edf4e681fe2e0395ab9f11cc90032c9 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 11 Jan 2014 15:38:29 +0100 Subject: README blibliothèques incluses + ajout librairies pour le mot de passe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Préparation https://github.com/marienfressinaud/FreshRSS/issues/104 --- README.md | 14 +++ lib/password_compat.php | 279 ++++++++++++++++++++++++++++++++++++++++++++++++ p/scripts/bcrypt.min.js | 41 +++++++ 3 files changed, 334 insertions(+) create mode 100644 lib/password_compat.php create mode 100644 p/scripts/bcrypt.min.js (limited to 'README.md') diff --git a/README.md b/README.md index 973ce5f12..aebd445cd 100644 --- a/README.md +++ b/README.md @@ -72,3 +72,17 @@ Par exemple, pour exécuter le script toutes les heures : ```bash mysqldump -u utilisateur -p --databases freshrss > freshrss.sql ``` + +# Bibliothèques incluses +* [SimplePie](https://github.com/simplepie/simplepie) +* [MINZ](https://github.com/marienfressinaud/MINZ) +* [php-http-304](http://alexandre.alapetite.fr/doc-alex/php-http-304/) +* [jQuery](http://jquery.com/) +* [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/) +## Uniquement dans certaines configurations +* [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) +* [phpQuery](http://code.google.com/p/phpquery/) +* [Lazy Load](http://www.appelsiini.net/projects/lazyload) +## Uniquement si les fonctions natives ne sont pas disponibles +* [Services_JSON](http://pear.php.net/pepr/pepr-proposal-show.php?id=198) +* [password_compat](https://github.com/ircmaxell/password_compat) diff --git a/lib/password_compat.php b/lib/password_compat.php new file mode 100644 index 000000000..e8ec02885 --- /dev/null +++ b/lib/password_compat.php @@ -0,0 +1,279 @@ + + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @copyright 2012 The Authors + */ + +namespace { + +if (!defined('PASSWORD_DEFAULT')) { + + define('PASSWORD_BCRYPT', 1); + define('PASSWORD_DEFAULT', PASSWORD_BCRYPT); + + /** + * Hash the password using the specified algorithm + * + * @param string $password The password to hash + * @param int $algo The algorithm to use (Defined by PASSWORD_* constants) + * @param array $options The options for the algorithm to use + * + * @return string|false The hashed password, or false on error. + */ + function password_hash($password, $algo, array $options = array()) { + if (!function_exists('crypt')) { + trigger_error("Crypt must be loaded for password_hash to function", E_USER_WARNING); + return null; + } + if (!is_string($password)) { + trigger_error("password_hash(): Password must be a string", E_USER_WARNING); + return null; + } + if (!is_int($algo)) { + trigger_error("password_hash() expects parameter 2 to be long, " . gettype($algo) . " given", E_USER_WARNING); + return null; + } + $resultLength = 0; + switch ($algo) { + case PASSWORD_BCRYPT: + // Note that this is a C constant, but not exposed to PHP, so we don't define it here. + $cost = 10; + if (isset($options['cost'])) { + $cost = $options['cost']; + if ($cost < 4 || $cost > 31) { + trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d", $cost), E_USER_WARNING); + return null; + } + } + // The length of salt to generate + $raw_salt_len = 16; + // The length required in the final serialization + $required_salt_len = 22; + $hash_format = sprintf("$2y$%02d$", $cost); + // The expected length of the final crypt() output + $resultLength = 60; + break; + default: + trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s", $algo), E_USER_WARNING); + return null; + } + $salt_requires_encoding = false; + if (isset($options['salt'])) { + switch (gettype($options['salt'])) { + case 'NULL': + case 'boolean': + case 'integer': + case 'double': + case 'string': + $salt = (string) $options['salt']; + break; + case 'object': + if (method_exists($options['salt'], '__tostring')) { + $salt = (string) $options['salt']; + break; + } + case 'array': + case 'resource': + default: + trigger_error('password_hash(): Non-string salt parameter supplied', E_USER_WARNING); + return null; + } + if (PasswordCompat\binary\_strlen($salt) < $required_salt_len) { + trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d", PasswordCompat\binary\_strlen($salt), $required_salt_len), E_USER_WARNING); + return null; + } elseif (0 == preg_match('#^[a-zA-Z0-9./]+$#D', $salt)) { + $salt_requires_encoding = true; + } + } else { + $buffer = ''; + $buffer_valid = false; + if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) { + $buffer = mcrypt_create_iv($raw_salt_len, MCRYPT_DEV_URANDOM); + if ($buffer) { + $buffer_valid = true; + } + } + if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) { + $buffer = openssl_random_pseudo_bytes($raw_salt_len); + if ($buffer) { + $buffer_valid = true; + } + } + if (!$buffer_valid && @is_readable('/dev/urandom')) { + $f = fopen('/dev/urandom', 'r'); + $read = PasswordCompat\binary\_strlen($buffer); + while ($read < $raw_salt_len) { + $buffer .= fread($f, $raw_salt_len - $read); + $read = PasswordCompat\binary\_strlen($buffer); + } + fclose($f); + if ($read >= $raw_salt_len) { + $buffer_valid = true; + } + } + if (!$buffer_valid || PasswordCompat\binary\_strlen($buffer) < $raw_salt_len) { + $bl = PasswordCompat\binary\_strlen($buffer); + for ($i = 0; $i < $raw_salt_len; $i++) { + if ($i < $bl) { + $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255)); + } else { + $buffer .= chr(mt_rand(0, 255)); + } + } + } + $salt = $buffer; + $salt_requires_encoding = true; + } + if ($salt_requires_encoding) { + // encode string with the Base64 variant used by crypt + $base64_digits = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + $bcrypt64_digits = + './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + $base64_string = base64_encode($salt); + $salt = strtr(rtrim($base64_string, '='), $base64_digits, $bcrypt64_digits); + } + $salt = PasswordCompat\binary\_substr($salt, 0, $required_salt_len); + + $hash = $hash_format . $salt; + + $ret = crypt($password, $hash); + + if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != $resultLength) { + return false; + } + + return $ret; + } + + /** + * Get information about the password hash. Returns an array of the information + * that was used to generate the password hash. + * + * array( + * 'algo' => 1, + * 'algoName' => 'bcrypt', + * 'options' => array( + * 'cost' => 10, + * ), + * ) + * + * @param string $hash The password hash to extract info from + * + * @return array The array of information about the hash. + */ + function password_get_info($hash) { + $return = array( + 'algo' => 0, + 'algoName' => 'unknown', + 'options' => array(), + ); + if (PasswordCompat\binary\_substr($hash, 0, 4) == '$2y$' && PasswordCompat\binary\_strlen($hash) == 60) { + $return['algo'] = PASSWORD_BCRYPT; + $return['algoName'] = 'bcrypt'; + list($cost) = sscanf($hash, "$2y$%d$"); + $return['options']['cost'] = $cost; + } + return $return; + } + + /** + * Determine if the password hash needs to be rehashed according to the options provided + * + * If the answer is true, after validating the password using password_verify, rehash it. + * + * @param string $hash The hash to test + * @param int $algo The algorithm used for new password hashes + * @param array $options The options array passed to password_hash + * + * @return boolean True if the password needs to be rehashed. + */ + function password_needs_rehash($hash, $algo, array $options = array()) { + $info = password_get_info($hash); + if ($info['algo'] != $algo) { + return true; + } + switch ($algo) { + case PASSWORD_BCRYPT: + $cost = isset($options['cost']) ? $options['cost'] : 10; + if ($cost != $info['options']['cost']) { + return true; + } + break; + } + return false; + } + + /** + * Verify a password against a hash using a timing attack resistant approach + * + * @param string $password The password to verify + * @param string $hash The hash to verify against + * + * @return boolean If the password matches the hash + */ + function password_verify($password, $hash) { + if (!function_exists('crypt')) { + trigger_error("Crypt must be loaded for password_verify to function", E_USER_WARNING); + return false; + } + $ret = crypt($password, $hash); + if (!is_string($ret) || PasswordCompat\binary\_strlen($ret) != PasswordCompat\binary\_strlen($hash) || PasswordCompat\binary\_strlen($ret) <= 13) { + return false; + } + + $status = 0; + for ($i = 0; $i < PasswordCompat\binary\_strlen($ret); $i++) { + $status |= (ord($ret[$i]) ^ ord($hash[$i])); + } + + return $status === 0; + } +} + +} + +namespace PasswordCompat\binary { + /** + * Count the number of bytes in a string + * + * We cannot simply use strlen() for this, because it might be overwritten by the mbstring extension. + * In this case, strlen() will count the number of *characters* based on the internal encoding. A + * sequence of bytes might be regarded as a single multibyte character. + * + * @param string $binary_string The input string + * + * @internal + * @return int The number of bytes + */ + function _strlen($binary_string) { + if (function_exists('mb_strlen')) { + return mb_strlen($binary_string, '8bit'); + } + return strlen($binary_string); + } + + /** + * Get a substring based on byte limits + * + * @see _strlen() + * + * @param string $binary_string The input string + * @param int $start + * @param int $length + * + * @internal + * @return string The substring + */ + function _substr($binary_string, $start, $length) { + if (function_exists('mb_substr')) { + return mb_substr($binary_string, $start, $length, '8bit'); + } + return substr($binary_string, $start, $length); + } + +} diff --git a/p/scripts/bcrypt.min.js b/p/scripts/bcrypt.min.js new file mode 100644 index 000000000..6892caddc --- /dev/null +++ b/p/scripts/bcrypt.min.js @@ -0,0 +1,41 @@ +/* + bcrypt.js (c) 2013 Daniel Wirtz + Released under the Apache License, Version 2.0 + see: https://github.com/dcodeIO/bcrypt.js for details +*/ +function p(n){throw n;}var q=null; +(function(n){function u(c,a,b,f){for(var d,e=c[a],l=c[a+1],e=e^b[0],h=0;14>=h;)d=f[e>>24&255],d+=f[256|e>>16&255],d^=f[512|e>>8&255],d+=f[768|e&255],l^=d^b[++h],d=f[l>>24&255],d+=f[256|l>>16&255],d^=f[512|l>>8&255],d+=f[768|l&255],e^=d^b[++h];c[a]=l^b[17];c[a+1]=e;return c}function s(c,a){var b,f=0;for(b=0;4>b;b++)f=f<<8|c[a]&255,a=(a+1)%c.length;return{key:f,a:a}}function y(c,a,b){for(var f=0,d=[0,0],e=a.length,l=b.length,h=0;hk;k++)for(m=0;m>1;m++)u(e,m<<1,h,g);n=[];for(k=0;k>24&255)>>>0),n.push((e[k]>>16&255)>>>0),n.push((e[k]>>8&255)>>>0),n.push((e[k]&255)>>>0);return f?(f(q,n),q):n}f&&z(d);return q}var e=B.slice(),l=e.length;(4>b||31>=8;while(a);f=f.concat(b.reverse())}return f}function w(c,a,b){function f(a){var b=[];b.push("$2");"a"<=d&&b.push(d);b.push("$");10>l&&b.push("0");b.push(l.toString());b.push("$");b.push(v.b(h,h.length));b.push(v.b(a,4*B.length-1));return b.join("")}var d,e;("$"!=a.charAt(0)||"2"!=a.charAt(1))&&p(Error("Invalid salt version: "+ +a.substring(0,2)));"$"==a.charAt(2)?(d=String.fromCharCode(0),e=3):(d=a.charAt(2),("a"!=d||"$"!=a.charAt(3))&&p(Error("Invalid salt revision: "+a.substring(2,4))),e=4);"$"=a||a>c.length)&&p(Error("Invalid 'len': "+a));b>2&63]);d=(d&3)<<4;if(b>=a){f.push(t[d&63]);break}e=c[b++]&255;d|=e>>4&15;f.push(t[d&63]);d=(e&15)<< +2;if(b>=a){f.push(t[d&63]);break}e=c[b++]&255;d|=e>>6&3;f.push(t[d&63]);f.push(t[e&63])}return f.join("")},c:function(c,a){var b=0,f=c.length,d=0,e=[],l,h,g;for(0>=a&&p(Error("Illegal 'len': "+a));b>>0;g|=(h&48)>>4;e.push(String.fromCharCode(g));if(++d>=a||b>=f)break;g=c.charCodeAt(b++);l=g>>0;g|=(l&60)>>2;e.push(String.fromCharCode(g)); +if(++d>=a||b>=f)break;g=c.charCodeAt(b++);h=g>>0;g|=h;e.push(String.fromCharCode(g));++d}f=[];for(b=0;bc||31c&&b.push("0");b.push(c.toString());b.push("$");try{b.push(v.b(G(),16)),a=b.join("")}catch(f){p(f)}return a};m.genSalt=function(c,a,b){"function"==typeof a&&(b=a,a=-1);var f;"function"==typeof c?(b=c,f=10):f=parseInt(c,10);"function"!=typeof b&&p(Error("Illegal or missing 'callback': "+b));z(function(){try{var a=m.genSaltSync(f);b(q,a)}catch(c){b(c,q)}})};m.hashSync=function(c,a){a||(a=10);"number"==typeof a&&(a=m.genSaltSync(a));return w(c,a)};m.hash=function(c,a,b){"function"!= +typeof b&&p(Error("Illegal 'callback': "+b));"number"==typeof a?m.genSalt(a,function(a,d){w(c,d,b)}):w(c,a,b)};m.compareSync=function(c,a){("string"!=typeof c||"string"!=typeof a)&&p(Error("Illegal argument types: "+typeof c+", "+typeof a));60!=a.length&&p(Error("Illegal hash length: "+a.length+" != 60"));for(var b=m.hashSync(c,a.substr(0,a.length-31)),f=b.length==a.length,d=b.length=e&&(a.length>=e&&b[e]!=a[e])&&(f=!1);return f};m.compare=function(c, +a,b){"function"!=typeof b&&p(Error("Illegal 'callback': "+b));m.hash(c,a.substr(0,29),function(c,d){b(c,a===d)})};m.getRounds=function(c){"string"!=typeof c&&p(Error("Illegal type of 'hash': "+typeof c));return parseInt(c.split("$")[2],10)};m.getSalt=function(c){"string"!=typeof c&&p(Error("Illegal type of 'hash': "+typeof c));60!=c.length&&p(Error("Illegal hash length: "+c.length+" != 60"));return c.substring(0,29)};"undefined"!=typeof module&&module.exports?module.exports=m:"undefined"!=typeof define&& +define.amd?define("bcrypt",function(){return m}):(n.dcodeIO||(n.dcodeIO={}),n.dcodeIO.bcrypt=m)})(this); -- cgit v1.2.3 From c17f5a139423e58a32ff5e29fb1f3f8a16c240dd Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 11 Jan 2014 15:41:58 +0100 Subject: Syntaxe README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'README.md') diff --git a/README.md b/README.md index aebd445cd..28c70b81f 100644 --- a/README.md +++ b/README.md @@ -73,16 +73,20 @@ Par exemple, pour exécuter le script toutes les heures : mysqldump -u utilisateur -p --databases freshrss > freshrss.sql ``` +--- + # Bibliothèques incluses * [SimplePie](https://github.com/simplepie/simplepie) * [MINZ](https://github.com/marienfressinaud/MINZ) * [php-http-304](http://alexandre.alapetite.fr/doc-alex/php-http-304/) * [jQuery](http://jquery.com/) * [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/) + ## Uniquement dans certaines configurations * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](http://code.google.com/p/phpquery/) * [Lazy Load](http://www.appelsiini.net/projects/lazyload) + ## Uniquement si les fonctions natives ne sont pas disponibles * [Services_JSON](http://pear.php.net/pepr/pepr-proposal-show.php?id=198) * [password_compat](https://github.com/ircmaxell/password_compat) -- cgit v1.2.3 From fa34f3149f2534dc50af1b69e12befc3ca62785a Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 11 Jan 2014 15:43:25 +0100 Subject: Syntaxe README #2 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'README.md') diff --git a/README.md b/README.md index 28c70b81f..96e25f4df 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,8 @@ Par exemple, pour exécuter le script toutes les heures : mysqldump -u utilisateur -p --databases freshrss > freshrss.sql ``` + + --- # Bibliothèques incluses @@ -87,6 +89,6 @@ mysqldump -u utilisateur -p --databases freshrss > freshrss.sql * [phpQuery](http://code.google.com/p/phpquery/) * [Lazy Load](http://www.appelsiini.net/projects/lazyload) -## Uniquement si les fonctions natives ne sont pas disponibles +## Si les fonctions natives ne sont pas disponibles * [Services_JSON](http://pear.php.net/pepr/pepr-proposal-show.php?id=198) * [password_compat](https://github.com/ircmaxell/password_compat) -- cgit v1.2.3 From eb50ab3b61ee2280dac2696598a58803e246fe22 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 11 Jan 2014 16:48:10 +0100 Subject: Mot de passe + nonce serveur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Début de https://github.com/marienfressinaud/FreshRSS/issues/104 --- README.md | 7 ++----- app/Controllers/javascriptController.php | 27 +++++++++++++++++++++++++++ app/Models/Configuration.php | 4 ++++ app/views/javascript/nonce.phtml | 2 ++ 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 app/views/javascript/nonce.phtml (limited to 'README.md') diff --git a/README.md b/README.md index 96e25f4df..4100a8638 100644 --- a/README.md +++ b/README.md @@ -74,17 +74,14 @@ mysqldump -u utilisateur -p --databases freshrss > freshrss.sql ``` - ---- - # Bibliothèques incluses -* [SimplePie](https://github.com/simplepie/simplepie) +* [SimplePie](http://simplepie.org/) * [MINZ](https://github.com/marienfressinaud/MINZ) * [php-http-304](http://alexandre.alapetite.fr/doc-alex/php-http-304/) * [jQuery](http://jquery.com/) * [keyboard_shortcuts](http://www.openjs.com/scripts/events/keyboard_shortcuts/) -## Uniquement dans certaines configurations +## Uniquement pour certaines options * [bcrypt.js](https://github.com/dcodeIO/bcrypt.js) * [phpQuery](http://code.google.com/p/phpquery/) * [Lazy Load](http://www.appelsiini.net/projects/lazyload) diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index 2d0ff4984..e29f439d8 100755 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -16,4 +16,31 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { $catDAO = new FreshRSS_CategoryDAO(); $this->view->categories = $catDAO->listCategories(true, false); } + + // For Web-form login + public function nonceAction() { + header('Content-Type: application/json; charset=UTF-8'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s \G\M\T')); + header('Expires: 0'); + header('Cache-Control: private, no-cache, no-store, must-revalidate'); + header('Pragma: no-cache'); + + $user = isset($_GET['user']) ? $_GET['user'] : ''; + if (ctype_alnum($user)) { + try { + $conf = new FreshRSS_Configuration($user); + $hash = $conf->passwordHash; //CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". + if (strlen($hash) >= 60) { + $this->view->salt1 = substr($hash, 0, 29); + $this->view->nonce = sha1(Minz_Configuration::salt() . uniqid(mt_rand(), true)); + Minz_Session::_param ('nonce', $this->view->nonce); + return; //Success + } + } catch (Minz_Exception $me) { + Minz_Log::record ('Login failure: ' . $me->getMessage(), Minz_Log::WARNING); + } + } + $this->view->nonce = ''; //Failure + $this->view->salt1 = ''; + } } diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php index c29e74603..8f394737a 100644 --- a/app/Models/Configuration.php +++ b/app/Models/Configuration.php @@ -9,6 +9,7 @@ class FreshRSS_Configuration { 'keep_history_default' => 0, 'mail_login' => '', 'token' => '', + 'passwordHash' => '', //CRYPT_BLOWFISH 'posts_per_page' => 20, 'view_mode' => 'normal', 'default_view' => 'not_read', @@ -162,6 +163,9 @@ class FreshRSS_Configuration { } } } + public function _passwordHash ($value) { + $this->data['passwordHash'] = ctype_graph($value) && (strlen($value) >= 60) ? $value : ''; + } public function _mail_login ($value) { $value = filter_var($value, FILTER_VALIDATE_EMAIL); if ($value) { diff --git a/app/views/javascript/nonce.phtml b/app/views/javascript/nonce.phtml new file mode 100644 index 000000000..4ac46c8fc --- /dev/null +++ b/app/views/javascript/nonce.phtml @@ -0,0 +1,2 @@ + $this->salt1, 'nonce' => $this->nonce)); -- cgit v1.2.3 From 5f0594c630028b8612b57da15bcdf00a932930bc Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 18 Jan 2014 21:26:33 +0100 Subject: Désactive l'identification par formulaire en dessous de PHP 5.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHP 5.3 est sorti en juin 2009. https://github.com/ircmaxell/password_compat Pour plus de tranquillité (compatibilité et sécurité), il faudrait même désactiver en dessous de PHP 5.3.7 (août 2011) --- CHANGELOG | 1 + README.md | 2 +- app/views/configure/users.phtml | 2 +- p/i/install.php | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) (limited to 'README.md') diff --git a/CHANGELOG b/CHANGELOG index 9a0ae1f61..f72bd8ff5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ * Nécessite un contrôle d’accès, soit : * par le nouveau mode de connexion par formulaire (nom d’utilisateur + mot de passe) * relativement sûr même sans HTTPS (le mot de passe n’est pas transmis en clair) + * requiert JavaScript et PHP 5.3+ * par HTTP (par exemple sous Apache en créant un fichier ./p/i/.htaccess et .htpasswd) * le nom d’utilisateur HTTP doit correspondre au nom d’utilisateur FreshRSS * par Mozilla Persona, en renseignant l’adresse courriel des utilisateurs diff --git a/README.md b/README.md index 4100a8638..abc40d489 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Privilégiez pour cela des demandes sur GitHub * Serveur modeste, par exemple sous Linux ou Windows * Fonctionne même sur un Raspberry Pi avec des temps de réponse < 1s (testé sur 150 flux, 22k articles, soit 32Mo de données partiellement compressées) * Serveur Web Apache2 ou Nginx (non testé sur les autres) -* PHP 5.2+ (PHP 5.3.4+ recommandé) +* PHP 5.2+ (PHP 5.3.7+ recommandé) * Requis : [PDO_MySQL](http://php.net/pdo-mysql), [cURL](http://php.net/curl), [LibXML](http://php.net/xml), [PCRE](http://php.net/pcre), [ctype](http://php.net/ctype) * Recommandés : [JSON](http://php.net/json), [zlib](http://php.net/zlib), [mbstring](http://php.net/mbstring), [iconv](http://php.net/iconv) * MySQL 5.0.3+ (ou SQLite 3.7.4+ à venir) diff --git a/app/views/configure/users.phtml b/app/views/configure/users.phtml index 3f352f9bf..41129333c 100644 --- a/app/views/configure/users.phtml +++ b/app/views/configure/users.phtml @@ -50,7 +50,7 @@
- + -- cgit v1.2.3 From d15fa1cab5880b3b87098b8065150170c422ee8f Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 18 Jan 2014 23:48:04 +0100 Subject: Préparation sortie 0.7-RC1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- constants.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'README.md') diff --git a/README.md b/README.md index abc40d489..bd186b46c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Il permet de gérer plusieurs utilisateurs, et dispose d’un mode de lecture an * Site officiel : http://freshrss.org * Démo : http://marienfressinaud.fr/projets/freshrss/ * Développeur : Marien Fressinaud -* Version actuelle : 0.7-dev +* Version actuelle : 0.7-RC1 * Date de publication 2014-01-xx * License [GNU AGPL 3](http://www.gnu.org/licenses/agpl-3.0.html) diff --git a/constants.php b/constants.php index c1c569f7d..0faac7c5f 100644 --- a/constants.php +++ b/constants.php @@ -1,5 +1,5 @@