From 75632e70f0d49048f4ce72a0fa8bbcbcd7b2d312 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 29 Aug 2019 12:02:05 +0200 Subject: 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 * Set PHPMailer validator to html5 before sending email * fixup! Remove trailing comma in userController --- app/Controllers/authController.php | 1 + app/Controllers/configureController.php | 12 ++ app/Controllers/userController.php | 195 +++++++++++++++++++++++- app/FreshRSS.php | 18 +++ app/Mailers/UserMailer.php | 31 ++++ app/Models/ConfigurationSetter.php | 4 + app/i18n/cz/admin.php | 1 + app/i18n/cz/conf.php | 1 + app/i18n/cz/gen.php | 1 + app/i18n/cz/user.php | 32 ++++ app/i18n/de/admin.php | 1 + app/i18n/de/conf.php | 1 + app/i18n/de/gen.php | 1 + app/i18n/de/user.php | 32 ++++ app/i18n/en/admin.php | 1 + app/i18n/en/conf.php | 1 + app/i18n/en/gen.php | 1 + app/i18n/en/user.php | 32 ++++ app/i18n/es/admin.php | 1 + app/i18n/es/conf.php | 1 + app/i18n/es/gen.php | 1 + app/i18n/es/user.php | 32 ++++ app/i18n/fr/admin.php | 1 + app/i18n/fr/conf.php | 1 + app/i18n/fr/gen.php | 1 + app/i18n/fr/user.php | 32 ++++ app/i18n/he/admin.php | 1 + app/i18n/he/conf.php | 1 + app/i18n/he/gen.php | 1 + app/i18n/he/user.php | 32 ++++ app/i18n/it/admin.php | 1 + app/i18n/it/conf.php | 1 + app/i18n/it/gen.php | 1 + app/i18n/it/user.php | 32 ++++ app/i18n/kr/admin.php | 1 + app/i18n/kr/conf.php | 1 + app/i18n/kr/gen.php | 1 + app/i18n/kr/user.php | 32 ++++ app/i18n/nl/admin.php | 1 + app/i18n/nl/conf.php | 1 + app/i18n/nl/gen.php | 1 + app/i18n/nl/user.php | 32 ++++ app/i18n/oc/admin.php | 1 + app/i18n/oc/conf.php | 1 + app/i18n/oc/gen.php | 1 + app/i18n/oc/user.php | 32 ++++ app/i18n/pt-br/admin.php | 1 + app/i18n/pt-br/conf.php | 1 + app/i18n/pt-br/gen.php | 1 + app/i18n/pt-br/user.php | 32 ++++ app/i18n/ru/admin.php | 1 + app/i18n/ru/conf.php | 1 + app/i18n/ru/gen.php | 1 + app/i18n/ru/user.php | 32 ++++ app/i18n/tr/admin.php | 1 + app/i18n/tr/conf.php | 1 + app/i18n/tr/gen.php | 1 + app/i18n/tr/user.php | 32 ++++ app/i18n/zh-cn/admin.php | 1 + app/i18n/zh-cn/conf.php | 1 + app/i18n/zh-cn/gen.php | 1 + app/i18n/zh-cn/user.php | 32 ++++ app/layout/simple.phtml | 66 ++++++++ app/views/auth/register.phtml | 9 ++ app/views/configure/system.phtml | 20 ++- app/views/user/manage.phtml | 11 ++ app/views/user/profile.phtml | 13 +- app/views/user/validateEmail.phtml | 22 +++ app/views/user_mailer/email_need_validation.txt | 5 + 69 files changed, 887 insertions(+), 10 deletions(-) create mode 100644 app/Mailers/UserMailer.php create mode 100644 app/i18n/cz/user.php create mode 100644 app/i18n/de/user.php create mode 100644 app/i18n/en/user.php create mode 100644 app/i18n/es/user.php create mode 100644 app/i18n/fr/user.php create mode 100644 app/i18n/he/user.php create mode 100644 app/i18n/it/user.php create mode 100644 app/i18n/kr/user.php create mode 100644 app/i18n/nl/user.php create mode 100644 app/i18n/oc/user.php create mode 100644 app/i18n/pt-br/user.php create mode 100644 app/i18n/ru/user.php create mode 100644 app/i18n/tr/user.php create mode 100644 app/i18n/zh-cn/user.php create mode 100644 app/layout/simple.phtml create mode 100644 app/views/user/validateEmail.phtml create mode 100644 app/views/user_mailer/email_need_validation.txt (limited to 'app') 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(); @@ -272,6 +335,122 @@ class FreshRSS_user_Controller extends Minz_ActionController { return $ok; } + /** + * 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. * 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 @@ +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
(tzn. pro mobilní aplikace)', 'password_form' => 'Heslo
(pro přihlášení webovým formulářem)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(z. B. für mobile Anwendungen)', 'password_form' => 'Passwort
(für die Anmeldemethode per Webformular)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(e.g., for mobile apps)', 'password_form' => 'Password
(for the Web-form login method)', '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 @@ + 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 on the profile page.', + 'email_sent_to' => 'We sent you an email at %s, 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
(para apps móviles, por ej.)', 'password_form' => 'Contraseña
(para el método de identificación por formulario web)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(ex. : pour applis mobiles)', 'password_form' => 'Mot de passe
(pour connexion par formulaire)', '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 @@ + 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 dans votre profil.', + 'email_sent_to' => 'Nous venons d’envoyer un email à %s, 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
(לדוגמה ליישומים סלולריים)', 'password_form' => 'סיסמה
(לשימוש בטפוס ההרשמה)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(e.g., per applicazioni mobili)', 'password_form' => 'Password
(per il login classico)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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 암호
(예: 모바일 애플리케이션)', 'password_form' => '암호
(웹폼 로그인 방식 사용시)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(e.g., voor mobiele apps)', 'password_form' => 'Wachtwoord
(voor de Web-formulier log in methode)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(ex. : per las aplicacions mobil)', 'password_form' => 'Senhal API
(ex. : per la connexion via formulari)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(p.s., para aplicativos móveis)', 'password_form' => 'Senha
(para o método de formulário web)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(e.g., for mobile apps)', //TODO - Translation 'password_form' => 'Password
(for the Web-form login method)', //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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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
(ör. mobil uygulamalar için)', 'password_form' => 'Şifre
(Tarayıcı girişi için)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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 密码
(例如,用于手机 APP)', 'password_form' => '密码
(用于 Web-form 登录方式)', '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 @@ + 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 on the profile page.', //TODO - Translation + 'email_sent_to' => 'We sent you an email at %s, 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 @@ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + + + + () + + +
+
+ + render(); ?> +
+ +notification)) { + $msg = $this->notification['content']; + $status = $this->notification['type']; + + invalidateHttpCache(); + } +?> +
+ + +
+ + + 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 @@ + show_email_field) { ?> +
+ + +
+ +
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 @@
+ can_enable_email_validation) { ?> +
+
+ +
+
+ +
@@ -51,7 +69,7 @@
- +
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 @@
+ show_email_field) { ?> +
+ +
+ +
+
+ +
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 @@ -partial('aside_configure'); ?> +disable_aside) { + $this->partial('aside_configure'); + } +?>
@@ -18,6 +22,13 @@
+
+ +
+ +
+
+
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 @@ +
+

+ title); ?> +

+ +

+ mail_login); ?> +

+ +
+ + +
+ +

+ + + +

+
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 @@ +username); ?> + +site_title); ?> + +validation_url; ?> -- cgit v1.2.3