diff --git a/app/app.php b/app/app.php index 78d313b..ac1960e 100644 --- a/app/app.php +++ b/app/app.php @@ -1,6 +1,6 @@ NULL, '1.0.12' => NULL, + '1.0.13' => NULL, ]; // Settings that must be renamed from NAME to NEW NAME and DELETE old NAME $settings_rename = []; diff --git a/app/routes/route.settings.php b/app/routes/route.settings.php index 71f7ac4..9911dae 100644 --- a/app/routes/route.settings.php +++ b/app/routes/route.settings.php @@ -9,7 +9,7 @@ Copyright (C) Rodolfo Berrios A. All rights reserved. - + BY USING THIS SOFTWARE YOU DECLARE TO ACCEPT THE CHEVERETO EULA http://chevereto.com/license @@ -17,46 +17,46 @@ $route = function($handler) { try { - + if($_POST and !$handler::checkAuthToken($_REQUEST['auth_token'])) { $handler->template = 'request-denied'; return; } - + $logged_user = CHV\Login::getUser(); - + if(!$logged_user) { G\redirect('login'); } - + // User status override redirect CHV\User::statusRedirect($logged_user['status']); - + // Dashboard hack $handler->template = 'settings'; $is_dashboard_user = $handler::getCond('dashboard_user'); - + // Request log if(!$is_dashboard_user) { $request_log = CHV\Requestlog::getCounts('account-edit', 'fail'); } - + // Editable values $allowed_to_edit = ['name', 'username', 'email', 'avatar_filename', 'website', 'background_filename', 'timezone', 'language', 'status', 'is_admin', 'image_keep_exif', 'image_expiration', 'newsletter_subscribe', 'bio', 'show_nsfw_listings', 'is_private']; - + if(CHV\getSetting('enable_expirable_uploads')) { unset($allowed_to_edit['image_expiration']); } - + // User handle $user = $is_dashboard_user ? CHV\User::getSingle($handler->request[1], 'id') : $logged_user; $is_owner = $user['id'] == CHV\Login::getUser()['id']; - + // Update the lang displayed on change if(in_array('language', $allowed_to_edit) and isset($_POST['language']) and $logged_user['language'] !== $_POST['language'] and $logged_user['id'] == $user['id'] and array_key_exists($_POST['language'], CHV\L10n::getEnabledLanguages())) { CHV\L10n::processTranslation($_POST['language']); } - + // Settings routes $routes = [ 'account' => _s('Account'), @@ -65,26 +65,26 @@ $route = function($handler) { 'homepage' => _s('Homepage') ]; $default_route = 'account'; - + if(CHV\getSetting('website_mode') == 'personal' and CHV\getSetting('website_mode_personal_routing') !== '/' and $logged_user['id'] == CHV\getSetting('website_mode_personal_uid')) { $route_homepage = TRUE; } - + $is_email_required = TRUE; // Don't require email for admin when editing users if($handler::getCond('admin') AND !$is_owner) { $is_email_required = FALSE; } - + $doing_level = $is_dashboard_user ? 2 : 0; $doing = $handler->request[$doing_level]; if(!$user or $handler->request[$doing_level+1] or (!is_null($doing) and !array_key_exists($doing, $routes))) { return $handler->issue404(); } - + if($doing == '') $doing = $default_route; - + // Populate the routes foreach($routes as $route => $label) { $aux = str_replace('_', '-', $route); @@ -101,42 +101,42 @@ $route = function($handler) { 'current' => $handler::getCond('settings_'.$aux) ); } - + $handler::setVar('settings_menu', $settings_menu); - + if(!array_key_exists($doing, $routes)) { return $handler->issue404(); } - + // Safe print $_POST - $SAFE_POST = $handler::getVar('safe_post'); - + $SAFE_POST = $handler::getVar('safe_post'); + // conds $is_error = false; $is_changed = false; $captcha_needed = false; - + // vars $input_errors = array(); $error_message = NULL; $changed_email_message = NULL; - + if($_POST) { - + $field_limits = 255; - + foreach($allowed_to_edit as $k) { if($_POST[$k]) { $_POST[$k] = substr($_POST[$k], 0, $field_limits); } } - + // Input validations switch($doing) { - + case NULL: case 'account': - + $checkboxes = ['upload_image_exif', 'newsletter_subscribe', 'show_nsfw_listings', 'is_private']; foreach($checkboxes as $k) { if(!isset($_POST[$k])) { @@ -144,9 +144,9 @@ $route = function($handler) { } $_POST[$k] = in_array($_POST[$k], ['On', 1]) ? 1 : 0; } - + G\nullify_string($_POST['image_expiration']); - + $__post = []; $__safe_post = []; foreach(['username', 'email'] as $v) { @@ -156,25 +156,25 @@ $route = function($handler) { $__safe_post[$v] = G\safe_html($_POST[$v]); } } - + $handler::updateVar('post', $__post); $handler::updateVar('safe_post', $__safe_post); - + if(!CHV\User::isValidUsername($_POST['username'])) { $input_errors['username'] = _s('Invalid username'); } - + if($is_email_required and !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { $input_errors['email'] = _s('Invalid email'); } - + if(CHV\getSetting('enable_expirable_uploads')) { // Image expire time if($_POST['image_expiration'] !== NULL && (!G\dateinterval($_POST['image_expiration']) || !array_key_exists($_POST['image_expiration'], CHV\Image::getAvailableExpirations()))) { $input_errors['image_expiration'] = _s('Invalid image expiration: %s', $_POST['image_expiration']); } } - + if(!array_key_exists($_POST['language'], CHV\get_available_languages())) { $_POST['language'] = CHV\getSetting('default_language'); } @@ -185,17 +185,17 @@ $route = function($handler) { if(count($input_errors) > 0) { $is_error = true; } - + if(!$is_error) { - + $user_db = CHV\DB::get('users', ['username' => $_POST['username'], 'email' => $_POST['email']], 'OR', NULL); - + if($user_db) { - + foreach($user_db as $row) { - + if($row['user_id'] == $user['id']) continue; // Same guy? - + // Invalid user, check the time if(!in_array($row['user_status'], ['valid', 'banned'])) { // Don't touch the valid and banned users $must_delete_old_user = false; @@ -215,7 +215,7 @@ $route = function($handler) { continue; } } - + // Username taken? if(G\timing_safe_compare($row['user_username'], $_POST['username']) and $user['username'] !== $row['user_username']) { $input_errors['username'] = 'Username already being used'; @@ -226,7 +226,7 @@ $route = function($handler) { $input_errors['email'] = _s('Email already being used'); } } - + if(count($input_errors) > 0) { $is_error = true; } @@ -235,10 +235,10 @@ $route = function($handler) { // Email MUST be validated (two steps) if(!$is_error && !empty($_POST['email']) && !G\timing_safe_compare($user['email'], $_POST['email'])) { - + // Delete any old confirmation CHV\Confirmation::delete(['type' => 'account-change-email', 'user_id' => $user['id']]); - + // Generate the thing $hashed_token = CHV\generate_hashed_token($user['id']); $insert_email_confirm = CHV\Confirmation::insert([ @@ -249,20 +249,20 @@ $route = function($handler) { 'extra' => $_POST['email'] ]); $email_confirm_link = G\get_base_url('account/change-email-confirm/?token='.$hashed_token['public_token_format']); - $changed_email_message = _s('An email has been sent to %s with instructions to activate this email', $SAFE_POST['email']); - + $changed_email_message = _s('An email has been sent to %s with instructions to activate this email', $SAFE_POST['email']); + // Build the mail global global $theme_mail; $theme_mail = [ 'user' => $user, 'link' => $email_confirm_link ]; - + ob_start(); require_once(G_APP_PATH_THEME . 'mails/account-change-email.php'); $mail_body = ob_get_contents(); ob_end_clean(); - + $mail['subject'] = _s('Confirmation required at %s', CHV\getSettings()['website_name']); $mail['message'] = $mail_body; @@ -273,13 +273,13 @@ $route = function($handler) { } catch(Exception $e) { echo($e->getMessage()); } - + unset($_POST['email']); - + } - + break; - + case 'profile': if(!preg_match('/^.{1,60}$/', $_POST['name'])) { $input_errors['name'] = _s('Invalid name'); @@ -288,9 +288,9 @@ $route = function($handler) { $input_errors['website'] = _s('Invalid website'); } break; - + case 'password': - + if(!$is_dashboard_user) { if($user['login']['password'] && !password_verify($_POST['current-password'], $user['login']['password']['secret'])) { $input_errors['current-password'] = _s('Wrong password'); @@ -301,23 +301,23 @@ $route = function($handler) { } } } - + if(!preg_match('/'.CHV\getSetting('user_password_pattern').'/', $_POST['new-password'])) { $input_errors['new-password'] = _s('Invalid password'); } - + if($_POST['new-password'] !== $_POST['new-password-confirm']) { $input_errors['new-password-confirm'] = _s("Passwords don't match"); } break; - + case 'homepage': if(!array_key_exists($doing, $routes)) { // Nope $handler->issue404(); } $allowed_to_edit = ['homepage_title_html', 'homepage_paragraph_html', 'homepage_cta_html']; - + // Protect editing $editing_array = G\array_filter_array($_POST, $allowed_to_edit, 'exclusion'); $update_settings = []; @@ -325,7 +325,7 @@ $route = function($handler) { if(!array_key_exists($k, CHV\Settings::get()) or CHV\Settings::get($k) == $editing_array[$k]) continue; $update_settings[$k] = $editing_array[$k]; } - + // Update settings (if any) if($update_settings) { $db = CHV\DB::getInstance(); @@ -344,21 +344,21 @@ $route = function($handler) { } } break; - + default: $handler->issue404(); break; } - + if(count($input_errors) > 0) { $is_error = true; } - + if(!$is_error) { - + // Account and profile changes if(in_array($doing, [NULL, 'account', 'profile'])) { - + // Detect changes foreach($_POST as $k => $v) { if($user[$k] !== $v) { @@ -367,10 +367,10 @@ $route = function($handler) { } if($is_changed) { - + // Protect editing $editing_array = G\array_filter_array($_POST, $allowed_to_edit, 'exclusion'); - + if(!$is_dashboard_user) { unset($editing_array['status'], $editing_array['is_admin']); } else { @@ -392,9 +392,12 @@ $route = function($handler) { if(CHV\User::update($user['id'], $editing_array)) { $user = array_merge($user, $editing_array); - $handler::updateVar('safe_post', ['name' => CHV\User::sanitizeUserName($_POST['name'])]); + // 'name' gets sanitized on User::update, this update safe_post to reflect the actual value + $handler::updateVar('safe_post', [ + 'name' => G\safe_html($user['name']), + ]); } - + if(!$is_dashboard_user) { $logged_user = CHV\Login::login($user['id'], $_SESSION['login']['type']); } else { @@ -403,39 +406,39 @@ $route = function($handler) { $changed_message = _s('Changes have been saved.'); } } - + // Update/create password if($doing == 'password') { - + if($user['login']['password']) { - + // Delete any old cookie/session login for this user CHV\Login::delete(['type' => 'cookie', 'user_id' => $user['id']]); CHV\Login::delete(['type' => 'session', 'user_id' => $user['id']]); - + // Insert the new login DB if needed if(!$is_dashboard_user and $_COOKIE['KEEP_LOGIN']) { CHV\Login::insert(['type' => 'cookie', 'user_id' => $user['id']]); } - + $is_changed = CHV\Login::changePassword($user['id'], $_POST['new-password']); // This inserts the session login $changed_message = _s('Password has been changed'); - + } else { // Insert - + $is_changed = CHV\Login::addPassword($user['id'], $_POST['new-password']); $changed_message = _s('Password has been created.'); if(!$is_dashboard_user or $logged_user['id'] == $user['id']) { $logged_user = CHV\Login::login($user['id'], 'password'); } } - + $unsets = array('current-password', 'new-password', 'new-password-confirm'); foreach($unsets as $unset) { $handler::updateVar('safe_post', [$unset => NULL]); } } - + } else { if(in_array($doing, array('', 'account')) and !$is_dashboard_user) { CHV\Requestlog::insert(array('type' => 'account-edit', 'result' => 'fail')); @@ -444,29 +447,29 @@ $route = function($handler) { } } - + $handler::setCond('settings_linked_accounts', FALSE); - + $handler::setCond('owner', $is_owner); $handler::setCond('error', $is_error); $handler::setCond('changed', $is_changed); $handler::setCond('captcha_needed', $captcha_needed); $handler::setCond('dashboard_user', $is_dashboard_user); $handler::setCond('email_required', $is_email_required); - + if($captcha_needed and !$handler::getVar('recaptcha_html')) { $handler::setVar('recaptcha_html', CHV\Render\get_recaptcha_html()); } - + $handler::setVar('pre_doctitle', $is_dashboard_user ? _s('Settings for %s', $user['username']) : _s('Settings')); - + $handler::setVar('error', $error_message); $handler::setVar('input_errors', $input_errors); $handler::setVar('changed_message', $changed_message); $handler::setVar('changed_email_message', $changed_email_message); $handler::setVar('user', $is_dashboard_user ? $user : $logged_user); $handler::setVar('safe_html_user', G\safe_html($handler::getVar('user'))); - + } catch(Exception $e) { G\exception_to_error($e); } diff --git a/app/themes/Peafowl/views/settings.php b/app/themes/Peafowl/views/settings.php index 7e55b74..0b7e753 100644 --- a/app/themes/Peafowl/views/settings.php +++ b/app/themes/Peafowl/views/settings.php @@ -2,9 +2,9 @@
- +
- +

- +
- +
- +
- + - + - +
@@ -132,9 +132,9 @@
- +
- + @@ -158,9 +158,9 @@
- +
- +
@@ -176,9 +176,9 @@

- + - +
@@ -189,7 +189,7 @@ ]); ?>
- +
((bool)(get_safe_post() ? get_safe_post()['newsletter_subscribe'] : get_user()['newsletter_subscribe'])) ]); ?>
- +
((bool)(get_safe_post() ? get_safe_post()['show_nsfw_listings'] : get_user()['show_nsfw_listings'])) ]); ?>
- +
- +
@@ -226,27 +226,27 @@
- - - +
- +
- + " required> - +
- + - + - +
- +
_s('Make my profile and identity totally private'), 'tooltip' => _s('Enable this if you want to act like an anonymous user'), 'checked' => ((bool)(get_safe_post() ? get_safe_post()['is_private'] : get_user()['is_private'])) - ]); ?> + ]); ?>
- +
@@ -384,12 +384,12 @@
- +
- + - + $label) { @@ -437,49 +437,49 @@ } } ?> - + - +
- +
- +
- +
- +
- +
">
- +
- +
- +