aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2019-08-29 12:02:05 +0200
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2019-08-29 12:02:05 +0200
commit75632e70f0d49048f4ce72a0fa8bbcbcd7b2d312 (patch)
tree09c2f637ceedb76a30ad833555f02c2d50ee4863 /app
parentad44ff81694ff4cbcccc514a17351476a38aadd8 (diff)
Provide email address verification feature (#2481)
* Add an email field to the profile page I reuse the `mail_login` from the configuration. I'm not sure if it's useful today (I would say it was used when Persona login was available). A good improvement would be to rename `mail_login` into `email` so it would be more intuitive to use. * Add boolean to the conf to force email validation This commit only adds a configuration item. * Add email during registration if email must be validated * Set email token to validate when email changes * Block access to FreshRSS if email is not validated * Send email when address is changed * Allow to resend the validation email * Allow the user to change its email while blocked * Document the email validation feature * fixup! Allow the user to change its email while blocked * tec: Autoload PHPMailer lib * Validate email address format * Add feedback on validation email resend action * Allow to logout when user is blocked * fix: Change default email "from" * Reorganize i18n keys * Complete all the locales with default english * Hide sidebar (profile page) if email is not validated * Check email requirements on registration * Allow admin to specify email when creating users * Don't check email format if value is empty * Remove trailing comma in userController Co-Authored-By: Alexandre Alapetite <alexandre@alapetite.fr> * Set PHPMailer validator to html5 before sending email * fixup! Remove trailing comma in userController
Diffstat (limited to 'app')
-rw-r--r--app/Controllers/authController.php1
-rwxr-xr-xapp/Controllers/configureController.php12
-rw-r--r--app/Controllers/userController.php195
-rw-r--r--app/FreshRSS.php18
-rw-r--r--app/Mailers/UserMailer.php31
-rw-r--r--app/Models/ConfigurationSetter.php4
-rw-r--r--app/i18n/cz/admin.php1
-rw-r--r--app/i18n/cz/conf.php1
-rw-r--r--app/i18n/cz/gen.php1
-rw-r--r--app/i18n/cz/user.php32
-rw-r--r--app/i18n/de/admin.php1
-rw-r--r--app/i18n/de/conf.php1
-rw-r--r--app/i18n/de/gen.php1
-rw-r--r--app/i18n/de/user.php32
-rw-r--r--app/i18n/en/admin.php1
-rw-r--r--app/i18n/en/conf.php1
-rw-r--r--app/i18n/en/gen.php1
-rw-r--r--app/i18n/en/user.php32
-rwxr-xr-xapp/i18n/es/admin.php1
-rwxr-xr-xapp/i18n/es/conf.php1
-rwxr-xr-xapp/i18n/es/gen.php1
-rw-r--r--app/i18n/es/user.php32
-rw-r--r--app/i18n/fr/admin.php1
-rw-r--r--app/i18n/fr/conf.php1
-rw-r--r--app/i18n/fr/gen.php1
-rw-r--r--app/i18n/fr/user.php32
-rw-r--r--app/i18n/he/admin.php1
-rw-r--r--app/i18n/he/conf.php1
-rw-r--r--app/i18n/he/gen.php1
-rw-r--r--app/i18n/he/user.php32
-rw-r--r--app/i18n/it/admin.php1
-rw-r--r--app/i18n/it/conf.php1
-rw-r--r--app/i18n/it/gen.php1
-rw-r--r--app/i18n/it/user.php32
-rw-r--r--app/i18n/kr/admin.php1
-rw-r--r--app/i18n/kr/conf.php1
-rw-r--r--app/i18n/kr/gen.php1
-rw-r--r--app/i18n/kr/user.php32
-rw-r--r--app/i18n/nl/admin.php1
-rw-r--r--app/i18n/nl/conf.php1
-rw-r--r--app/i18n/nl/gen.php1
-rw-r--r--app/i18n/nl/user.php32
-rw-r--r--app/i18n/oc/admin.php1
-rw-r--r--app/i18n/oc/conf.php1
-rw-r--r--app/i18n/oc/gen.php1
-rw-r--r--app/i18n/oc/user.php32
-rw-r--r--app/i18n/pt-br/admin.php1
-rw-r--r--app/i18n/pt-br/conf.php1
-rw-r--r--app/i18n/pt-br/gen.php1
-rw-r--r--app/i18n/pt-br/user.php32
-rw-r--r--app/i18n/ru/admin.php1
-rw-r--r--app/i18n/ru/conf.php1
-rw-r--r--app/i18n/ru/gen.php1
-rw-r--r--app/i18n/ru/user.php32
-rw-r--r--app/i18n/tr/admin.php1
-rw-r--r--app/i18n/tr/conf.php1
-rw-r--r--app/i18n/tr/gen.php1
-rw-r--r--app/i18n/tr/user.php32
-rw-r--r--app/i18n/zh-cn/admin.php1
-rw-r--r--app/i18n/zh-cn/conf.php1
-rw-r--r--app/i18n/zh-cn/gen.php1
-rw-r--r--app/i18n/zh-cn/user.php32
-rw-r--r--app/layout/simple.phtml66
-rw-r--r--app/views/auth/register.phtml9
-rw-r--r--app/views/configure/system.phtml20
-rw-r--r--app/views/user/manage.phtml11
-rw-r--r--app/views/user/profile.phtml13
-rw-r--r--app/views/user/validateEmail.phtml22
-rw-r--r--app/views/user_mailer/email_need_validation.txt5
69 files changed, 887 insertions, 10 deletions
diff --git a/app/Controllers/authController.php b/app/Controllers/authController.php
index e06a26399..a8b21b886 100644
--- a/app/Controllers/authController.php
+++ b/app/Controllers/authController.php
@@ -205,6 +205,7 @@ class FreshRSS_auth_Controller extends Minz_ActionController {
Minz_Error::error(403);
}
+ $this->view->show_email_field = FreshRSS_Context::$system_conf->force_email_validation;
Minz_View::prependTitle(_t('gen.auth.registration.title') . ' · ');
}
}
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index a839f0005..b02ad02e4 100755
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -293,15 +293,24 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
* configuration values then sends a notification to the user.
*
* The options available on the page are:
+ * - instance name (default: FreshRSS)
+ * - auto update URL (default: false)
+ * - force emails validation (default: false)
* - user limit (default: 1)
* - user category limit (default: 16384)
* - user feed limit (default: 16384)
* - user login duration for form auth (default: 2592000)
+ *
+ * The `force-email-validation` is ignored with PHP < 5.5
*/
public function systemAction() {
if (!FreshRSS_Auth::hasAccess('admin')) {
Minz_Error::error(403);
}
+
+ $can_enable_email_validation = version_compare(PHP_VERSION, '5.5') >= 0;
+ $this->view->can_enable_email_validation = $can_enable_email_validation;
+
if (Minz_Request::isPost()) {
$limits = FreshRSS_Context::$system_conf->limits;
$limits['max_registrations'] = Minz_Request::param('max-registrations', 1);
@@ -311,6 +320,9 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
FreshRSS_Context::$system_conf->limits = $limits;
FreshRSS_Context::$system_conf->title = Minz_Request::param('instance-name', 'FreshRSS');
FreshRSS_Context::$system_conf->auto_update_url = Minz_Request::param('auto-update-url', false);
+ if ($can_enable_email_validation) {
+ FreshRSS_Context::$system_conf->force_email_validation = Minz_Request::param('force-email-validation', false);
+ }
FreshRSS_Context::$system_conf->save();
invalidateHttpCache();
diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php
index c1c27a4ab..9e909a3b5 100644
--- a/app/Controllers/userController.php
+++ b/app/Controllers/userController.php
@@ -33,12 +33,23 @@ class FreshRSS_user_Controller extends Minz_ActionController {
return false;
}
- public static function updateUser($user, $passwordPlain, $apiPasswordPlain, $userConfigUpdated = array()) {
+ public static function updateUser($user, $email, $passwordPlain, $apiPasswordPlain, $userConfigUpdated = array()) {
$userConfig = get_user_configuration($user);
if ($userConfig === null) {
return false;
}
+ if ($email !== null && $userConfig->mail_login !== $email) {
+ $userConfig->mail_login = $email;
+
+ if (FreshRSS_Context::$system_conf->force_email_validation) {
+ $salt = FreshRSS_Context::$system_conf->salt;
+ $userConfig->email_validation_token = sha1($salt . uniqid(mt_rand(), true));
+ $mailer = new FreshRSS_User_Mailer();
+ $mailer->send_email_need_validation($user, $userConfig);
+ }
+ }
+
if ($passwordPlain != '') {
$passwordHash = self::hashPassword($passwordPlain);
$userConfig->passwordHash = $passwordHash;
@@ -84,7 +95,7 @@ class FreshRSS_user_Controller extends Minz_ActionController {
$apiPasswordPlain = Minz_Request::param('apiPasswordPlain', '', true);
$username = Minz_Request::param('username');
- $ok = self::updateUser($username, $passwordPlain, $apiPasswordPlain, array(
+ $ok = self::updateUser($username, null, $passwordPlain, $apiPasswordPlain, array(
'token' => Minz_Request::param('token', null),
));
@@ -111,25 +122,58 @@ class FreshRSS_user_Controller extends Minz_ActionController {
Minz_Error::error(403);
}
+ $email_not_verified = FreshRSS_Context::$user_conf->email_validation_token !== '';
+ if ($email_not_verified) {
+ $this->view->_layout('simple');
+ $this->view->disable_aside = true;
+ }
+
Minz_View::prependTitle(_t('conf.profile.title') . ' · ');
Minz_View::appendScript(Minz_Url::display('/scripts/bcrypt.min.js?' . @filemtime(PUBLIC_PATH . '/scripts/bcrypt.min.js')));
if (Minz_Request::isPost()) {
+ $system_conf = FreshRSS_Context::$system_conf;
+ $user_config = FreshRSS_Context::$user_conf;
+ $old_email = $user_config->mail_login;
+
+ $email = trim(Minz_Request::param('email', ''));
$passwordPlain = Minz_Request::param('newPasswordPlain', '', true);
Minz_Request::_param('newPasswordPlain'); //Discard plain-text password ASAP
$_POST['newPasswordPlain'] = '';
$apiPasswordPlain = Minz_Request::param('apiPasswordPlain', '', true);
- $ok = self::updateUser(Minz_Session::param('currentUser'), $passwordPlain, $apiPasswordPlain, array(
+ if ($system_conf->force_email_validation && empty($email)) {
+ Minz_Request::bad(
+ _t('user.email.feedback.required'),
+ array('c' => 'user', 'a' => 'profile')
+ );
+ }
+
+ if (!empty($email) && !validateEmailAddress($email)) {
+ Minz_Request::bad(
+ _t('user.email.feedback.invalid'),
+ array('c' => 'user', 'a' => 'profile')
+ );
+ }
+
+ $ok = self::updateUser(
+ Minz_Session::param('currentUser'),
+ $email,
+ $passwordPlain,
+ $apiPasswordPlain,
+ array(
'token' => Minz_Request::param('token', null),
- ));
+ )
+ );
Minz_Session::_param('passwordHash', FreshRSS_Context::$user_conf->passwordHash);
if ($ok) {
- if ($passwordPlain == '') {
+ if ($system_conf->force_email_validation && $email !== $old_email) {
+ Minz_Request::good(_t('feedback.profile.updated'), array('c' => 'user', 'a' => 'validateEmail'));
+ } elseif ($passwordPlain == '') {
Minz_Request::good(_t('feedback.profile.updated'), array('c' => 'user', 'a' => 'profile'));
} else {
Minz_Request::good(_t('feedback.profile.updated'), array('c' => 'index', 'a' => 'index'));
@@ -151,6 +195,7 @@ class FreshRSS_user_Controller extends Minz_ActionController {
Minz_View::prependTitle(_t('admin.user.title') . ' · ');
+ $this->view->show_email_field = FreshRSS_Context::$system_conf->force_email_validation;
$this->view->current_user = Minz_Request::param('u');
$this->view->nb_articles = 0;
@@ -165,7 +210,7 @@ class FreshRSS_user_Controller extends Minz_ActionController {
}
}
- public static function createUser($new_user_name, $passwordPlain, $apiPasswordPlain, $userConfig = array(), $insertDefaultFeeds = true) {
+ public static function createUser($new_user_name, $email, $passwordPlain, $apiPasswordPlain, $userConfig = array(), $insertDefaultFeeds = true) {
if (!is_array($userConfig)) {
$userConfig = array();
}
@@ -193,7 +238,7 @@ class FreshRSS_user_Controller extends Minz_ActionController {
if ($ok) {
$userDAO = new FreshRSS_UserDAO();
$ok &= $userDAO->createUser($new_user_name, $userConfig['language'], $insertDefaultFeeds);
- $ok &= self::updateUser($new_user_name, $passwordPlain, $apiPasswordPlain);
+ $ok &= self::updateUser($new_user_name, $email, $passwordPlain, $apiPasswordPlain);
}
return $ok;
}
@@ -204,6 +249,7 @@ class FreshRSS_user_Controller extends Minz_ActionController {
* Request parameters are:
* - new_user_language
* - new_user_name
+ * - new_user_email
* - new_user_passwordPlain
* - r (i.e. a redirection url, optional)
*
@@ -216,11 +262,28 @@ class FreshRSS_user_Controller extends Minz_ActionController {
}
if (Minz_Request::isPost()) {
+ $system_conf = FreshRSS_Context::$system_conf;
+
$new_user_name = Minz_Request::param('new_user_name');
+ $email = Minz_Request::param('new_user_email', '');
$passwordPlain = Minz_Request::param('new_user_passwordPlain', '', true);
$new_user_language = Minz_Request::param('new_user_language', FreshRSS_Context::$user_conf->language);
- $ok = self::createUser($new_user_name, $passwordPlain, '', array('language' => $new_user_language));
+ if ($system_conf->force_email_validation && empty($email)) {
+ Minz_Request::bad(
+ _t('user.email.feedback.required'),
+ array('c' => 'auth', 'a' => 'register')
+ );
+ }
+
+ if (!empty($email) && !validateEmailAddress($email)) {
+ Minz_Request::bad(
+ _t('user.email.feedback.invalid'),
+ array('c' => 'auth', 'a' => 'register')
+ );
+ }
+
+ $ok = self::createUser($new_user_name, $email, $passwordPlain, '', array('language' => $new_user_language));
Minz_Request::_param('new_user_passwordPlain'); //Discard plain-text password ASAP
$_POST['new_user_passwordPlain'] = '';
invalidateHttpCache();
@@ -273,6 +336,122 @@ class FreshRSS_user_Controller extends Minz_ActionController {
}
/**
+ * This action validates an email address, based on the token sent by email.
+ * It also serves the main page when user is blocked.
+ *
+ * Request parameters are:
+ * - username
+ * - token
+ *
+ * This route works with GET requests since the URL is provided by email.
+ * The security risks (e.g. forged URL by an attacker) are not very high so
+ * it's ok.
+ *
+ * It returns 404 error if `force_email_validation` is disabled or if the
+ * user doesn't exist.
+ *
+ * It returns 403 if user isn't logged in and `username` param isn't passed.
+ */
+ public function validateEmailAction() {
+ if (!FreshRSS_Context::$system_conf->force_email_validation) {
+ Minz_Error::error(404);
+ }
+
+ Minz_View::prependTitle(_t('user.email.validation.title') . ' · ');
+ $this->view->_layout('simple');
+
+ $username = Minz_Request::param('username');
+ $token = Minz_Request::param('token');
+
+ if ($username) {
+ $user_config = get_user_configuration($username);
+ } elseif (FreshRSS_Auth::hasAccess()) {
+ $user_config = FreshRSS_Context::$user_conf;
+ } else {
+ Minz_Error::error(403);
+ }
+
+ if (!FreshRSS_UserDAO::exists($username) || $user_config === null) {
+ Minz_Error::error(404);
+ }
+
+ if ($user_config->email_validation_token === '') {
+ Minz_Request::good(
+ _t('user.email.validation.feedback.unnecessary'),
+ array('c' => 'index', 'a' => 'index')
+ );
+ }
+
+ if ($token) {
+ if ($user_config->email_validation_token !== $token) {
+ Minz_Request::bad(
+ _t('user.email.validation.feedback.wrong_token'),
+ array('c' => 'user', 'a' => 'validateEmail')
+ );
+ }
+
+ $user_config->email_validation_token = '';
+ if ($user_config->save()) {
+ Minz_Request::good(
+ _t('user.email.validation.feedback.ok'),
+ array('c' => 'index', 'a' => 'index')
+ );
+ } else {
+ Minz_Request::bad(
+ _t('user.email.validation.feedback.error'),
+ array('c' => 'user', 'a' => 'validateEmail')
+ );
+ }
+ }
+ }
+
+ /**
+ * This action resends a validation email to the current user.
+ *
+ * It only acts on POST requests but doesn't require any param (except the
+ * CSRF token).
+ *
+ * It returns 403 error if the user is not logged in or 404 if request is
+ * not POST. Else it redirects silently to the index if user has already
+ * validated its email, or to the user#validateEmail route.
+ */
+ public function sendValidationEmailAction() {
+ if (!FreshRSS_Auth::hasAccess()) {
+ Minz_Error::error(403);
+ }
+
+ if (!Minz_Request::isPost()) {
+ Minz_Error::error(404);
+ }
+
+ $username = Minz_Session::param('currentUser', '_');
+ $user_config = FreshRSS_Context::$user_conf;
+
+ if ($user_config->email_validation_token === '') {
+ Minz_Request::forward(array(
+ 'c' => 'index',
+ 'a' => 'index',
+ ), true);
+ }
+
+ $mailer = new FreshRSS_User_Mailer();
+ $ok = $mailer->send_email_need_validation($username, $user_config);
+
+ $redirect_url = array('c' => 'user', 'a' => 'validateEmail');
+ if ($ok) {
+ Minz_Request::good(
+ _t('user.email.validation.feedback.email_sent'),
+ $redirect_url
+ );
+ } else {
+ Minz_Request::bad(
+ _t('user.email.validation.feedback.email_failed'),
+ $redirect_url
+ );
+ }
+ }
+
+ /**
* This action delete an existing user.
*
* Request parameter is:
diff --git a/app/FreshRSS.php b/app/FreshRSS.php
index d578beac4..c48ad2093 100644
--- a/app/FreshRSS.php
+++ b/app/FreshRSS.php
@@ -54,6 +54,8 @@ class FreshRSS extends Minz_FrontController {
Minz_ExtensionManager::enableByList($ext_list);
}
+ self::checkEmailValidated();
+
Minz_ExtensionManager::callHook('freshrss_init');
}
@@ -144,4 +146,20 @@ class FreshRSS extends Minz_FrontController {
FreshRSS_Share::load(join_path(APP_PATH, 'shares.php'));
self::loadStylesAndScripts();
}
+
+ private static function checkEmailValidated() {
+ $email_not_verified = FreshRSS_Auth::hasAccess() && FreshRSS_Context::$user_conf->email_validation_token !== '';
+ $action_is_allowed = (
+ Minz_Request::is('user', 'validateEmail') ||
+ Minz_Request::is('user', 'sendValidationEmail') ||
+ Minz_Request::is('user', 'profile') ||
+ Minz_Request::is('auth', 'logout')
+ );
+ if ($email_not_verified && !$action_is_allowed) {
+ Minz_Request::forward(array(
+ 'c' => 'user',
+ 'a' => 'validateEmail',
+ ), true);
+ }
+ }
}
diff --git a/app/Mailers/UserMailer.php b/app/Mailers/UserMailer.php
new file mode 100644
index 000000000..5a2d39f1a
--- /dev/null
+++ b/app/Mailers/UserMailer.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * Manage the emails sent to the users.
+ */
+class FreshRSS_User_Mailer extends Minz_Mailer {
+ public function send_email_need_validation($username, $user_config) {
+ $this->view->_path('user_mailer/email_need_validation.txt');
+
+ $this->view->username = $username;
+ $this->view->site_title = FreshRSS_Context::$system_conf->title;
+ $this->view->validation_url = Minz_Url::display(
+ array(
+ 'c' => 'user',
+ 'a' => 'validateEmail',
+ 'params' => array(
+ 'username' => $username,
+ 'token' => $user_config->email_validation_token
+ )
+ ),
+ 'txt',
+ true
+ );
+
+ $subject_prefix = '[' . FreshRSS_Context::$system_conf->title . ']';
+ return $this->mail(
+ $user_config->mail_login,
+ $subject_prefix . ' ' ._t('user.mailer.email_need_validation.title')
+ );
+ }
+}
diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php
index 778513f17..963d37e2b 100644
--- a/app/Models/ConfigurationSetter.php
+++ b/app/Models/ConfigurationSetter.php
@@ -389,4 +389,8 @@ class FreshRSS_ConfigurationSetter {
$data['auto_update_url'] = $value;
}
+
+ private function _force_email_validation(&$data, $value) {
+ $data['force_email_validation'] = $this->handleBool($value);
+ }
}
diff --git a/app/i18n/cz/admin.php b/app/i18n/cz/admin.php
index 68127f571..a2a509560 100644
--- a/app/i18n/cz/admin.php
+++ b/app/i18n/cz/admin.php
@@ -163,6 +163,7 @@ return array(
'help' => 'in seconds', //TODO - Translation
'number' => 'Duration to keep logged in', //TODO - Translation
),
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Instance name', //TODO - Translation
'max-categories' => 'Categories per user limit', //TODO - Translation
'max-feeds' => 'Feeds per user limit', //TODO - Translation
diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php
index 8a21067ee..cd7535571 100644
--- a/app/i18n/cz/conf.php
+++ b/app/i18n/cz/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Smazání účtu',
'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty',
),
+ 'email' => 'Email',
'password_api' => 'Password API<br /><small>(tzn. pro mobilní aplikace)</small>',
'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
'password_format' => 'Alespoň 7 znaků',
diff --git a/app/i18n/cz/gen.php b/app/i18n/cz/gen.php
index f1a412252..990ff0c30 100644
--- a/app/i18n/cz/gen.php
+++ b/app/i18n/cz/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Aktualizovat',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← Zpět na seznam RSS kanálů',
'cancel' => 'Zrušit',
'create' => 'Vytvořit',
diff --git a/app/i18n/cz/user.php b/app/i18n/cz/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/cz/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/de/admin.php b/app/i18n/de/admin.php
index f0307dcab..d075bf28f 100644
--- a/app/i18n/de/admin.php
+++ b/app/i18n/de/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Systemeinstellungen',
'auto-update-url' => 'Auto-update URL',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Dein Reader Name',
'max-categories' => 'Anzahl erlaubter Kategorien pro Benutzer',
'max-feeds' => 'Anzahl erlaubter Feeds pro Benutzer',
diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php
index 37a67eb15..99225da9c 100644
--- a/app/i18n/de/conf.php
+++ b/app/i18n/de/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Accountlöschung',
'warn' => 'Dein Account und alle damit bezogenen Daten werden gelöscht.',
),
+ 'email' => 'E-Mail-Adresse',
'password_api' => 'Passwort-API<br /><small>(z. B. für mobile Anwendungen)</small>',
'password_form' => 'Passwort<br /><small>(für die Anmeldemethode per Webformular)</small>',
'password_format' => 'mindestens 7 Zeichen',
diff --git a/app/i18n/de/gen.php b/app/i18n/de/gen.php
index 93bd62d41..135263d28 100644
--- a/app/i18n/de/gen.php
+++ b/app/i18n/de/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Aktualisieren',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← Zurück zu Ihren RSS-Feeds gehen',
'cancel' => 'Abbrechen',
'create' => 'Erstellen',
diff --git a/app/i18n/de/user.php b/app/i18n/de/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/de/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/en/admin.php b/app/i18n/en/admin.php
index 004089ffc..c5ab183e8 100644
--- a/app/i18n/en/admin.php
+++ b/app/i18n/en/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'System configuration',
'auto-update-url' => 'Auto-update server URL',
+ 'force_email_validation' => 'Force email addresses validation',
'instance-name' => 'Instance name',
'max-categories' => 'Categories per user limit',
'max-feeds' => 'Feeds per user limit',
diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php
index 8193233ce..1078c736c 100644
--- a/app/i18n/en/conf.php
+++ b/app/i18n/en/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Account deletion',
'warn' => 'Your account and all related data will be deleted.',
),
+ 'email' => 'Email address',
'password_api' => 'API password<br /><small>(e.g., for mobile apps)</small>',
'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
'password_format' => 'At least 7 characters',
diff --git a/app/i18n/en/gen.php b/app/i18n/en/gen.php
index 655b02402..470c27234 100644
--- a/app/i18n/en/gen.php
+++ b/app/i18n/en/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Actualize',
+ 'back' => '← Go back',
'back_to_rss_feeds' => '← Go back to your RSS feeds',
'cancel' => 'Cancel',
'create' => 'Create',
diff --git a/app/i18n/en/user.php b/app/i18n/en/user.php
new file mode 100644
index 000000000..5b4cd4fcb
--- /dev/null
+++ b/app/i18n/en/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.',
+ 'required' => 'The email address is required.',
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.',
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.',
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.',
+ 'email_sent' => 'An email has been sent to your address.',
+ 'error' => 'The email address failed to be validated.',
+ 'ok' => 'The email address has been validated.',
+ 'unneccessary' => 'The email address was already validated.',
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.',
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.',
+ 'resend_email' => 'Resend the email',
+ 'title' => 'Email address validation',
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account',
+ 'welcome' => 'Welcome %s,',
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:',
+ ),
+ ),
+);
diff --git a/app/i18n/es/admin.php b/app/i18n/es/admin.php
index 0ec8549bd..1af3bdcb2 100755
--- a/app/i18n/es/admin.php
+++ b/app/i18n/es/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Configuración del sistema',
'auto-update-url' => 'URL de auto-actualización',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Nombre de la fuente',
'max-categories' => 'Límite de categorías por usuario',
'max-feeds' => 'Límite de fuentes por usuario',
diff --git a/app/i18n/es/conf.php b/app/i18n/es/conf.php
index 2eeeee052..6aaad8d13 100755
--- a/app/i18n/es/conf.php
+++ b/app/i18n/es/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Borrar cuenta',
'warn' => 'Tu cuenta y todos los datos asociados serán eliminados.',
),
+ 'email' => 'Correo electrónico',
'password_api' => 'Contraseña API <br /><small>(para apps móviles, por ej.)</small>',
'password_form' => 'Contraseña<br /><small>(para el método de identificación por formulario web)</small>',
'password_format' => 'Mínimo de 7 caracteres',
diff --git a/app/i18n/es/gen.php b/app/i18n/es/gen.php
index 16c8267a6..e73aaef12 100755
--- a/app/i18n/es/gen.php
+++ b/app/i18n/es/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Actualizar',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← regresar a tus fuentes RSS',
'cancel' => 'Cancelar',
'create' => 'Crear',
diff --git a/app/i18n/es/user.php b/app/i18n/es/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/es/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/fr/admin.php b/app/i18n/fr/admin.php
index 74605b5ee..6002617fc 100644
--- a/app/i18n/fr/admin.php
+++ b/app/i18n/fr/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Configuration du système',
'auto-update-url' => 'URL du service de mise à jour',
+ 'force_email_validation' => 'Forcer la validation des adresses email',
'instance-name' => 'Nom de l’instance',
'max-categories' => 'Limite de catégories par utilisateur',
'max-feeds' => 'Limite de flux par utilisateur',
diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php
index 5f6730b53..dcd623b5a 100644
--- a/app/i18n/fr/conf.php
+++ b/app/i18n/fr/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Suppression du compte',
'warn' => 'Le compte et toutes les données associées vont être supprimées.',
),
+ 'email' => 'Adresse email',
'password_api' => 'Mot de passe API<br /><small>(ex. : pour applis mobiles)</small>',
'password_form' => 'Mot de passe<br /><small>(pour connexion par formulaire)</small>',
'password_format' => '7 caractères minimum',
diff --git a/app/i18n/fr/gen.php b/app/i18n/fr/gen.php
index d99e42fca..8e195c60d 100644
--- a/app/i18n/fr/gen.php
+++ b/app/i18n/fr/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Actualiser',
+ 'back' => '← Retour',
'back_to_rss_feeds' => '← Retour à vos flux RSS',
'cancel' => 'Annuler',
'create' => 'Créer',
diff --git a/app/i18n/fr/user.php b/app/i18n/fr/user.php
new file mode 100644
index 000000000..01d3ad1af
--- /dev/null
+++ b/app/i18n/fr/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'L’adresse email est invalide.',
+ 'required' => 'L’adresse email est requise.',
+ ),
+ 'validation' => array(
+ 'change_email' => 'Vous pouvez changer votre adresse email <a href="%s">dans votre profil</a>.',
+ 'email_sent_to' => 'Nous venons d’envoyer un email à <strong>%s</strong>, veuillez suivre ses indications pour valider votre adresse.',
+ 'feedback' => array(
+ 'email_failed' => 'Nous n’avons pas pu vous envoyer d’email à cause d’une mauvaise configuration du serveur.',
+ 'email_sent' => 'Un email a été envoyé à votre adresse.',
+ 'error' => 'L’adresse email n’a pas pu être validée.',
+ 'ok' => 'L’adresse email a été validée.',
+ 'unnecessary' => 'L’adresse email a déjà été validée.',
+ 'wrong_token' => 'L’adresse email n’a pas pu être validée à cause d’un mauvais token.',
+ ),
+ 'need_to' => 'Vous devez valider votre adresse email avant de pouvoir utiliser %s.',
+ 'resend_email' => 'Renvoyer l’email',
+ 'title' => 'Validation de l’adresse email',
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'Vous devez valider votre compte',
+ 'welcome' => 'Bienvenue %s,',
+ 'body' => 'Vous venez de vous inscrire sur %s mais vous devez encore valider votre adresse email. Pour cela, veuillez cliquer sur ce lien :',
+ ),
+ ),
+);
diff --git a/app/i18n/he/admin.php b/app/i18n/he/admin.php
index e0dfc405d..759b74e2a 100644
--- a/app/i18n/he/admin.php
+++ b/app/i18n/he/admin.php
@@ -163,6 +163,7 @@ return array(
'help' => 'in seconds', //TODO - Translation
'number' => 'Duration to keep logged in', //TODO - Translation
),
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Instance name', //TODO - Translation
'max-categories' => 'Categories per user limit', //TODO - Translation
'max-feeds' => 'Feeds per user limit', //TODO - Translation
diff --git a/app/i18n/he/conf.php b/app/i18n/he/conf.php
index 1da5c292c..7e764b944 100644
--- a/app/i18n/he/conf.php
+++ b/app/i18n/he/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Account deletion', //TODO - Translation
'warn' => 'Your account and all related data will be deleted.', //TODO - Translation
),
+ 'email' => 'Email address', //TODO - Translation
'password_api' => 'סיסמת API<br /><small>(לדוגמה ליישומים סלולריים)</small>',
'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
'password_format' => 'At least 7 characters', //TODO - Translation
diff --git a/app/i18n/he/gen.php b/app/i18n/he/gen.php
index 13084fda0..270a66ea0 100644
--- a/app/i18n/he/gen.php
+++ b/app/i18n/he/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'מימוש',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← חזרה להזנות הRSS שלך',
'cancel' => 'ביטול',
'create' => 'יצירה',
diff --git a/app/i18n/he/user.php b/app/i18n/he/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/he/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/it/admin.php b/app/i18n/it/admin.php
index d4253e9ba..8bb6c7bfe 100644
--- a/app/i18n/it/admin.php
+++ b/app/i18n/it/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Configurazione di sistema',
'auto-update-url' => 'Auto-update server URL', //TODO - Translation
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Nome istanza',
'max-categories' => 'Limite categorie per utente',
'max-feeds' => 'Limite feeds per utente',
diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php
index f3c59ed8c..f06302c72 100644
--- a/app/i18n/it/conf.php
+++ b/app/i18n/it/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Cancellazione account',
'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.',
),
+ 'email' => 'Indirizzo email',
'password_api' => 'Password API<br /><small>(e.g., per applicazioni mobili)</small>',
'password_form' => 'Password<br /><small>(per il login classico)</small>',
'password_format' => 'Almeno 7 caratteri',
diff --git a/app/i18n/it/gen.php b/app/i18n/it/gen.php
index 4f6f7e36f..e5114439c 100644
--- a/app/i18n/it/gen.php
+++ b/app/i18n/it/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Aggiorna',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← Indietro',
'cancel' => 'Annulla',
'create' => 'Crea',
diff --git a/app/i18n/it/user.php b/app/i18n/it/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/it/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/kr/admin.php b/app/i18n/kr/admin.php
index 6312bd3fe..4a8e425d5 100644
--- a/app/i18n/kr/admin.php
+++ b/app/i18n/kr/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => '시스템 설정',
'auto-update-url' => '자동 업데이트 서버 URL',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => '인스턴스 이름',
'max-categories' => '사용자별 카테고리 개수 제한',
'max-feeds' => '사용자별 피드 개수 제한',
diff --git a/app/i18n/kr/conf.php b/app/i18n/kr/conf.php
index 1efaee88b..397d57418 100644
--- a/app/i18n/kr/conf.php
+++ b/app/i18n/kr/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => '계정 삭제',
'warn' => '당신의 계정과 관련된 모든 데이터가 삭제됩니다.',
),
+ 'email' => '메일 주소',
'password_api' => 'API 암호<br /><small>(예: 모바일 애플리케이션)</small>',
'password_form' => '암호<br /><small>(웹폼 로그인 방식 사용시)</small>',
'password_format' => '7 글자 이상이어야 합니다',
diff --git a/app/i18n/kr/gen.php b/app/i18n/kr/gen.php
index 72b95fa6e..979cb9ffa 100644
--- a/app/i18n/kr/gen.php
+++ b/app/i18n/kr/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => '새 글 가져오기',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← RSS 피드로 돌아가기',
'cancel' => '취소',
'create' => '생성',
diff --git a/app/i18n/kr/user.php b/app/i18n/kr/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/kr/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/nl/admin.php b/app/i18n/nl/admin.php
index e5d126eb8..535241e58 100644
--- a/app/i18n/nl/admin.php
+++ b/app/i18n/nl/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Systeem configuratie',
'auto-update-url' => 'Automatische update server URL',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Voorbeeld naam',
'max-categories' => 'Categorielimiet per gebruiker',
'max-feeds' => 'Feedlimiet per gebruiker',
diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php
index b7ba7bbeb..ec219d051 100644
--- a/app/i18n/nl/conf.php
+++ b/app/i18n/nl/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Account verwijderen',
'warn' => 'Uw account en alle gerelateerde gegvens worden verwijderd.',
),
+ 'email' => 'Email adres',
'password_api' => 'Wachtwoord API<br /><small>(e.g., voor mobiele apps)</small>',
'password_form' => 'Wachtwoord<br /><small>(voor de Web-formulier log in methode)</small>',
'password_format' => 'Ten minste 7 tekens',
diff --git a/app/i18n/nl/gen.php b/app/i18n/nl/gen.php
index 57d68d673..419d8b36c 100644
--- a/app/i18n/nl/gen.php
+++ b/app/i18n/nl/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Actualiseren',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← Ga terug naar je RSS feeds',
'cancel' => 'Annuleren',
'create' => 'Opslaan',
diff --git a/app/i18n/nl/user.php b/app/i18n/nl/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/nl/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/oc/admin.php b/app/i18n/oc/admin.php
index 2f8ede873..aee12a20d 100644
--- a/app/i18n/oc/admin.php
+++ b/app/i18n/oc/admin.php
@@ -163,6 +163,7 @@ return array(
'help' => 'en segondas',
'number' => 'Durada de téner d’ésser connectat',
),
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Nom de l’instància',
'max-categories' => 'Limita de categoria per utilizaire',
'max-feeds' => 'Limita de fluxes per utilizaire',
diff --git a/app/i18n/oc/conf.php b/app/i18n/oc/conf.php
index b37785a7e..19880b3f8 100644
--- a/app/i18n/oc/conf.php
+++ b/app/i18n/oc/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Supression del compte',
'warn' => 'Lo compte e totas las donadas ligadas seràn suprimits.',
),
+ 'email' => 'Adreça de corrièl',
'password_api' => 'Senhal API<br /><small>(ex. : per las aplicacions mobil)</small>',
'password_form' => 'Senhal API<br /><small>(ex. : per la connexion via formulari)</small>',
'password_format' => 'Almens 7 caractèrs',
diff --git a/app/i18n/oc/gen.php b/app/i18n/oc/gen.php
index 1fa1358ff..281bb06f1 100644
--- a/app/i18n/oc/gen.php
+++ b/app/i18n/oc/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Actualizar',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← Tornar a vòstres fluxes RSS',
'cancel' => 'Anullar',
'create' => 'Crear',
diff --git a/app/i18n/oc/user.php b/app/i18n/oc/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/oc/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/pt-br/admin.php b/app/i18n/pt-br/admin.php
index 82559c67b..cef6694c2 100644
--- a/app/i18n/pt-br/admin.php
+++ b/app/i18n/pt-br/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Configuração do sistema',
'auto-update-url' => 'URL do servidor para atualização automática',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Nome da instância',
'max-categories' => 'Limite de categorias por usuário',
'max-feeds' => 'Limite de Feeds por usuário',
diff --git a/app/i18n/pt-br/conf.php b/app/i18n/pt-br/conf.php
index 082027328..eb067e58a 100644
--- a/app/i18n/pt-br/conf.php
+++ b/app/i18n/pt-br/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Remover conta',
'warn' => 'Sua conta e todos os dados relacionados serão removidos.',
),
+ 'email' => 'Endereço de e-mail',
'password_api' => 'Senha da API<br /><small>(p.s., para aplicativos móveis)</small>',
'password_form' => 'Senha<br /><small>(para o método de formulário web)</small>',
'password_format' => 'Ao menos 7 caracteres',
diff --git a/app/i18n/pt-br/gen.php b/app/i18n/pt-br/gen.php
index 2d2b5f1a4..e536e1d95 100644
--- a/app/i18n/pt-br/gen.php
+++ b/app/i18n/pt-br/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Atualizar',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← Volte para o seu feeds RSS',
'cancel' => 'Cancelar',
'create' => 'Criar',
diff --git a/app/i18n/pt-br/user.php b/app/i18n/pt-br/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/pt-br/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/ru/admin.php b/app/i18n/ru/admin.php
index c9a7d6683..adf091df9 100644
--- a/app/i18n/ru/admin.php
+++ b/app/i18n/ru/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Системные настройки',
'auto-update-url' => 'Адрес сервера для автоматического обновления',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Название этого сервера',
'max-categories' => 'Количество категорий на пользователя',
'max-feeds' => 'Количество статей на пользователя',
diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php
index 48ce4b9f3..af6f3b5f6 100644
--- a/app/i18n/ru/conf.php
+++ b/app/i18n/ru/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Account deletion', //TODO - Translation
'warn' => 'Your account and all the related data will be deleted.', //TODO - Translation
),
+ 'email' => 'Email address', //TODO - Translation
'password_api' => 'Password API<br /><small>(e.g., for mobile apps)</small>', //TODO - Translation
'password_form' => 'Password<br /><small>(for the Web-form login method)</small>', //TODO - Translation
'password_format' => 'At least 7 characters', //TODO - Translation
diff --git a/app/i18n/ru/gen.php b/app/i18n/ru/gen.php
index f28e5adad..39f3c7534 100644
--- a/app/i18n/ru/gen.php
+++ b/app/i18n/ru/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Actualize', //TODO - Translation
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← Go back to your RSS feeds', //TODO - Translation
'cancel' => 'Cancel', //TODO - Translation
'create' => 'Create', //TODO - Translation
diff --git a/app/i18n/ru/user.php b/app/i18n/ru/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/ru/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/tr/admin.php b/app/i18n/tr/admin.php
index b1d6671ca..2c7d0fd6d 100644
--- a/app/i18n/tr/admin.php
+++ b/app/i18n/tr/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => 'Sistem yapılandırması',
'auto-update-url' => 'Otomatik güncelleme sunucu URL',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => 'Örnek isim',
'max-categories' => 'Kullanıcı başına kategori limiti',
'max-feeds' => 'Kullanıcı başına akış limiti',
diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php
index 855bca6c8..2bf1e8a6a 100644
--- a/app/i18n/tr/conf.php
+++ b/app/i18n/tr/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => 'Hesap silme',
'warn' => 'Hesabınız ve tüm verileriniz silinecek.',
),
+ 'email' => 'Email adresleri',
'password_api' => 'API Şifresi<br /><small>(ör. mobil uygulamalar için)</small>',
'password_form' => 'Şifre<br /><small>(Tarayıcı girişi için)</small>',
'password_format' => 'En az 7 karakter',
diff --git a/app/i18n/tr/gen.php b/app/i18n/tr/gen.php
index e167f5a09..8bac03746 100644
--- a/app/i18n/tr/gen.php
+++ b/app/i18n/tr/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => 'Yenile',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← RSS akışlarınız için geri gidin',
'cancel' => 'İptal',
'create' => 'Oluştur',
diff --git a/app/i18n/tr/user.php b/app/i18n/tr/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/tr/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/i18n/zh-cn/admin.php b/app/i18n/zh-cn/admin.php
index 74f57b6e8..cdc8449a3 100644
--- a/app/i18n/zh-cn/admin.php
+++ b/app/i18n/zh-cn/admin.php
@@ -159,6 +159,7 @@ return array(
'system' => array(
'_' => '系统配置',
'auto-update-url' => '自动升级服务器 URL',
+ 'force_email_validation' => 'Force email addresses validation', //TODO - Translation
'instance-name' => '实例名称',
'max-categories' => '每用户分类限制',
'max-feeds' => '每用户 RSS 源限制',
diff --git a/app/i18n/zh-cn/conf.php b/app/i18n/zh-cn/conf.php
index ebe069c2c..2960cd6b1 100644
--- a/app/i18n/zh-cn/conf.php
+++ b/app/i18n/zh-cn/conf.php
@@ -46,6 +46,7 @@ return array(
'_' => '账户删除',
'warn' => '你的帐户和所有相关数据都将被删除。',
),
+ 'email' => 'Email 地址',
'password_api' => 'API 密码<br /><small>(例如,用于手机 APP)</small>',
'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>',
'password_format' => '至少 7 个字符',
diff --git a/app/i18n/zh-cn/gen.php b/app/i18n/zh-cn/gen.php
index bef5744b6..4d4c52ed6 100644
--- a/app/i18n/zh-cn/gen.php
+++ b/app/i18n/zh-cn/gen.php
@@ -3,6 +3,7 @@
return array(
'action' => array(
'actualize' => '获取',
+ 'back' => '← Go back', //TODO - Translation
'back_to_rss_feeds' => '← 返回',
'cancel' => '取消',
'create' => '创建',
diff --git a/app/i18n/zh-cn/user.php b/app/i18n/zh-cn/user.php
new file mode 100644
index 000000000..4f2cfcda2
--- /dev/null
+++ b/app/i18n/zh-cn/user.php
@@ -0,0 +1,32 @@
+<?php
+
+return array(
+ 'email' => array(
+ 'feedback' => array(
+ 'invalid' => 'The email address is invalid.', //TODO - Translation
+ 'required' => 'The email address is required.', //TODO - Translation
+ ),
+ 'validation' => array(
+ 'change_email' => 'You can change your email address <a href="%s">on the profile page</a>.', //TODO - Translation
+ 'email_sent_to' => 'We sent you an email at <strong>%s</strong>, please follow its indications to validate your address.', //TODO - Translation
+ 'feedback' => array(
+ 'email_failed' => 'We couldn’t send you an email because of a misconfiguration of the server.', //TODO - Translation
+ 'email_sent' => 'An email has been sent to your address.', //TODO - Translation
+ 'error' => 'The email address failed to be validated.', //TODO - Translation
+ 'ok' => 'The email address has been validated.', //TODO - Translation
+ 'unneccessary' => 'The email address was already validated.', //TODO - Translation
+ 'wrong_token' => 'The email address failed to be validated due to a wrong token.', //TODO - Translation
+ ),
+ 'need_to' => 'You need to validate your email address before being able to use %s.', //TODO - Translation
+ 'resend_email' => 'Resend the email', //TODO - Translation
+ 'title' => 'Email address validation', //TODO - Translation
+ ),
+ ),
+ 'mailer' => array(
+ 'email_need_validation' => array(
+ 'title' => 'You need to validate your account', //TODO - Translation
+ 'welcome' => 'Welcome %s,', //TODO - Translation
+ 'body' => 'You’ve just registered on %s but you still need to validate your email. For that, just follow the link:', //TODO - Translation
+ ),
+ ),
+);
diff --git a/app/layout/simple.phtml b/app/layout/simple.phtml
new file mode 100644
index 000000000..5546966be
--- /dev/null
+++ b/app/layout/simple.phtml
@@ -0,0 +1,66 @@
+<?php FreshRSS::preLayout(); ?>
+<!DOCTYPE html>
+<html lang="<?php echo FreshRSS_Context::$user_conf->language; ?>" xml:lang="<?php echo FreshRSS_Context::$user_conf->language; ?>">
+ <head>
+ <meta charset="UTF-8" />
+ <meta name="viewport" content="initial-scale=1.0" />
+ <?php echo self::headStyle(); ?>
+ <?php echo self::headScript(); ?>
+ <link rel="shortcut icon" id="favicon" type="image/x-icon" sizes="16x16 64x64" href="<?php echo Minz_Url::display('/favicon.ico'); ?>" />
+ <link rel="icon msapplication-TileImage apple-touch-icon" type="image/png" sizes="256x256" href="<?php echo Minz_Url::display('/themes/icons/favicon-256.png'); ?>" />
+ <link rel="apple-touch-icon" href="<?php echo Minz_Url::display('/themes/icons/apple-touch-icon.png'); ?>" />
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+ <meta name="apple-mobile-web-app-title" content="<?php echo FreshRSS_Context::$system_conf->title; ?>">
+ <meta name="msapplication-TileColor" content="#FFF" />
+ <meta name="referrer" content="never" />
+ <meta name="robots" content="noindex,nofollow" />
+ <?php echo self::headTitle(); ?>
+ </head>
+ <body>
+
+<?php flush(); ?>
+<div class="app-layout app-layout-simple">
+ <div class="header">
+ <div class="item title">
+ <h1>
+ <a href="<?php echo _url('index', 'index'); ?>">
+ <img class="logo" src="<?php echo _i('icon', true); ?>" alt="" />
+ <?php echo FreshRSS_Context::$system_conf->title; ?>
+ </a>
+ </h1>
+ </div>
+
+ <div class="item"></div>
+
+ <div class="item">
+ <?php if (FreshRSS_Auth::accessNeedsAction()) { ?>
+ <a class="signout" href="<?php echo _url('auth', 'logout'); ?>">
+ <?php echo _i('logout') . _t('gen.auth.logout'); ?>
+
+ (<?php echo htmlspecialchars(Minz_Session::param('currentUser', '_'), ENT_NOQUOTES, 'UTF-8'); ?>)
+ </a>
+ <?php } ?>
+ </div>
+ </div>
+
+ <?php $this->render(); ?>
+</div>
+
+<?php
+ $msg = '';
+ $status = 'closed';
+ if (isset($this->notification)) {
+ $msg = $this->notification['content'];
+ $status = $this->notification['type'];
+
+ invalidateHttpCache();
+ }
+?>
+<div id="notification" class="notification <?php echo $status; ?>">
+ <span class="msg"><?php echo $msg; ?></span>
+ <a class="close" href=""><?php echo _i('close'); ?></a>
+</div>
+
+ </body>
+</html>
diff --git a/app/views/auth/register.phtml b/app/views/auth/register.phtml
index 19e11ef76..87582a2d0 100644
--- a/app/views/auth/register.phtml
+++ b/app/views/auth/register.phtml
@@ -8,6 +8,15 @@
<input id="new_user_name" name="new_user_name" type="text" size="16" required="required" autocomplete="off" pattern="<?php echo FreshRSS_user_Controller::USERNAME_PATTERN; ?>" />
</div>
+ <?php if ($this->show_email_field) { ?>
+ <div>
+ <label class="group-name" for="new_user_email">
+ <?php echo _t('gen.auth.email'); ?>
+ </label>
+ <input id="new_user_email" name="new_user_email" type="email" required />
+ </div>
+ <?php } ?>
+
<div>
<label class="group-name" for="new_user_passwordPlain"><?php echo _t('gen.auth.password'), '<br />', _i('help'), ' ', _t('gen.auth.password.format'); ?></label>
<div class="stick">
diff --git a/app/views/configure/system.phtml b/app/views/configure/system.phtml
index 9af4cc2c9..eb0e68dfc 100644
--- a/app/views/configure/system.phtml
+++ b/app/views/configure/system.phtml
@@ -38,6 +38,24 @@
</div>
</div>
+ <?php if ($this->can_enable_email_validation) { ?>
+ <div class="form-group">
+ <div class="group-controls">
+ <label class="checkbox" for="force-email-validation">
+ <input
+ type="checkbox"
+ name="force-email-validation"
+ id="force-email-validation"
+ value="1"
+ <?php echo FreshRSS_Context::$system_conf->force_email_validation ? 'checked="checked"' : ''; ?>
+ data-leave-validation="<?php echo FreshRSS_Context::$system_conf->force_email_validation; ?>"
+ />
+ <?php echo _t('admin.system.force_email_validation'); ?>
+ </label>
+ </div>
+ </div>
+ <?php } ?>
+
<div class="form-group">
<label class="group-name" for="max-feeds"><?php echo _t('admin.system.max-feeds'); ?></label>
<div class="group-controls">
@@ -51,7 +69,7 @@
<input type="number" id="max-categories" name="max-categories" value="<?php echo FreshRSS_Context::$system_conf->limits['max_categories']; ?>" min="1" data-leave-validation="<?php echo FreshRSS_Context::$system_conf->limits['max_categories']; ?>"/>
</div>
</div>
-
+
<div class="form-group">
<label class="group-name" for="cookie-duration"><?php echo _t('admin.system.cookie-duration.number'); ?></label>
<div class="group-controls">
diff --git a/app/views/user/manage.phtml b/app/views/user/manage.phtml
index d0e5928ef..501257e5b 100644
--- a/app/views/user/manage.phtml
+++ b/app/views/user/manage.phtml
@@ -26,6 +26,17 @@
</div>
</div>
+ <?php if ($this->show_email_field) { ?>
+ <div class="form-group">
+ <label class="group-name" for="new_user_email">
+ <?php echo _t('gen.auth.email'); ?>
+ </label>
+ <div class="group-controls">
+ <input id="new_user_email" name="new_user_email" type="email" required />
+ </div>
+ </div>
+ <?php } ?>
+
<div class="form-group">
<label class="group-name" for="new_user_passwordPlain"><?php echo _t('admin.user.password_form'); ?></label>
<div class="group-controls">
diff --git a/app/views/user/profile.phtml b/app/views/user/profile.phtml
index 83140376d..87aa25b11 100644
--- a/app/views/user/profile.phtml
+++ b/app/views/user/profile.phtml
@@ -1,4 +1,8 @@
-<?php $this->partial('aside_configure'); ?>
+<?php
+ if (!$this->disable_aside) {
+ $this->partial('aside_configure');
+ }
+?>
<div class="post">
<a href="<?php echo _url('index', 'index'); ?>"><?php echo _t('gen.action.back_to_rss_feeds'); ?></a>
@@ -19,6 +23,13 @@
</div>
<div class="form-group">
+ <label class="group-name" for="email"><?php echo _t('conf.profile.email'); ?></label>
+ <div class="group-controls">
+ <input id="email" name="email" type="email" value="<?php echo FreshRSS_Context::$user_conf->mail_login; ?>" />
+ </div>
+ </div>
+
+ <div class="form-group">
<label class="group-name" for="newPasswordPlain"><?php echo _t('conf.profile.password_form'); ?></label>
<div class="group-controls">
<div class="stick">
diff --git a/app/views/user/validateEmail.phtml b/app/views/user/validateEmail.phtml
new file mode 100644
index 000000000..a246c222e
--- /dev/null
+++ b/app/views/user/validateEmail.phtml
@@ -0,0 +1,22 @@
+<div class="post">
+ <p>
+ <?php echo _t('user.email.validation.need_to', FreshRSS_Context::$system_conf->title); ?>
+ </p>
+
+ <p>
+ <?php echo _t('user.email.validation.email_sent_to', FreshRSS_Context::$user_conf->mail_login); ?>
+ </p>
+
+ <form action="<?php echo _url('user', 'sendValidationEmail'); ?>" method="post">
+ <input type="hidden" name="_csrf" value="<?php echo FreshRSS_Auth::csrfToken(); ?>" />
+ <button type="submit" class="btn">
+ <?php echo _t('user.email.validation.resend_email'); ?>
+ </button>
+ </form>
+
+ <p>
+ <small>
+ <?php echo _t('user.email.validation.change_email', _url('user', 'profile')); ?>
+ </small>
+ </p>
+</div>
diff --git a/app/views/user_mailer/email_need_validation.txt b/app/views/user_mailer/email_need_validation.txt
new file mode 100644
index 000000000..13b63c1af
--- /dev/null
+++ b/app/views/user_mailer/email_need_validation.txt
@@ -0,0 +1,5 @@
+<?php echo _t('user.mailer.email_need_validation.welcome', $this->username); ?>
+
+<?php echo _t('user.mailer.email_need_validation.body', $this->site_title); ?>
+
+<?php echo $this->validation_url; ?>