diff options
| author | 2019-12-03 23:11:06 +0100 | |
|---|---|---|
| committer | 2019-12-03 23:11:06 +0100 | |
| commit | d0f1f9f141a58e090d210c221a7c1745378b96a3 (patch) | |
| tree | 5d538ee048a14d29f8091d9e85cf391ada48ae83 | |
| parent | 15b8ef8f40f249ace343696df216f2d61f8249d0 (diff) | |
Separate the update API password endpoint (#2675)
* Extract hashPassword method from userController
* Extract and refactor fever key-related methods
* Move update of API password to dedicated action
* Simplify the controller by refactoring feverUtil
* Add locales
40 files changed, 292 insertions, 73 deletions
diff --git a/app/Controllers/apiController.php b/app/Controllers/apiController.php new file mode 100644 index 000000000..d096ba83f --- /dev/null +++ b/app/Controllers/apiController.php @@ -0,0 +1,47 @@ +<?php + +/** + * This controller manage API-related features. + */ +class FreshRSS_api_Controller extends Minz_ActionController { + /** + * This action updates the user API password. + * + * Parameter is: + * - apiPasswordPlain: the new user password + */ + public function updatePasswordAction() { + if (!FreshRSS_Auth::hasAccess()) { + Minz_Error::error(403); + } + + $return_url = array('c' => 'user', 'a' => 'profile'); + + if (!Minz_Request::isPost()) { + Minz_Request::forward($return_url, true); + } + + $apiPasswordPlain = Minz_Request::param('apiPasswordPlain', '', true); + if ($apiPasswordPlain == '') { + Minz_Request::forward($return_url, true); + } + + $username = Minz_Session::param('currentUser'); + $userConfig = FreshRSS_Context::$user_conf; + + $apiPasswordHash = FreshRSS_password_Util::hash($apiPasswordPlain); + $userConfig->apiPasswordHash = $apiPasswordHash; + + $feverKey = FreshRSS_fever_Util::updateKey($username, $apiPasswordPlain); + if (!$feverKey) { + Minz_Request::bad(_t('feedback.api.password.failed'), $return_url); + } + + $userConfig->feverKey = $feverKey; + if ($userConfig->save()) { + Minz_Request::good(_t('feedback.api.password.updated'), $return_url); + } else { + Minz_Request::bad(_t('feedback.api.password.failed'), $return_url); + } + } +} diff --git a/app/Controllers/javascriptController.php b/app/Controllers/javascriptController.php index c84e5483b..b22e2c127 100755 --- a/app/Controllers/javascriptController.php +++ b/app/Controllers/javascriptController.php @@ -47,7 +47,7 @@ class FreshRSS_javascript_Controller extends Minz_ActionController { Minz_Log::notice('Nonce failure due to invalid username!'); } //Failure: Return random data. - $this->view->salt1 = sprintf('$2a$%02d$', FreshRSS_user_Controller::BCRYPT_COST); + $this->view->salt1 = sprintf('$2a$%02d$', FreshRSS_password_Util::BCRYPT_COST); $alphabet = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for ($i = 22; $i > 0; $i--) { $this->view->salt1 .= $alphabet[mt_rand(0, 63)]; diff --git a/app/Controllers/userController.php b/app/Controllers/userController.php index 05e7475e7..3a48e65e3 100644 --- a/app/Controllers/userController.php +++ b/app/Controllers/userController.php @@ -4,17 +4,6 @@ * Controller to handle user actions. */ class FreshRSS_user_Controller extends Minz_ActionController { - // Will also have to be computed client side on mobile devices, - // so do not use a too high cost - const BCRYPT_COST = 9; - - public static function hashPassword($passwordPlain) { - $passwordHash = password_hash($passwordPlain, PASSWORD_BCRYPT, array('cost' => self::BCRYPT_COST)); - $passwordPlain = ''; - $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); //Compatibility with bcrypt.js - return $passwordHash == '' ? '' : $passwordHash; - } - /** * The username is also used as folder name, file name, and part of SQL table name. * '_' is a reserved internal username. @@ -25,15 +14,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { return preg_match('/^' . self::USERNAME_PATTERN . '$/', $username) === 1; } - public static function deleteFeverKey($username) { - $userConfig = get_user_configuration($username); - if ($userConfig !== null && ctype_xdigit($userConfig->feverKey)) { - return @unlink(DATA_PATH . '/fever/.key-' . sha1(FreshRSS_Context::$system_conf->salt) . '-' . $userConfig->feverKey . '.txt'); - } - return false; - } - - public static function updateUser($user, $email, $passwordPlain, $apiPasswordPlain, $userConfigUpdated = array()) { + public static function updateUser($user, $email, $passwordPlain, $userConfigUpdated = array()) { $userConfig = get_user_configuration($user); if ($userConfig === null) { return false; @@ -51,33 +32,10 @@ class FreshRSS_user_Controller extends Minz_ActionController { } if ($passwordPlain != '') { - $passwordHash = self::hashPassword($passwordPlain); + $passwordHash = FreshRSS_password_Util::hash($passwordPlain); $userConfig->passwordHash = $passwordHash; } - if ($apiPasswordPlain != '') { - $apiPasswordHash = self::hashPassword($apiPasswordPlain); - $userConfig->apiPasswordHash = $apiPasswordHash; - - $feverPath = DATA_PATH . '/fever/'; - - if (!file_exists($feverPath)) { - @mkdir($feverPath, 0770, true); - } - - if (!is_writable($feverPath)) { - Minz_Log::error("Could not save Fever API credentials. The directory does not have write access."); - } else { - self::deleteFeverKey($user); - $userConfig->feverKey = strtolower(md5("{$user}:{$apiPasswordPlain}")); - $ok = file_put_contents($feverPath . '.key-' . sha1(FreshRSS_Context::$system_conf->salt) . '-' . $userConfig->feverKey . '.txt', $user) !== false; - - if (!$ok) { - Minz_Log::warning('Could not save Fever API credentials. Unknown error.', ADMIN_LOG); - } - } - } - if (is_array($userConfigUpdated)) { foreach ($userConfigUpdated as $configName => $configValue) { if ($configValue !== null) { @@ -100,10 +58,8 @@ class FreshRSS_user_Controller extends Minz_ActionController { Minz_Request::_param('newPasswordPlain'); //Discard plain-text password ASAP $_POST['newPasswordPlain'] = ''; - $apiPasswordPlain = Minz_Request::param('apiPasswordPlain', '', true); - $username = Minz_Request::param('username'); - $ok = self::updateUser($username, null, $passwordPlain, $apiPasswordPlain, array( + $ok = self::updateUser($username, null, $passwordPlain, array( 'token' => Minz_Request::param('token', null), )); @@ -150,8 +106,6 @@ class FreshRSS_user_Controller extends Minz_ActionController { Minz_Request::_param('newPasswordPlain'); //Discard plain-text password ASAP $_POST['newPasswordPlain'] = ''; - $apiPasswordPlain = Minz_Request::param('apiPasswordPlain', '', true); - if ($system_conf->force_email_validation && empty($email)) { Minz_Request::bad( _t('user.email.feedback.required'), @@ -170,7 +124,6 @@ class FreshRSS_user_Controller extends Minz_ActionController { Minz_Session::param('currentUser'), $email, $passwordPlain, - $apiPasswordPlain, array( 'token' => Minz_Request::param('token', null), ) @@ -239,7 +192,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { } } - public static function createUser($new_user_name, $email, $passwordPlain, $apiPasswordPlain = '', $userConfigOverride = [], $insertDefaultFeeds = true) { + public static function createUser($new_user_name, $email, $passwordPlain, $userConfigOverride = [], $insertDefaultFeeds = true) { $userConfig = []; $customUserConfigPath = join_path(DATA_PATH, 'config-user.custom.php'); @@ -291,7 +244,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { } } - $ok &= self::updateUser($new_user_name, $email, $passwordPlain, $apiPasswordPlain); + $ok &= self::updateUser($new_user_name, $email, $passwordPlain); } return $ok; } @@ -346,7 +299,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { ); } - $ok = self::createUser($new_user_name, $email, $passwordPlain, '', array('language' => $new_user_language)); + $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(); @@ -386,7 +339,7 @@ class FreshRSS_user_Controller extends Minz_ActionController { $user_data = join_path(DATA_PATH, 'users', $username); $ok &= is_dir($user_data); if ($ok) { - self::deleteFeverKey($username); + FreshRSS_fever_Util::deleteKey($username); $oldUserDAO = FreshRSS_Factory::createUserDao($username); $ok &= $oldUserDAO->deleteUser(); $ok &= recursive_unlink($user_data); diff --git a/app/Utils/feverUtil.php b/app/Utils/feverUtil.php new file mode 100644 index 000000000..83921943c --- /dev/null +++ b/app/Utils/feverUtil.php @@ -0,0 +1,80 @@ +<?php + +class FreshRSS_fever_Util { + const FEVER_PATH = DATA_PATH . '/fever'; + + /** + * Make sure the fever path exists and is writable. + * + * @return boolean true if the path is writable, else false. + */ + public static function checkFeverPath() { + if (!file_exists(self::FEVER_PATH)) { + @mkdir(self::FEVER_PATH, 0770, true); + } + + $ok = is_writable(self::FEVER_PATH); + if (!$ok) { + Minz_Log::error("Could not save Fever API credentials. The directory does not have write access."); + } + return $ok; + } + + /** + * Return the corresponding path for a fever key. + * + * @param string + * @return string + */ + public static function getKeyPath($feverKey) { + $salt = sha1(FreshRSS_Context::$system_conf->salt); + return self::FEVER_PATH . '/.key-' . $salt . '-' . $feverKey . '.txt'; + } + + /** + * Update the fever key of a user. + * + * @param string + * @param string + * @return string the Fever key, or false if the update failed + */ + public static function updateKey($username, $passwordPlain) { + $ok = self::checkFeverPath(); + if (!$ok) { + return false; + } + + self::deleteKey($username); + + $feverKey = strtolower(md5("{$username}:{$passwordPlain}")); + $feverKeyPath = self::getKeyPath($feverKey); + $res = file_put_contents($feverKeyPath, $username); + if ($res !== false) { + return $feverKey; + } else { + Minz_Log::warning('Could not save Fever API credentials. Unknown error.', ADMIN_LOG); + return false; + } + } + + /** + * Delete the Fever key of a user. + * + * @param string + * @return boolean true if the deletion succeeded, else false. + */ + public static function deleteKey($username) { + $userConfig = get_user_configuration($username); + if ($userConfig === null) { + return false; + } + + $feverKey = $userConfig->feverKey; + if (!ctype_xdigit($feverKey)) { + return false; + } + + $feverKeyPath = self::getKeyPath($feverKey); + return @unlink($feverKeyPath); + } +} diff --git a/app/Utils/passwordUtil.php b/app/Utils/passwordUtil.php new file mode 100644 index 000000000..fd71d4b72 --- /dev/null +++ b/app/Utils/passwordUtil.php @@ -0,0 +1,27 @@ +<?php + +class FreshRSS_password_Util { + // Will also have to be computed client side on mobile devices, + // so do not use a too high cost + const BCRYPT_COST = 9; + + /** + * Return a hash of a plain password, using BCRYPT + * + * @param string + * @return string + */ + public static function hash($passwordPlain) { + $passwordHash = password_hash( + $passwordPlain, + PASSWORD_BCRYPT, + array('cost' => self::BCRYPT_COST) + ); + $passwordPlain = ''; + + // Compatibility with bcrypt.js + $passwordHash = preg_replace('/^\$2[xy]\$/', '\$2a\$', $passwordHash); + + return $passwordHash == '' ? '' : $passwordHash; + } +} diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 056e895a7..f066ac9a4 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Správa profilu', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Smazání účtu', 'warn' => 'Váš účet bude smazán spolu se všemi souvisejícími daty', diff --git a/app/i18n/cz/feedback.php b/app/i18n/cz/feedback.php index 3d0dcbc96..ad3d38cf0 100644 --- a/app/i18n/cz/feedback.php +++ b/app/i18n/cz/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Nemáte oprávnění přistupovat na tuto stránku', 'not_found' => 'Tato stránka neexistuje', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Nastal problém s konfigurací přihlašovacího systému. Zkuste to prosím později.', diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php index b08694eee..2d9b91260 100644 --- a/app/i18n/de/conf.php +++ b/app/i18n/de/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Profil-Verwaltung', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Accountlöschung', 'warn' => 'Dein Account und alle damit bezogenen Daten werden gelöscht.', diff --git a/app/i18n/de/feedback.php b/app/i18n/de/feedback.php index 269069162..446aa2a04 100644 --- a/app/i18n/de/feedback.php +++ b/app/i18n/de/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Sie haben nicht die Berechtigung, diese Seite aufzurufen', 'not_found' => 'Sie suchen nach einer Seite, die nicht existiert', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Während der Konfiguration des Authentifikationssystems trat ein Fehler auf. Bitte versuchen Sie es später erneut.', diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index 2d4e06550..f01de649a 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Profile management', + 'api' => 'API management', 'delete' => array( '_' => 'Account deletion', 'warn' => 'Your account and all related data will be deleted.', diff --git a/app/i18n/en/feedback.php b/app/i18n/en/feedback.php index 2322a62cc..89bbd4154 100644 --- a/app/i18n/en/feedback.php +++ b/app/i18n/en/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'You don’t have permission to access this page', 'not_found' => 'You are looking for a page which doesn’t exist', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', + 'updated' => 'Your password has been modified', + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'A problem occured during authentication system configuration. Please retry later.', diff --git a/app/i18n/es/conf.php b/app/i18n/es/conf.php index 7a93a87de..fcbe9b984 100755 --- a/app/i18n/es/conf.php +++ b/app/i18n/es/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Administración de perfiles', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Borrar cuenta', 'warn' => 'Tu cuenta y todos los datos asociados serán eliminados.', diff --git a/app/i18n/es/feedback.php b/app/i18n/es/feedback.php index d70ccfe8a..5a7358b0d 100755 --- a/app/i18n/es/feedback.php +++ b/app/i18n/es/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'No dispones de permiso para acceder a esta página', 'not_found' => 'La página que buscas no existe', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Hubo un problema durante la configuración del sistema de idenfificación. Por favor, inténtalo más tarde.', diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php index 020c94085..b51d123f1 100644 --- a/app/i18n/fr/conf.php +++ b/app/i18n/fr/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Gestion du profil', + 'api' => 'Gestion de l’API', 'delete' => array( '_' => 'Suppression du compte', 'warn' => 'Le compte et toutes les données associées vont être supprimées.', diff --git a/app/i18n/fr/feedback.php b/app/i18n/fr/feedback.php index 328113c25..f4b3ba245 100644 --- a/app/i18n/fr/feedback.php +++ b/app/i18n/fr/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Vous n’avez pas le droit d’accéder à cette page !', 'not_found' => 'La page que vous cherchez n’existe pas !', ), + 'api' => array( + 'password' => array( + 'failed' => 'Votre mot de passe n’a pas pu être mis à jour', + 'updated' => 'Votre mot de passe a été mis à jour', + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Un problème est survenu lors de la configuration de votre système d’authentification. Veuillez réessayer plus tard.', diff --git a/app/i18n/he/conf.php b/app/i18n/he/conf.php index b987f21f4..d83d688d5 100644 --- a/app/i18n/he/conf.php +++ b/app/i18n/he/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Profile management', //TODO - Translation + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Account deletion', //TODO - Translation 'warn' => 'Your account and all related data will be deleted.', //TODO - Translation diff --git a/app/i18n/he/feedback.php b/app/i18n/he/feedback.php index f972173cb..026e93450 100644 --- a/app/i18n/he/feedback.php +++ b/app/i18n/he/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'אין לך הרשאות לצפות בדף זה', 'not_found' => 'הדף הזה לא נמצא', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'אירעה שגיאה במהלך הגדרת מערכת האימיות. אנא נסו שוב מאוחר יותר.', diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php index 4bdaad33d..6dd390ebd 100644 --- a/app/i18n/it/conf.php +++ b/app/i18n/it/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Gestione profili', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Cancellazione account', 'warn' => 'Il tuo account e tutti i dati associati saranno cancellati.', diff --git a/app/i18n/it/feedback.php b/app/i18n/it/feedback.php index ca7879904..f137de9e8 100644 --- a/app/i18n/it/feedback.php +++ b/app/i18n/it/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Non hai i permessi per accedere a questa pagina', 'not_found' => 'Pagina non disponibile', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Si è verificato un problema alla configurazione del sistema di autenticazione. Per favore riprova più tardi.', diff --git a/app/i18n/kr/conf.php b/app/i18n/kr/conf.php index 1e77d0098..219feab49 100644 --- a/app/i18n/kr/conf.php +++ b/app/i18n/kr/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => '프로필 관리', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => '계정 삭제', 'warn' => '당신의 계정과 관련된 모든 데이터가 삭제됩니다.', diff --git a/app/i18n/kr/feedback.php b/app/i18n/kr/feedback.php index 0e31536f8..1ea58388b 100644 --- a/app/i18n/kr/feedback.php +++ b/app/i18n/kr/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => '이 페이지에 접근할 수 있는 권한이 없습니다', 'not_found' => '이 페이지는 존재하지 않습니다', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => '인증 시스템을 설정하는 동안 문제가 발생했습니다. 잠시 후 다시 시도하세요.', diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php index ca6627cbb..fdd82f7c2 100644 --- a/app/i18n/nl/conf.php +++ b/app/i18n/nl/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Profiel beheer', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Account verwijderen', 'warn' => 'Uw account en alle gerelateerde gegvens worden verwijderd.', diff --git a/app/i18n/nl/feedback.php b/app/i18n/nl/feedback.php index 97e1a71b8..dafbb9d68 100644 --- a/app/i18n/nl/feedback.php +++ b/app/i18n/nl/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'U hebt geen rechten om deze pagina te bekijken.', 'not_found' => 'Deze pagina bestaat niet', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Er is een probleem opgetreden tijdens de controle van de systeemconfiguratie. Probeer het later nog eens.', diff --git a/app/i18n/oc/conf.php b/app/i18n/oc/conf.php index e123c03c5..98758be28 100644 --- a/app/i18n/oc/conf.php +++ b/app/i18n/oc/conf.php @@ -51,6 +51,7 @@ return array( ), 'profile' => array( '_' => 'Gestion del perfil', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Supression del compte', 'warn' => 'Lo compte e totas las donadas ligadas seràn suprimits.', diff --git a/app/i18n/oc/feedback.php b/app/i18n/oc/feedback.php index 7f7d05dbd..a37ad2ae2 100644 --- a/app/i18n/oc/feedback.php +++ b/app/i18n/oc/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Avètz pas l’autorizacion d’accedir a aquesta pagina', 'not_found' => 'La pagina que cercatz existís pas', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Un problèma es aparegut pendent la configuracion del sistèma d’autentificacion. Tonatz ensajar ai tard.', diff --git a/app/i18n/pt-br/conf.php b/app/i18n/pt-br/conf.php index 5e43cc373..d2a60aba8 100644 --- a/app/i18n/pt-br/conf.php +++ b/app/i18n/pt-br/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Gerenciamento de perfil', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Remover conta', 'warn' => 'Sua conta e todos os dados relacionados serão removidos.', diff --git a/app/i18n/pt-br/feedback.php b/app/i18n/pt-br/feedback.php index 816bbf43b..d15080964 100644 --- a/app/i18n/pt-br/feedback.php +++ b/app/i18n/pt-br/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Você não tem permissão para acessar esta página', 'not_found' => 'VocÊ está buscando por uma página que não existe', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Um problema ocorreu durante o sistema de configuração para autenticação. Por favor tente mais tarde.', diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php index 7a80587f8..96a307976 100644 --- a/app/i18n/ru/conf.php +++ b/app/i18n/ru/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Profile management', //TODO - Translation + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Account deletion', //TODO - Translation 'warn' => 'Your account and all the related data will be deleted.', //TODO - Translation diff --git a/app/i18n/ru/feedback.php b/app/i18n/ru/feedback.php index 7b859fcdd..449d01ee4 100644 --- a/app/i18n/ru/feedback.php +++ b/app/i18n/ru/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'You don’t have permission to access this page', //TODO - Translation 'not_found' => 'You are looking for a page which doesn’t exist', //TODO - Translation ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'A problem occured during authentication system configuration. Please retry later.', //TODO - Translation diff --git a/app/i18n/sk/conf.php b/app/i18n/sk/conf.php index 2e2289b79..be6fdce4f 100644 --- a/app/i18n/sk/conf.php +++ b/app/i18n/sk/conf.php @@ -42,6 +42,7 @@ return array( ), 'profile' => array( '_' => 'Správca profilu', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Vymazanie účtu', 'warn' => 'Váš účet a všetky údaje v ňom budú vymazané.', diff --git a/app/i18n/sk/feedback.php b/app/i18n/sk/feedback.php index 9aee79068..5bccd8259 100644 --- a/app/i18n/sk/feedback.php +++ b/app/i18n/sk/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Na prístup k tejto stránke nemáte oprávnenie', 'not_found' => 'Hľadáte stránku, ktorá neexistuje', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Nastavl problém pri nastavovaní prihlasovacieho systému. Prosím, skúste to znova neskôr.', diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php index c8ea78efa..25eaedc55 100644 --- a/app/i18n/tr/conf.php +++ b/app/i18n/tr/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => 'Profil yönetimi', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => 'Hesap silme', 'warn' => 'Hesabınız ve tüm verileriniz silinecek.', diff --git a/app/i18n/tr/feedback.php b/app/i18n/tr/feedback.php index fc1e59bbc..73489c723 100644 --- a/app/i18n/tr/feedback.php +++ b/app/i18n/tr/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => 'Bu sayfaya erişim yetkiniz yok', 'not_found' => 'Varolmayan bir sayfa arıyorsunuz', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => 'Sistem yapılandırma kimlik doğrulaması sırasında hata oldu. Lütfen daha sonra tekrar deneyin.', diff --git a/app/i18n/zh-cn/conf.php b/app/i18n/zh-cn/conf.php index a7404bc58..485da16f2 100644 --- a/app/i18n/zh-cn/conf.php +++ b/app/i18n/zh-cn/conf.php @@ -50,6 +50,7 @@ return array( ), 'profile' => array( '_' => '帐户管理', + 'api' => 'API management', // TODO - Translation 'delete' => array( '_' => '账户删除', 'warn' => '你的帐户和所有相关数据都将被删除。', diff --git a/app/i18n/zh-cn/feedback.php b/app/i18n/zh-cn/feedback.php index e8ee969b0..9dbc45cf5 100644 --- a/app/i18n/zh-cn/feedback.php +++ b/app/i18n/zh-cn/feedback.php @@ -8,6 +8,12 @@ return array( 'denied' => '你无权访问此页面', 'not_found' => '你寻找的页面不存在', ), + 'api' => array( + 'password' => array( + 'failed' => 'Your password cannot be modified', // TODO - Translation + 'updated' => 'Your password has been modified', // TODO - Translation + ), + ), 'auth' => array( 'form' => array( 'not_set' => '配置认证方式时出错。请稍后重试。', diff --git a/app/install.php b/app/install.php index 557ae9eab..3737e2ccc 100644 --- a/app/install.php +++ b/app/install.php @@ -221,7 +221,6 @@ function saveStep3() { $_SESSION['default_user'], '', //TODO: Add e-mail $password_plain, - '', [ 'language' => $_SESSION['language'], ] diff --git a/app/views/user/profile.phtml b/app/views/user/profile.phtml index b8bb5cee9..5357c2bfd 100644 --- a/app/views/user/profile.phtml +++ b/app/views/user/profile.phtml @@ -48,19 +48,6 @@ </div> </div> - <?php if (FreshRSS_Context::$system_conf->api_enabled) { ?> - <div class="form-group"> - <label class="group-name" for="apiPasswordPlain"><?= _t('conf.profile.password_api') ?></label> - <div class="group-controls"> - <div class="stick"> - <input type="password" id="apiPasswordPlain" name="apiPasswordPlain" autocomplete="new-password" pattern=".{7,}" <?= cryptAvailable() ? '' : 'disabled="disabled" ' ?>/> - <a class="btn toggle-password" data-toggle="apiPasswordPlain"><?= _i('key') ?></a> - </div> - <?= _i('help') ?> <kbd><a href="../api/"><?= Minz_Url::display('/api/', 'html', true) ?></a></kbd> - </div> - </div> - <?php } ?> - <?php if (FreshRSS_Auth::accessNeedsAction()) { ?> <div class="form-group"> <label class="group-name" for="token"><?= _t('admin.auth.token') ?></label> @@ -82,6 +69,30 @@ </div> </form> + <?php if (FreshRSS_Context::$system_conf->api_enabled) { ?> + <form method="post" action="<?= _url('api', 'updatePassword') ?>"> + <input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" /> + <legend><?= _t('conf.profile.api') ?></legend> + + <div class="form-group"> + <label class="group-name" for="apiPasswordPlain"><?= _t('conf.profile.password_api') ?></label> + <div class="group-controls"> + <div class="stick"> + <input type="password" id="apiPasswordPlain" name="apiPasswordPlain" autocomplete="new-password" pattern=".{7,}" <?= cryptAvailable() ? '' : 'disabled="disabled" ' ?>/> + <a class="btn toggle-password" data-toggle="apiPasswordPlain"><?= _i('key') ?></a> + </div> + <?= _i('help') ?> <kbd><a href="../api/"><?= Minz_Url::display('/api/', 'html', true) ?></a></kbd> + </div> + </div> + + <div class="form-group form-actions"> + <div class="group-controls"> + <button type="submit" class="btn btn-important"><?= _t('gen.action.submit') ?></button> + </div> + </div> + </form> + <?php } ?> + <?php if (!FreshRSS_Auth::hasAccess('admin')) { ?> <form id="crypto-form" method="post" action="<?= _url('user', 'delete') ?>"> <input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" /> diff --git a/cli/_update-or-create-user.php b/cli/_update-or-create-user.php index 43b86a4a9..3217a07ea 100644 --- a/cli/_update-or-create-user.php +++ b/cli/_update-or-create-user.php @@ -4,7 +4,6 @@ require(__DIR__ . '/_cli.php'); $params = array( 'user:', 'password:', - 'api_password:', 'language:', 'email:', 'token:', @@ -24,7 +23,7 @@ $options = getopt('', $params); if (!validateOptions($argv, $params) || empty($options['user'])) { fail('Usage: ' . basename($_SERVER['SCRIPT_FILENAME']) . - " --user username ( --password 'password' --api_password 'api_password'" . + " --user username ( --password 'password'" . " --language en --email user@example.net --token 'longRandomString'" . ($isUpdate ? '' : '--no_default_feeds') . " --purge_after_months 3 --feed_min_articles_default 50 --feed_ttl_default 3600" . diff --git a/cli/create-user.php b/cli/create-user.php index 7e0a031d9..9e978ee3c 100755 --- a/cli/create-user.php +++ b/cli/create-user.php @@ -20,7 +20,6 @@ $ok = FreshRSS_user_Controller::createUser( $username, empty($options['mail_login']) ? '' : $options['mail_login'], empty($options['password']) ? '' : $options['password'], - empty($options['api_password']) ? '' : $options['api_password'], $values, !isset($options['no_default_feeds']) ); diff --git a/cli/update-user.php b/cli/update-user.php index 8067dadd3..02da16d5a 100755 --- a/cli/update-user.php +++ b/cli/update-user.php @@ -11,7 +11,6 @@ $ok = FreshRSS_user_Controller::updateUser( $username, empty($options['mail_login']) ? null : $options['mail_login'], empty($options['password']) ? '' : $options['password'], - empty($options['api_password']) ? '' : $options['api_password'], $values); if (!$ok) { |
