summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar plopoyop <clement@iMac-de-Clement.local> 2014-09-19 09:07:11 +0200
committerGravatar plopoyop <clement@iMac-de-Clement.local> 2014-09-19 09:07:11 +0200
commitffbfbb92cc89c5ae07e0a28ee3477fcd0c44505d (patch)
tree827469859e1300f3525196658b7191fa1dbb40f9
parent4fd1478e82dabaa042f4e80d4b9b2830f29a7da8 (diff)
parent2f5304a1f7052bce1315f2ed85141568f0995e7c (diff)
Merge branch 'dev' of https://github.com/marienfressinaud/FreshRSS into dev
-rwxr-xr-xapp/Controllers/indexController.php76
-rw-r--r--app/Controllers/updateController.php6
-rw-r--r--app/FreshRSS.php9
-rw-r--r--app/Models/Configuration.php13
-rw-r--r--app/Models/Entry.php2
-rw-r--r--app/Models/EntryDAO.php3
-rw-r--r--app/Models/FeedDAO.php2
-rw-r--r--app/i18n/en.php21
-rw-r--r--app/i18n/fr.php17
-rw-r--r--app/i18n/install.en.php2
-rw-r--r--app/i18n/install.fr.php2
-rw-r--r--app/install.php52
-rw-r--r--app/layout/aside_configure.phtml16
-rw-r--r--app/layout/layout.phtml1
-rw-r--r--app/views/configure/reading.phtml22
-rwxr-xr-xapp/views/helpers/pagination.phtml5
-rw-r--r--app/views/index/formLogin.phtml13
-rw-r--r--app/views/index/resetAuth.phtml33
-rw-r--r--app/views/stats/idle.phtml19
-rw-r--r--app/views/stats/index.phtml46
-rw-r--r--app/views/stats/repartition.phtml8
-rw-r--r--app/views/update/index.phtml4
-rw-r--r--lib/Minz/Request.php14
-rw-r--r--lib/lib_rss.php14
-rw-r--r--p/scripts/main.js35
-rw-r--r--p/themes/Dark/dark.css13
-rw-r--r--p/themes/Flat/flat.css13
-rw-r--r--p/themes/Origine/origine.css17
-rw-r--r--p/themes/Screwdriver/screwdriver.css13
-rw-r--r--p/themes/base-theme/base.css12
-rw-r--r--p/themes/base-theme/template.css23
31 files changed, 412 insertions, 114 deletions
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php
index b0b051119..b69c09127 100755
--- a/app/Controllers/indexController.php
+++ b/app/Controllers/indexController.php
@@ -83,6 +83,11 @@ class FreshRSS_index_Controller extends Minz_ActionController {
$nb = Minz_Request::param ('nb', $this->view->conf->posts_per_page);
$first = Minz_Request::param ('next', '');
+ $ajax_request = Minz_Request::param('ajax', false);
+ if ($ajax_request == 1 && $this->view->conf->display_posts) {
+ $nb = max(1, round($nb / 2));
+ }
+
if ($this->view->state === FreshRSS_Entry::STATE_NOT_READ) { //Any unread article in this category at all?
switch ($getType) {
case 'a':
@@ -415,4 +420,75 @@ class FreshRSS_index_Controller extends Minz_ActionController {
self::deleteLongTermCookie();
Minz_Request::forward(array('c' => 'index', 'a' => 'index'), true);
}
+
+ public function resetAuthAction() {
+ Minz_View::prependTitle(_t('auth_reset') . ' · ');
+ Minz_View::appendScript(Minz_Url::display(
+ '/scripts/bcrypt.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js')
+ ));
+
+ $this->view->no_form = false;
+ // Enable changement of auth only if Persona!
+ if (Minz_Configuration::authType() != 'persona') {
+ $this->view->message = array(
+ 'status' => 'bad',
+ 'title' => _t('damn'),
+ 'body' => _t('auth_not_persona')
+ );
+ $this->view->no_form = true;
+ return;
+ }
+
+ $conf = new FreshRSS_Configuration(Minz_Configuration::defaultUser());
+ // Admin user must have set its master password.
+ if (!$conf->passwordHash) {
+ $this->view->message = array(
+ 'status' => 'bad',
+ 'title' => _t('damn'),
+ 'body' => _t('auth_no_password_set')
+ );
+ $this->view->no_form = true;
+ return;
+ }
+
+ invalidateHttpCache();
+
+ if (Minz_Request::isPost()) {
+ $nonce = Minz_Session::param('nonce');
+ $username = Minz_Request::param('username', '');
+ $c = Minz_Request::param('challenge', '');
+ if (!(ctype_alnum($username) && ctype_graph($c) && ctype_alnum($nonce))) {
+ Minz_Log::debug('Invalid credential parameters:' .
+ ' user=' . $username .
+ ' challenge=' . $c .
+ ' nonce=' . $nonce);
+ Minz_Request::bad(_t('invalid_login'),
+ array('c' => 'index', 'a' => 'resetAuth'));
+ }
+
+ if (!function_exists('password_verify')) {
+ include_once(LIB_PATH . '/password_compat.php');
+ }
+
+ $s = $conf->passwordHash;
+ $ok = password_verify($nonce . $s, $c);
+ if ($ok) {
+ Minz_Configuration::_authType('form');
+ $ok = Minz_Configuration::writeFile();
+
+ if ($ok) {
+ Minz_Request::good(_t('auth_form_set'));
+ } else {
+ Minz_Request::bad(_t('auth_form_not_set'),
+ array('c' => 'index', 'a' => 'resetAuth'));
+ }
+ } else {
+ Minz_Log::debug('Password mismatch for user ' . $username .
+ ', nonce=' . $nonce . ', c=' . $c);
+
+ Minz_Request::bad(_t('invalid_login'),
+ array('c' => 'index', 'a' => 'resetAuth'));
+ }
+ }
+ }
}
diff --git a/app/Controllers/updateController.php b/app/Controllers/updateController.php
index 72244e9c7..da5bddc65 100644
--- a/app/Controllers/updateController.php
+++ b/app/Controllers/updateController.php
@@ -10,7 +10,10 @@ class FreshRSS_update_Controller extends Minz_ActionController {
);
}
+ invalidateHttpCache();
+
Minz_View::prependTitle(_t('update_system') . ' · ');
+ $this->view->update_to_apply = false;
$this->view->last_update_time = 'unknown';
$this->view->check_last_hour = false;
$timestamp = (int)@file_get_contents(DATA_PATH . '/last_update.txt');
@@ -29,10 +32,11 @@ class FreshRSS_update_Controller extends Minz_ActionController {
);
} elseif (file_exists(UPDATE_FILENAME)) {
// There is an update file to apply!
+ $this->view->update_to_apply = true;
$this->view->message = array(
'status' => 'good',
'title' => _t('ok'),
- 'body' => _t('update_can_apply', _url('update', 'apply'))
+ 'body' => _t('update_can_apply')
);
}
}
diff --git a/app/FreshRSS.php b/app/FreshRSS.php
index 6cca27f78..cdf8962cb 100644
--- a/app/FreshRSS.php
+++ b/app/FreshRSS.php
@@ -6,7 +6,7 @@ class FreshRSS extends Minz_FrontController {
}
$loginOk = $this->accessControl(Minz_Session::param('currentUser', ''));
$this->loadParamsView();
- if (Minz_Request::isPost() && !Minz_Request::isRefererFromSameDomain()) {
+ if (Minz_Request::isPost() && !is_referer_from_same_domain()) {
$loginOk = false; //Basic protection against XSRF attacks
Minz_Error::error(
403,
@@ -143,11 +143,12 @@ class FreshRSS extends Minz_FrontController {
$theme = FreshRSS_Themes::load($this->conf->theme);
if ($theme) {
foreach($theme['files'] as $file) {
- $theme_id = $theme['id'];
- $filename = $file;
- if ($file[0] == '_') {
+ if ($file[0] === '_') {
$theme_id = 'base-theme';
$filename = substr($file, 1);
+ } else {
+ $theme_id = $theme['id'];
+ $filename = $file;
}
$filetime = @filemtime(PUBLIC_PATH . '/themes/' . $theme_id . '/' . $filename);
Minz_View::appendStyle(Minz_Url::display(
diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php
index 830d39f0d..f94d82402 100644
--- a/app/Models/Configuration.php
+++ b/app/Models/Configuration.php
@@ -142,7 +142,18 @@ class FreshRSS_Configuration {
}
}
public function _default_view ($value) {
- $this->data['default_view'] = $value === FreshRSS_Entry::STATE_ALL ? FreshRSS_Entry::STATE_ALL : FreshRSS_Entry::STATE_NOT_READ;
+ switch ($value) {
+ case FreshRSS_Entry::STATE_ALL:
+ // left blank on purpose
+ case FreshRSS_Entry::STATE_NOT_READ:
+ // left blank on purpose
+ case FreshRSS_Entry::STATE_NOT_READ_STRICT:
+ $this->data['default_view'] = $value;
+ break;
+ default:
+ $this->data['default_view'] = FreshRSS_Entry::STATE_ALL;
+ break;
+ }
}
public function _display_posts ($value) {
$this->data['display_posts'] = ((bool)$value) && $value !== 'no';
diff --git a/app/Models/Entry.php b/app/Models/Entry.php
index 0bf1f2616..5f1c8abc4 100644
--- a/app/Models/Entry.php
+++ b/app/Models/Entry.php
@@ -6,6 +6,8 @@ class FreshRSS_Entry extends Minz_Model {
const STATE_NOT_READ = 2;
const STATE_FAVORITE = 4;
const STATE_NOT_FAVORITE = 8;
+ const STATE_READ_STRICT = 16;
+ const STATE_NOT_READ_STRICT = 32;
private $id = 0;
private $guid;
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index 75a8aeba4..dee49212d 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -338,6 +338,9 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
elseif ($state & FreshRSS_Entry::STATE_READ) {
$where .= 'AND e1.is_read=1 ';
}
+ elseif ($state & FreshRSS_Entry::STATE_NOT_READ_STRICT) {
+ $where .= 'AND e1.is_read=0 ';
+ }
if ($state & FreshRSS_Entry::STATE_FAVORITE) {
if (!($state & FreshRSS_Entry::STATE_NOT_FAVORITE)) {
$where .= 'AND e1.is_favorite=1 ';
diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php
index 756b1f008..b89ae2045 100644
--- a/app/Models/FeedDAO.php
+++ b/app/Models/FeedDAO.php
@@ -331,7 +331,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo {
$id_max = intval($date_min) . '000000';
$stm->bindParam(':id_feed', $id, PDO::PARAM_INT);
- $stm->bindParam(':id_max', $id_max, PDO::PARAM_INT);
+ $stm->bindParam(':id_max', $id_max, PDO::PARAM_STR);
$stm->bindParam(':keep', $keep, PDO::PARAM_INT);
if ($stm && $stm->execute()) {
diff --git a/app/i18n/en.php b/app/i18n/en.php
index ca31c4bfc..8598e61cb 100644
--- a/app/i18n/en.php
+++ b/app/i18n/en.php
@@ -5,6 +5,7 @@ return array (
'login' => 'Login',
'keep_logged_in' => 'Keep me logged in <small>(1 month)</small>',
'login_with_persona' => 'Login with Persona',
+ 'login_persona_problem' => 'Problem of connection with Persona?',
'logout' => 'Logout',
'search' => 'Search words or #tags',
'search_short' => 'Search',
@@ -92,6 +93,7 @@ return array (
'rss_view' => 'RSS feed',
'show_all_articles' => 'Show all articles',
'show_not_reads' => 'Show only unread',
+ 'show_adaptive' => 'Adjust showing',
'show_read' => 'Show only read',
'show_favorite' => 'Show only favorites',
'show_not_favorite' => 'Show all but favorites',
@@ -158,6 +160,7 @@ return array (
'save' => 'Save',
'delete' => 'Delete',
'cancel' => 'Cancel',
+ 'submit' => 'Submit',
'back_to_rss_feeds' => '← Go back to your RSS feeds',
'feeds_moved_category_deleted' => 'When you delete a category, their feeds are automatically classified under <em>%s</em>.',
@@ -203,6 +206,7 @@ return array (
'informations' => 'Information',
'damn' => 'Damn!',
'ok' => 'Ok!',
+ 'attention' => 'Be careful!',
'feed_in_error' => 'This feed has encountered a problem. Please verify that it is always reachable then actualize it.',
'feed_empty' => 'This feed is empty. Please verify that it is still maintained.',
'feed_description' => 'Description',
@@ -254,6 +258,7 @@ return array (
'users_list' => 'List of users',
'create_user' => 'Create new user',
'username' => 'Username',
+ 'username_admin' => 'Administrator username',
'password' => 'Password',
'create' => 'Create',
'user_created' => 'User %s has been created',
@@ -269,7 +274,9 @@ return array (
'reading_configuration' => 'Reading',
'display_configuration' => 'Display',
'articles_per_page' => 'Number of articles per page',
+ 'number_divided_when_unfolded' => 'Divided by 2 during loading of unfolded articles.',
'default_view' => 'Default view',
+ 'articles_to_display' => 'Articles to display',
'sort_order' => 'Sort order',
'auto_load_more' => 'Load next articles at the page bottom',
'display_articles_unfolded' => 'Show articles unfolded by default',
@@ -427,9 +434,17 @@ return array (
'update_system' => 'Update system',
'update_check' => 'Check for new updates',
'update_last' => 'Last verification: %s',
- 'update_can_apply' => 'There is an available update. <a class="btn" href="%s">Apply</a>',
+ 'update_can_apply' => 'An update is available.',
+ 'update_apply' => 'Apply',
'update_server_not_found' => 'Update server cannot be found. [%s]',
'no_update' => 'No update to apply',
- 'update_problem' => 'Update has encountered an error: %s',
- 'update_finished' => 'Update is now finished!',
+ 'update_problem' => 'The update process has encountered an error: %s',
+ 'update_finished' => 'Update completed!',
+
+ 'auth_reset' => 'Authentication reset',
+ 'auth_will_reset' => 'Authentication system will be reseted: form will be used instead of Persona.',
+ 'auth_not_persona' => 'Only Persona system can be reseted.',
+ 'auth_no_password_set' => 'Administrator password hasn’t been set. This feature isn’t available.',
+ 'auth_form_set' => 'Form is now your default authentication system.',
+ 'auth_form_not_set' => 'A problem occured during authentication system configuration. Please retry later.',
);
diff --git a/app/i18n/fr.php b/app/i18n/fr.php
index d6c0118e7..4af819cac 100644
--- a/app/i18n/fr.php
+++ b/app/i18n/fr.php
@@ -5,6 +5,7 @@ return array (
'login' => 'Connexion',
'keep_logged_in' => 'Rester connecté <small>(1 mois)</small>',
'login_with_persona' => 'Connexion avec Persona',
+ 'login_persona_problem' => 'Problème de connexion à Persona ?',
'logout' => 'Déconnexion',
'search' => 'Rechercher des mots ou des #tags',
'search_short' => 'Rechercher',
@@ -92,6 +93,7 @@ return array (
'rss_view' => 'Flux RSS',
'show_all_articles' => 'Afficher tous les articles',
'show_not_reads' => 'Afficher les non lus',
+ 'show_adaptive' => 'Adapter l’affichage',
'show_read' => 'Afficher les lus',
'show_favorite' => 'Afficher les favoris',
'show_not_favorite' => 'Afficher tout sauf les favoris',
@@ -158,6 +160,7 @@ return array (
'save' => 'Enregistrer',
'delete' => 'Supprimer',
'cancel' => 'Annuler',
+ 'submit' => 'Valider',
'back_to_rss_feeds' => '← Retour à vos flux RSS',
'feeds_moved_category_deleted' => 'Lors de la suppression d’une catégorie, ses flux seront automatiquement classés dans <em>%s</em>.',
@@ -203,6 +206,7 @@ return array (
'informations' => 'Informations',
'damn' => 'Arf !',
'ok' => 'Ok !',
+ 'attention' => 'Attention !',
'feed_in_error' => 'Ce flux a rencontré un problème. Veuillez vérifier qu’il est toujours accessible puis actualisez-le.',
'feed_empty' => 'Ce flux est vide. Veuillez vérifier qu’il est toujours maintenu.',
'feed_description' => 'Description',
@@ -254,6 +258,7 @@ return array (
'users_list' => 'Liste des utilisateurs',
'create_user' => 'Créer un nouvel utilisateur',
'username' => 'Nom d’utilisateur',
+ 'username_admin' => 'Nom d’utilisateur administrateur',
'password' => 'Mot de passe',
'create' => 'Créer',
'user_created' => 'L’utilisateur %s a été créé.',
@@ -269,7 +274,9 @@ return array (
'reading_configuration' => 'Lecture',
'display_configuration' => 'Affichage',
'articles_per_page' => 'Nombre d’articles par page',
+ 'number_divided_when_unfolded' => 'Divisé par 2 lors du chargement d’articles dépliés.',
'default_view' => 'Vue par défaut',
+ 'articles_to_display' => 'Articles à afficher',
'sort_order' => 'Ordre de tri',
'auto_load_more' => 'Charger les articles suivants en bas de page',
'display_articles_unfolded' => 'Afficher les articles dépliés par défaut',
@@ -427,9 +434,17 @@ return array (
'update_system' => 'Système de mise à jour',
'update_check' => 'Vérifier les mises à jour',
'update_last' => 'Dernière vérification : %s',
- 'update_can_apply' => 'Il y’a une mise à jour à appliquer. <a class="btn" href="%s">Appliquer la mise à jour</a>',
+ 'update_can_apply' => 'Une mise à jour est disponible.',
+ 'update_apply' => 'Appliquer la mise à jour',
'update_server_not_found' => 'Le serveur de mise à jour n’a pas été trouvé. [%s]',
'no_update' => 'Aucune mise à jour à appliquer',
'update_problem' => 'La mise à jour a rencontré un problème : %s',
'update_finished' => 'La mise à jour est terminée !',
+
+ 'auth_reset' => 'Reset de l’authentification',
+ 'auth_will_reset' => 'Le système d’authentification va être remis à zéro : le formulaire sera utilisé à la place de Persona.',
+ 'auth_not_persona' => 'Seul le système d’authentification Persona peut être remis à zéro.',
+ 'auth_no_password_set' => 'Aucun mot de passe administrateur n’a été précisé. Cette fonctionnalité n’est pas disponible.',
+ 'auth_form_set' => 'Le formulaire est désormais votre système d’authentification.',
+ 'auth_form_not_set' => 'Un problème est survenu lors de la configuration de votre système d’authentification. Veuillez réessayer plus tard.',
);
diff --git a/app/i18n/install.en.php b/app/i18n/install.en.php
index 50208fcef..c422de90f 100644
--- a/app/i18n/install.en.php
+++ b/app/i18n/install.en.php
@@ -42,6 +42,8 @@ return array (
'data_is_ok' => 'Permissions on data directory are good',
'persona_is_ok' => 'Permissions on Mozilla Persona directory are good',
'file_is_nok' => 'Check permissions on <em>%s</em> directory. HTTP server must have rights to write into',
+ 'http_referer_is_ok' => 'Your HTTP REFERER is known and corresponds to your server.',
+ 'http_referer_is_nok' => 'Please check that you are not altering your HTTP REFERER.',
'fix_errors_before' => 'Fix errors before skip to the next step.',
'general_conf_is_ok' => 'General configuration has been saved.',
diff --git a/app/i18n/install.fr.php b/app/i18n/install.fr.php
index 9c039f904..785c02459 100644
--- a/app/i18n/install.fr.php
+++ b/app/i18n/install.fr.php
@@ -42,6 +42,8 @@ return array (
'data_is_ok' => 'Les droits sur le répertoire de data sont bons',
'persona_is_ok' => 'Les droits sur le répertoire de Mozilla Persona sont bons',
'file_is_nok' => 'Veuillez vérifier les droits sur le répertoire <em>%s</em>. Le serveur HTTP doit être capable d’écrire dedans',
+ 'http_referer_is_ok' => 'Le HTTP REFERER est connu et semble correspondre à votre serveur.',
+ 'http_referer_is_nok' => 'Veuillez vérifier que vous ne modifiez pas votre HTTP REFERER.',
'fix_errors_before' => 'Veuillez corriger les erreurs avant de passer à l’étape suivante.',
'general_conf_is_ok' => 'La configuration générale a été enregistrée.',
diff --git a/app/install.php b/app/install.php
index 8986e9965..4449cd063 100644
--- a/app/install.php
+++ b/app/install.php
@@ -149,7 +149,7 @@ function saveStep2() {
$config_array = array(
'language' => $_SESSION['language'],
- 'theme' => $_SESSION['theme'],
+ 'theme' => 'Origine',
'old_entries' => $_SESSION['old_entries'],
'mail_login' => $_SESSION['mail_login'],
'passwordHash' => $_SESSION['passwordHash'],
@@ -307,6 +307,7 @@ function checkStep1() {
$log = LOG_PATH && is_writable(LOG_PATH);
$favicons = is_writable(DATA_PATH . '/favicons');
$persona = is_writable(DATA_PATH . '/persona');
+ $http_referer = is_referer_from_same_domain();
return array(
'php' => $php ? 'ok' : 'ko',
@@ -323,8 +324,10 @@ function checkStep1() {
'log' => $log ? 'ok' : 'ko',
'favicons' => $favicons ? 'ok' : 'ko',
'persona' => $persona ? 'ok' : 'ko',
+ 'http_referer' => $http_referer ? 'ok' : 'ko',
'all' => $php && $minz && $curl && $pdo && $pcre && $ctype && $dom &&
- $data && $cache && $log && $favicons && $persona ? 'ok' : 'ko'
+ $data && $cache && $log && $favicons && $persona && $http_referer ?
+ 'ok' : 'ko'
);
}
@@ -334,9 +337,15 @@ function checkStep2() {
isset($_SESSION['mail_login']) &&
!empty($_SESSION['default_user']);
- $form = $_SESSION['auth_type'] != 'form' || !empty($_SESSION['passwordHash']);
+ $form = (
+ isset($_SESSION['auth_type']) &&
+ ($_SESSION['auth_type'] != 'form' || !empty($_SESSION['passwordHash']))
+ );
- $persona = $_SESSION['auth_type'] != 'persona' || !empty($_SESSION['mail_login']);
+ $persona = (
+ isset($_SESSION['auth_type']) &&
+ ($_SESSION['auth_type'] != 'persona' || !empty($_SESSION['mail_login']))
+ );
$defaultUser = empty($_POST['default_user']) ? null : $_POST['default_user'];
if ($defaultUser === null) {
@@ -548,6 +557,12 @@ function printStep1() {
<p class="alert alert-error"><span class="alert-head"><?php echo _t('damn'); ?></span> <?php echo _t('file_is_nok', DATA_PATH . '/persona'); ?></p>
<?php } ?>
+ <?php if ($res['http_referer'] == 'ok') { ?>
+ <p class="alert alert-success"><span class="alert-head"><?php echo _t('ok'); ?></span> <?php echo _t('http_referer_is_ok'); ?></p>
+ <?php } else { ?>
+ <p class="alert alert-error"><span class="alert-head"><?php echo _t('damn'); ?></span> <?php echo _t('http_referer_is_nok'); ?></p>
+ <?php } ?>
+
<?php if ($res['all'] == 'ok') { ?>
<a class="btn btn-important next-step" href="?step=2"><?php echo _t('next_step'); ?></a>
<?php } else { ?>
@@ -591,16 +606,17 @@ function printStep2() {
<div class="form-group">
<label class="group-name" for="auth_type"><?php echo _t('auth_type'); ?></label>
<div class="group-controls">
- <select id="auth_type" name="auth_type" required="required" onchange="auth_type_change()">
+ <select id="auth_type" name="auth_type" required="required" onchange="auth_type_change(true)">
<?php
- function no_auth() {
- return !in_array($_SESSION['auth_type'], array('form', 'persona', 'http_auth', 'none'));
+ function no_auth($auth_type) {
+ return !in_array($auth_type, array('form', 'persona', 'http_auth', 'none'));
}
+ $auth_type = isset($_SESSION['auth_type']) ? $_SESSION['auth_type'] : '';
?>
- <option value="form"<?php echo $_SESSION['auth_type'] === 'form' || no_auth() ? ' selected="selected"' : '', cryptAvailable() ? '' : ' disabled="disabled"'; ?>><?php echo _t('auth_form'); ?></option>
- <option value="persona"<?php echo $_SESSION['auth_type'] === 'persona' ? ' selected="selected"' : ''; ?>><?php echo _t('auth_persona'); ?></option>
- <option value="http_auth"<?php echo $_SESSION['auth_type'] === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>><?php echo _t('http_auth'); ?>(REMOTE_USER = '<?php echo httpAuthUser(); ?>')</option>
- <option value="none"<?php echo $_SESSION['auth_type'] === 'none' ? ' selected="selected"' : ''; ?>><?php echo _t('auth_none'); ?></option>
+ <option value="form"<?php echo $auth_type === 'form' || no_auth($auth_type) ? ' selected="selected"' : '', cryptAvailable() ? '' : ' disabled="disabled"'; ?>><?php echo _t('auth_form'); ?></option>
+ <option value="persona"<?php echo $auth_type === 'persona' ? ' selected="selected"' : ''; ?>><?php echo _t('auth_persona'); ?></option>
+ <option value="http_auth"<?php echo $auth_type === 'http_auth' ? ' selected="selected"' : '', httpAuthUser() == '' ? ' disabled="disabled"' : ''; ?>><?php echo _t('http_auth'); ?>(REMOTE_USER = '<?php echo httpAuthUser(); ?>')</option>
+ <option value="none"<?php echo $auth_type === 'none' ? ' selected="selected"' : ''; ?>><?php echo _t('auth_none'); ?></option>
</select>
</div>
</div>
@@ -609,7 +625,7 @@ function printStep2() {
<label class="group-name" for="passwordPlain"><?php echo _t('password_form'); ?></label>
<div class="group-controls">
<div class="stick">
- <input type="password" id="passwordPlain" name="passwordPlain" pattern=".{7,}" autocomplete="off" <?php echo $_SESSION['auth_type'] === 'form' ? ' required="required"' : ''; ?> />
+ <input type="password" id="passwordPlain" name="passwordPlain" pattern=".{7,}" autocomplete="off" <?php echo $auth_type === 'form' ? ' required="required"' : ''; ?> />
<a class="btn toggle-password" data-toggle="passwordPlain"><?php echo FreshRSS_Themes::icon('key'); ?></a>
</div>
<noscript><b><?php echo _t('javascript_should_be_activated'); ?></b></noscript>
@@ -619,7 +635,7 @@ function printStep2() {
<div class="form-group">
<label class="group-name" for="mail_login"><?php echo _t('persona_connection_email'); ?></label>
<div class="group-controls">
- <input type="email" id="mail_login" name="mail_login" value="<?php echo isset($_SESSION['mail_login']) ? $_SESSION['mail_login'] : ''; ?>" placeholder="alice@example.net" <?php echo $_SESSION['auth_type'] === 'persona' ? ' required="required"' : ''; ?> />
+ <input type="email" id="mail_login" name="mail_login" value="<?php echo isset($_SESSION['mail_login']) ? $_SESSION['mail_login'] : ''; ?>" placeholder="alice@example.net" <?php echo $auth_type === 'persona' ? ' required="required"' : ''; ?> />
<noscript><b><?php echo _t('javascript_should_be_activated'); ?></b></noscript>
</div>
</div>
@@ -644,7 +660,7 @@ function printStep2() {
toggles[i].addEventListener('click', toggle_password);
}
- function auth_type_change() {
+ function auth_type_change(focus) {
var auth_value = document.getElementById('auth_type').value,
password_input = document.getElementById('passwordPlain'),
mail_input = document.getElementById('mail_login');
@@ -652,15 +668,21 @@ function printStep2() {
if (auth_value === 'form') {
password_input.required = true;
mail_input.required = false;
+ if (focus) {
+ password_input.focus();
+ }
} else if (auth_value === 'persona') {
password_input.required = false;
mail_input.required = true;
+ if (focus) {
+ mail_input.focus();
+ }
} else {
password_input.required = false;
mail_input.required = false;
}
}
- auth_type_change();
+ auth_type_change(false);
</script>
<div class="form-group form-actions">
diff --git a/app/layout/aside_configure.phtml b/app/layout/aside_configure.phtml
index 03bea4836..d5c9bf4c9 100644
--- a/app/layout/aside_configure.phtml
+++ b/app/layout/aside_configure.phtml
@@ -1,32 +1,32 @@
<ul class="nav nav-list aside">
<li class="nav-header"><?php echo _t('configuration'); ?></li>
- <li class="item<?php echo Minz_Request::actionName() == 'display' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::actionName() === 'display' ? ' active' : ''; ?>">
<a href="<?php echo _url('configure', 'display'); ?>"><?php echo _t('display_configuration'); ?></a>
</li>
- <li class="item<?php echo Minz_Request::actionName() == 'reading' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::actionName() === 'reading' ? ' active' : ''; ?>">
<a href="<?php echo _url('configure', 'reading'); ?>"><?php echo _t('reading_configuration'); ?></a>
</li>
- <li class="item<?php echo Minz_Request::actionName() == 'archiving' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::actionName() === 'archiving' ? ' active' : ''; ?>">
<a href="<?php echo _url('configure', 'archiving'); ?>"><?php echo _t('archiving_configuration'); ?></a>
</li>
- <li class="item<?php echo Minz_Request::actionName() == 'sharing' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::actionName() === 'sharing' ? ' active' : ''; ?>">
<a href="<?php echo _url('configure', 'sharing'); ?>"><?php echo _t('sharing'); ?></a>
</li>
- <li class="item<?php echo Minz_Request::actionName() == 'shortcut' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::actionName() === 'shortcut' ? ' active' : ''; ?>">
<a href="<?php echo _url('configure', 'shortcut'); ?>"><?php echo _t('shortcuts'); ?></a>
</li>
- <li class="item<?php echo Minz_Request::actionName() == 'queries' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::actionName() === 'queries' ? ' active' : ''; ?>">
<a href="<?php echo _url('configure', 'queries'); ?>"><?php echo _t('queries'); ?></a>
</li>
<li class="separator"></li>
- <li class="item<?php echo Minz_Request::actionName() == 'users' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::actionName() === 'users' ? ' active' : ''; ?>">
<a href="<?php echo _url('configure', 'users'); ?>"><?php echo _t('users'); ?></a>
</li>
<?php
$current_user = Minz_Session::param('currentUser', '');
if (Minz_Configuration::isAdmin($current_user)) {
?>
- <li class="item<?php echo Minz_Request::controllerName() == 'update' ? ' active' : ''; ?>">
+ <li class="item<?php echo Minz_Request::controllerName() === 'update' ? ' active' : ''; ?>">
<a href="<?php echo _url('update', 'index'); ?>"><?php echo _t('update'); ?></a>
</li>
<?php } ?>
diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml
index 96a88d245..f95f45b5e 100644
--- a/app/layout/layout.phtml
+++ b/app/layout/layout.phtml
@@ -13,6 +13,7 @@
if (!empty($this->nextId)) {
$params = Minz_Request::params();
$params['next'] = $this->nextId;
+ $params['ajax'] = 1;
?>
<link id="prefetch" rel="next prefetch" href="<?php echo Minz_Url::display(array('c' => Minz_Request::controllerName(), 'a' => Minz_Request::actionName(), 'params' => $params)); ?>" />
<?php } ?>
diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml
index 5a26501a4..3dd457a2b 100644
--- a/app/views/configure/reading.phtml
+++ b/app/views/configure/reading.phtml
@@ -10,6 +10,9 @@
<label class="group-name" for="posts_per_page"><?php echo Minz_Translate::t ('articles_per_page'); ?></label>
<div class="group-controls">
<input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->posts_per_page; ?>" min="5" max="50" />
+ <?php if ($this->conf->display_posts) { ?>
+ <?php echo _i('help'); ?> <?php echo _t('number_divided_when_unfolded'); ?>
+ <?php } ?>
</div>
</div>
@@ -31,14 +34,17 @@
<option value="reader"<?php echo $this->conf->view_mode === 'reader' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('reader_view'); ?></option>
<option value="global"<?php echo $this->conf->view_mode === 'global' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('global_view'); ?></option>
</select>
- <label class="radio" for="radio_all">
- <input type="radio" name="default_view" id="radio_all" value="<?php echo FreshRSS_Entry::STATE_ALL; ?>"<?php echo $this->conf->default_view === FreshRSS_Entry::STATE_ALL ? ' checked="checked"' : ''; ?> />
- <?php echo Minz_Translate::t ('show_all_articles'); ?>
- </label>
- <label class="radio" for="radio_not_read">
- <input type="radio" name="default_view" id="radio_not_read" value="<?php echo FreshRSS_Entry::STATE_NOT_READ; ?>"<?php echo $this->conf->default_view === FreshRSS_Entry::STATE_NOT_READ ? ' checked="checked"' : ''; ?> />
- <?php echo Minz_Translate::t ('show_not_reads'); ?>
- </label>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label class="group-name" for="view_mode"><?php echo _t('articles_to_display'); ?></label>
+ <div class="group-controls">
+ <select name="default_view" id="default_view">
+ <option value="<?php echo FreshRSS_Entry::STATE_NOT_READ; ?>"<?php echo $this->conf->default_view === FreshRSS_Entry::STATE_NOT_READ ? ' selected="selected"' : ''; ?>><?php echo _t('show_adaptive'); ?></option>
+ <option value="<?php echo FreshRSS_Entry::STATE_ALL; ?>"<?php echo $this->conf->default_view === FreshRSS_Entry::STATE_ALL ? ' selected="selected"' : ''; ?>><?php echo _t('show_all_articles'); ?></option>
+ <option value="<?php echo FreshRSS_Entry::STATE_NOT_READ_STRICT; ?>"<?php echo $this->conf->default_view === FreshRSS_Entry::STATE_NOT_READ_STRICT ? ' selected="selected"' : ''; ?>><?php echo _t('show_not_reads'); ?></option>
+ </select>
</div>
</div>
diff --git a/app/views/helpers/pagination.phtml b/app/views/helpers/pagination.phtml
index f6fcbc701..1b15cc632 100755
--- a/app/views/helpers/pagination.phtml
+++ b/app/views/helpers/pagination.phtml
@@ -9,7 +9,10 @@
<ul class="pagination">
<li class="item pager-next">
<?php if (!empty($this->nextId)) { ?>
- <?php $params['next'] = $this->nextId; ?>
+ <?php
+ $params['next'] = $this->nextId;
+ $params['ajax'] = 1;
+ ?>
<a id="load_more" href="<?php echo Minz_Url::display(array('c' => $c, 'a' => $a, 'params' => $params)); ?>">
<?php echo _t('load_more'); ?>
</a>
diff --git a/app/views/index/formLogin.phtml b/app/views/index/formLogin.phtml
index b79c1b614..b05cdced4 100644
--- a/app/views/index/formLogin.phtml
+++ b/app/views/index/formLogin.phtml
@@ -3,7 +3,7 @@
switch (Minz_Configuration::authType()) {
case 'form':
- ?><form id="loginForm" method="post" action="<?php echo _url('index', 'formLogin'); ?>">
+ ?><form id="crypto-form" method="post" action="<?php echo _url('index', 'formLogin'); ?>">
<div>
<label for="username"><?php echo _t('username'); ?></label>
<input type="text" id="username" name="username" size="16" required="required" maxlength="16" pattern="[0-9a-zA-Z]{1,16}" autofocus="autofocus" />
@@ -29,8 +29,15 @@
case 'persona':
?><p>
- <?php echo _i('login'); ?>
- <a class="signin" href="#"><?php echo _t('login_with_persona'); ?></a>
+ <a class="signin btn btn-important" href="#">
+ <?php echo _i('login'); ?>
+ <?php echo _t('login_with_persona'); ?>
+ </a><br /><br />
+
+ <?php echo _i('help'); ?>
+ <small>
+ <a href="<?php echo _url('index', 'resetAuth'); ?>"><?php echo _t('login_persona_problem'); ?></a>
+ </small>
</p><?php
break;
} ?>
diff --git a/app/views/index/resetAuth.phtml b/app/views/index/resetAuth.phtml
new file mode 100644
index 000000000..6d4282c14
--- /dev/null
+++ b/app/views/index/resetAuth.phtml
@@ -0,0 +1,33 @@
+<div class="prompt">
+ <h1><?php echo _t('auth_reset'); ?></h1>
+
+ <?php if (!empty($this->message)) { ?>
+ <p class="alert <?php echo $this->message['status'] === 'bad' ? 'alert-error' : 'alert-warn'; ?>">
+ <span class="alert-head"><?php echo $this->message['title']; ?></span><br />
+ <?php echo $this->message['body']; ?>
+ </p>
+ <?php } ?>
+
+ <?php if (!$this->no_form) { ?>
+ <form id="crypto-form" method="post" action="<?php echo _url('index', 'resetAuth'); ?>">
+ <p class="alert alert-warn">
+ <span class="alert-head"><?php echo _t('attention'); ?></span><br />
+ <?php echo _t('auth_will_reset'); ?>
+ </p>
+
+ <div>
+ <label for="username"><?php echo _t('username_admin'); ?></label>
+ <input type="text" id="username" name="username" size="16" required="required" maxlength="16" pattern="[0-9a-zA-Z]{1,16}" autofocus="autofocus" />
+ </div>
+ <div>
+ <label for="passwordPlain"><?php echo _t('password'); ?></label>
+ <input type="password" id="passwordPlain" required="required" />
+ <input type="hidden" id="challenge" name="challenge" /><br />
+ <noscript><strong><?php echo _t('javascript_should_be_activated'); ?></strong></noscript>
+ </div>
+ <div>
+ <button id="loginButton" type="submit" class="btn btn-important"><?php echo _t('submit'); ?></button>
+ </div>
+ </form>
+ <?php } ?>
+</div>
diff --git a/app/views/stats/idle.phtml b/app/views/stats/idle.phtml
index 2ba5237f7..608e2d33c 100644
--- a/app/views/stats/idle.phtml
+++ b/app/views/stats/idle.phtml
@@ -1,6 +1,6 @@
<?php $this->partial('aside_stats'); ?>
-<div class="post content">
+<div class="post">
<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('back_to_rss_feeds'); ?></a>
<h1><?php echo _t('stats_idle'); ?></h1>
@@ -12,11 +12,20 @@
<div class="stat">
<h2><?php echo _t($period); ?></h2>
- <ul>
- <?php foreach ($feeds as $feed) { ?>
- <li><a href="<?php echo _url('configure', 'feed', 'id', $feed['id']); ?>" title="<?php echo date('Y-m-d', $feed['last_date']); ?>"><?php echo $feed['name']; ?></a></li>
- <?php } ?>
+ <form id="form-delete" method="post" style="display: none"></form>
+
+ <?php foreach ($feeds as $feed) { ?>
+ <ul class="horizontal-list">
+ <li class="item">
+ <div class="stick">
+ <a class="btn" href="<?php echo _url('index', 'index', 'get', 'f_' . $feed['id']); ?>"><?php echo _i('link'); ?> <?php echo _t('filter'); ?></a>
+ <a class="btn" href="<?php echo _url('configure', 'feed', 'id', $feed['id']); ?>"><?php echo _i('configure'); ?> <?php echo _t('administration'); ?></a>
+ <button class="btn btn-attention confirm" form="form-delete" formaction="<?php echo _url('feed', 'delete', 'id', $feed['id']); ?>"><?php echo _t('delete'); ?></button>
+ </div>
+ </li>
+ <li class="item"><span title="<?php echo timestamptodate($feed['last_date'], false); ?>"><?php echo $feed['name']; ?></span></li>
</ul>
+ <?php } ?>
</div>
<?php
}
diff --git a/app/views/stats/index.phtml b/app/views/stats/index.phtml
index a48181fe4..46cdc2a8b 100644
--- a/app/views/stats/index.phtml
+++ b/app/views/stats/index.phtml
@@ -1,11 +1,11 @@
<?php $this->partial('aside_stats'); ?>
-<div class="post content">
+<div class="post">
<a href="<?php echo _url ('index', 'index'); ?>"><?php echo _t ('back_to_rss_feeds'); ?></a>
-
+
<h1><?php echo _t ('stats_main'); ?></h1>
- <div class="stat">
+ <div class="stat half">
<h2><?php echo _t ('stats_entry_repartition'); ?></h2>
<table>
<thead>
@@ -38,26 +38,9 @@
</tr>
</tbody>
</table>
- </div>
-
- <div class="stat">
- <h2><?php echo _t ('stats_entry_per_day'); ?></h2>
- <div id="statsEntryPerDay" style="height: 300px"></div>
- </div>
-
- <div class="stat">
- <h2><?php echo _t ('stats_feed_per_category'); ?></h2>
- <div id="statsFeedPerCategory" style="height: 300px"></div>
- <div id="statsFeedPerCategoryLegend"></div>
- </div>
-
- <div class="stat">
- <h2><?php echo _t ('stats_entry_per_category'); ?></h2>
- <div id="statsEntryPerCategory" style="height: 300px"></div>
- <div id="statsEntryPerCategoryLegend"></div>
- </div>
-
- <div class="stat">
+ </div><!--
+
+ --><div class="stat half">
<h2><?php echo _t ('stats_top_feed'); ?></h2>
<table>
<thead>
@@ -78,6 +61,23 @@
</tbody>
</table>
</div>
+
+ <div class="stat">
+ <h2><?php echo _t ('stats_entry_per_day'); ?></h2>
+ <div id="statsEntryPerDay" style="height: 300px"></div>
+ </div>
+
+ <div class="stat half">
+ <h2><?php echo _t ('stats_feed_per_category'); ?></h2>
+ <div id="statsFeedPerCategory" style="height: 300px"></div>
+ <div id="statsFeedPerCategoryLegend"></div>
+ </div><!--
+
+ --><div class="stat half">
+ <h2><?php echo _t ('stats_entry_per_category'); ?></h2>
+ <div id="statsEntryPerCategory" style="height: 300px"></div>
+ <div id="statsEntryPerCategoryLegend"></div>
+ </div>
</div>
<script>
diff --git a/app/views/stats/repartition.phtml b/app/views/stats/repartition.phtml
index d9dc4c89d..ead275696 100644
--- a/app/views/stats/repartition.phtml
+++ b/app/views/stats/repartition.phtml
@@ -1,6 +1,6 @@
<?php $this->partial('aside_stats'); ?>
-<div class="post content">
+<div class="post ">
<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('back_to_rss_feeds'); ?></a>
<h1><?php echo _t('stats_repartition'); ?></h1>
@@ -34,12 +34,12 @@
<div id="statsEntryPerHour" style="height: 300px"></div>
</div>
- <div class="stat">
+ <div class="stat half">
<h2><?php echo _t('stats_entry_per_day_of_week'); ?></h2>
<div id="statsEntryPerDayOfWeek" style="height: 300px"></div>
- </div>
+ </div><!--
- <div class="stat">
+ --><div class="stat half">
<h2><?php echo _t('stats_entry_per_month'); ?></h2>
<div id="statsEntryPerMonth" style="height: 300px"></div>
</div>
diff --git a/app/views/update/index.phtml b/app/views/update/index.phtml
index 5be8b1e8b..401f6acd6 100644
--- a/app/views/update/index.phtml
+++ b/app/views/update/index.phtml
@@ -29,4 +29,8 @@
<a href="<?php echo _url('update', 'check'); ?>" class="btn"><?php echo _t('update_check'); ?></a>
</p>
<?php } ?>
+
+ <?php if ($this->update_to_apply) { ?>
+ <a class="btn btn-important" href="<?php echo _url('update', 'apply'); ?>"><?php echo _t('update_apply'); ?></a>
+ <?php } ?>
</div>
diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php
index ec4e25a6b..52f53012f 100644
--- a/lib/Minz/Request.php
+++ b/lib/Minz/Request.php
@@ -84,20 +84,6 @@ class Minz_Request {
return $_SERVER['HTTP_HOST'];
}
- public static function isRefererFromSameDomain() {
- if (empty($_SERVER['HTTP_REFERER'])) {
- return false;
- }
- $host = parse_url(((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://') .
- (empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']));
- $referer = parse_url($_SERVER['HTTP_REFERER']);
- if (empty($host['scheme']) || empty($referer['scheme']) || $host['scheme'] !== $referer['scheme'] ||
- empty($host['host']) || empty($referer['host']) || $host['host'] !== $referer['host']) {
- return false;
- }
- return (isset($host['port']) ? $host['port'] : 0) === (isset($referer['port']) ? $referer['port'] : 0);
- }
-
/**
* Détermine la base de l'url
* @return la base de l'url
diff --git a/lib/lib_rss.php b/lib/lib_rss.php
index 823f53716..31c9cdbc1 100644
--- a/lib/lib_rss.php
+++ b/lib/lib_rss.php
@@ -230,3 +230,17 @@ function cryptAvailable() {
}
return false;
}
+
+function is_referer_from_same_domain() {
+ if (empty($_SERVER['HTTP_REFERER'])) {
+ return false;
+ }
+ $host = parse_url(((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https://' : 'http://') .
+ (empty($_SERVER['HTTP_HOST']) ? $_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']));
+ $referer = parse_url($_SERVER['HTTP_REFERER']);
+ if (empty($host['scheme']) || empty($referer['scheme']) || $host['scheme'] !== $referer['scheme'] ||
+ empty($host['host']) || empty($referer['host']) || $host['host'] !== $referer['host']) {
+ return false;
+ }
+ return (isset($host['port']) ? $host['port'] : 0) === (isset($referer['port']) ? $referer['port'] : 0);
+}
diff --git a/p/scripts/main.js b/p/scripts/main.js
index 9d2d83a32..b2ca90c5b 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -984,7 +984,7 @@ function init_load_more(box) {
}
//</endless_mode>
-//<Web login form>
+//<crypto form (Web login)>
function poormanSalt() { //If crypto.getRandomValues is not available
var text = '$2a$04$',
base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789/abcdefghijklmnopqrstuvwxyz';
@@ -994,20 +994,24 @@ function poormanSalt() { //If crypto.getRandomValues is not available
return text;
}
-function init_loginForm() {
- var $loginForm = $('#loginForm');
- if ($loginForm.length === 0) {
+function init_crypto_form() {
+ var $crypto_form = $('#crypto-form');
+ if ($crypto_form.length === 0) {
return;
}
+
if (!(window.dcodeIO)) {
if (window.console) {
console.log('FreshRSS waiting for bcrypt.js…');
}
- window.setTimeout(init_loginForm, 100);
+ window.setTimeout(init_crypto_form, 100);
return;
}
- $loginForm.on('submit', function() {
- $('#loginButton').attr('disabled', '');
+
+ $crypto_form.on('submit', function() {
+ var $submit_button = $(this).find('button[type="submit"]');
+ $submit_button.attr('disabled', '');
+
var success = false;
$.ajax({
url: './?c=javascript&a=nonce&user=' + $('#username').val(),
@@ -1015,7 +1019,7 @@ function init_loginForm() {
async: false
}).done(function (data) {
if (data.salt1 == '' || data.nonce == '') {
- alert('Invalid user!');
+ openNotification('Invalid user!', 'bad');
} else {
try {
var strong = window.Uint32Array && window.crypto && (typeof window.crypto.getRandomValues === 'function'),
@@ -1023,22 +1027,23 @@ function init_loginForm() {
c = dcodeIO.bcrypt.hashSync(data.nonce + s, strong ? 4 : poormanSalt());
$('#challenge').val(c);
if (s == '' || c == '') {
- alert('Crypto error!');
+ openNotification('Crypto error!', 'bad');
} else {
success = true;
}
} catch (e) {
- alert('Crypto exception! ' + e);
+ openNotification('Crypto exception! ' + e, 'bad');
}
}
}).fail(function() {
- alert('Communication error!');
+ openNotification('Communication error!', 'bad');
});
- $('#loginButton').removeAttr('disabled');
+
+ $submit_button.removeAttr('disabled');
return success;
});
}
-//</Web login form>
+//</crypto form (Web login)>
//<persona>
function init_persona() {
@@ -1240,14 +1245,12 @@ function init_all() {
}
init_notifications();
switch (authType) {
- case 'form':
- init_loginForm();
- break;
case 'persona':
init_persona();
break;
}
init_confirm_action();
+ init_crypto_form();
$stream = $('#stream');
if ($stream.length > 0) {
init_actualize();
diff --git a/p/themes/Dark/dark.css b/p/themes/Dark/dark.css
index 669f4ce42..e47415366 100644
--- a/p/themes/Dark/dark.css
+++ b/p/themes/Dark/dark.css
@@ -872,7 +872,18 @@ a.btn {
.stat > table td,
.stat > table th {
border-bottom: 1px solid #333;
- text-align: center;
+}
+
+.stat > .horizontal-list {
+ margin: 0 0 5px;
+}
+.stat > .horizontal-list .item {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.stat > .horizontal-list .item:first-child {
+ width: 270px;
}
/*=== LOGS */
diff --git a/p/themes/Flat/flat.css b/p/themes/Flat/flat.css
index a942df0e8..41d03c57d 100644
--- a/p/themes/Flat/flat.css
+++ b/p/themes/Flat/flat.css
@@ -859,7 +859,18 @@ a.btn {
.stat > table td,
.stat > table th {
border-bottom: 1px solid #ddd;
- text-align: center;
+}
+
+.stat > .horizontal-list {
+ margin: 0 0 5px;
+}
+.stat > .horizontal-list .item {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.stat > .horizontal-list .item:first-child {
+ width: 270px;
}
/*=== LOGS */
diff --git a/p/themes/Origine/origine.css b/p/themes/Origine/origine.css
index 55ff3fc73..6a4ef9699 100644
--- a/p/themes/Origine/origine.css
+++ b/p/themes/Origine/origine.css
@@ -808,12 +808,12 @@ a.btn {
background: #fafafa;
}
#bigMarkAsRead:hover {
- color: #27ae60;
+ color: #0062be;
background: #fff;
box-shadow: 0 -5px 10px #eee inset;
}
#bigMarkAsRead:hover .bigTick {
- text-shadow: 0 0 5px #27ae60;
+ text-shadow: 0 0 5px #0062be;
}
/*=== Navigation menu (for articles) */
@@ -913,7 +913,18 @@ a.btn {
.stat > table td,
.stat > table th {
border-bottom: 1px solid #ddd;
- text-align: center;
+}
+
+.stat > .horizontal-list {
+ margin: 0 0 5px;
+}
+.stat > .horizontal-list .item {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.stat > .horizontal-list .item:first-child {
+ width: 270px;
}
/*=== LOGS */
diff --git a/p/themes/Screwdriver/screwdriver.css b/p/themes/Screwdriver/screwdriver.css
index 1d84753c7..c96d4bfe3 100644
--- a/p/themes/Screwdriver/screwdriver.css
+++ b/p/themes/Screwdriver/screwdriver.css
@@ -1025,7 +1025,18 @@ opacity: 1;
border-bottom: 1px solid #ccc;
background: rgba(255,255,255,0.38);
box-shadow: 0 1px #fff;
- text-align: center;
+}
+
+.stat > .horizontal-list {
+ margin: 0 0 5px;
+}
+.stat > .horizontal-list .item {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.stat > .horizontal-list .item:first-child {
+ width: 250px;
}
/*=== LOGS */
diff --git a/p/themes/base-theme/base.css b/p/themes/base-theme/base.css
index b49cd79ea..1688a6f79 100644
--- a/p/themes/base-theme/base.css
+++ b/p/themes/base-theme/base.css
@@ -678,6 +678,18 @@ a.btn {
text-align: center;
}
+.stat > .horizontal-list {
+ margin: 0 0 5px;
+}
+.stat > .horizontal-list .item {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.stat > .horizontal-list .item:first-child {
+ width: 250px;
+}
+
/*=== LOGS */
/*=========*/
.logs {
diff --git a/p/themes/base-theme/template.css b/p/themes/base-theme/template.css
index f05ddff4e..0f00632ee 100644
--- a/p/themes/base-theme/template.css
+++ b/p/themes/base-theme/template.css
@@ -98,6 +98,15 @@ button.as-link:active {
font-size: 1.1em;
}
+/*=== Tables */
+table {
+ max-width: 100%;
+}
+th.numeric,
+td.numeric {
+ text-align: center;
+}
+
/*=== COMPONENTS */
/*===============*/
/*=== Forms */
@@ -458,6 +467,12 @@ a.btn {
.content pre {
overflow: auto;
}
+br {
+ line-height: 1em;
+}
+br + br + br {
+ display: none;
+}
/*=== Notification and actualize notification */
.notification {
@@ -526,6 +541,14 @@ a.btn {
}
/*=== Statistiques */
+.stat {
+ margin: 15px 0;
+}
+.stat.half {
+ display: inline-block;
+ width: 46%;
+ padding: 0 2%;
+}
.stat > table {
width: 100%;
}