diff --git a/.gitmodules b/.gitmodules
index 6f9ccfa7037066bdeda69184d6e836d400cd97b5..2fdd3642fb60b14938aa868b0d8451fed0934cfb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -20,12 +20,16 @@
 [submodule "functions/GoogleAuthenticator"]
 	path = functions/GoogleAuthenticator
 	url = https://github.com/PHPGangsta/GoogleAuthenticator
+	ignore = all
 [submodule "functions/qrcodejs"]
 	path = functions/qrcodejs
 	url = https://github.com/davidshimjs/qrcodejs
+	ignore = all
 [submodule "functions/xmlseclibs"]
 	path = functions/xmlseclibs
 	url = https://github.com/robrichards/xmlseclibs.git
+	ignore = all
 [submodule "functions/parsedown"]
 	path = functions/parsedown
 	url = https://github.com/erusev/parsedown.git
+	ignore = all
diff --git a/README.md b/README.md
index a42a4ea7b98212c161d027a93e0d97225bc27c42..25f6428be09c3cf6779787b6ff2e98cd47a5b4d4 100755
--- a/README.md
+++ b/README.md
@@ -15,7 +15,8 @@ to be able to display javascript quickly and correctly.
 
 ## Branches
  - MASTER: Current development release
- - 1.5: Productional branch for 1.5.x release
+ - 1.6: Productional branch for 1.6.x release
+ - 1.5: Productional branch for 1.5.x release (obsolete)
  - 1.4: Productional branch for 1.4.x release (obsolete)
  - 1.3: Productional branch for 1.3.x release (obsolete)
  - 1.2: Productional branch for 1.2.x release (obsolete)
@@ -26,7 +27,8 @@ to be able to display javascript quickly and correctly.
 phpIPAM has been developed and tested on the following PHP versions.\
 The use of untested PHP versions is unsupported and may result in compatibility issues.
 
-- MASTER: PHP versions 5.4 to 8.1 (8.x support work-in-progress)
+- MASTER: PHP versions 7.2 to 8.3
+- 1.6.x: PHP versions 7.2 to 8.3
 - 1.5.x: PHP versions 5.4 to 7.4
 - 1.4.x: PHP versions 5.4 to 7.4
 - 1.3.x: PHP versions 5.4 to 7.1
diff --git a/app/admin/devices/edit-result.php b/app/admin/devices/edit-result.php
index f32b76d61c338eedaf4a3ec1be04bdbdbb2ef2c6..57fe01626710e9c3cda989eb908d3694c8314139 100755
--- a/app/admin/devices/edit-result.php
+++ b/app/admin/devices/edit-result.php
@@ -14,11 +14,12 @@ $Admin	 	= new Admin ($Database, false);
 $Tools	 	= new Tools ($Database);
 $Racks      = new phpipam_rack ($Database);
 $Result 	= new Result ();
+$Params		= new Params ($User->strip_input_tags ($_POST));
 
 # verify that user is logged in
 $User->check_user_session();
 # perm check popup
-if($_POST['action']=="edit") {
+if($Params->action=="edit") {
     $User->check_module_permissions ("devices", User::ACCESS_RW, true, false);
 }
 else {
@@ -29,13 +30,12 @@ else {
 $User->check_maintaneance_mode ();
 
 # validate csrf cookie
-$User->Crypto->csrf_cookie ("validate", "device", $_POST['csrf_cookie']) === false ? $Result->show("danger", _("Invalid CSRF cookie"), true) : "";
-
+$User->Crypto->csrf_cookie ("validate", "device", $Params->csrf_cookie) === false ? $Result->show("danger", _("Invalid CSRF cookie"), true) : "";
 # get modified details
-$device = $Admin->strip_input_tags($_POST);
+$device = (array) $Params;
 
 # ID must be numeric
-if($_POST['action']!="add" && !is_numeric($_POST['switchid']))			{ $Result->show("danger", _("Invalid ID"), true); }
+if($Params->action!="add" && !is_numeric($Params->switchid))			{ $Result->show("danger", _("Invalid ID"), true); }
 
 # available devices set
 foreach($device as $key=>$line) {
@@ -62,9 +62,11 @@ if (!is_blank(@$device['rack']) && $User->get_module_permissions ("racks")>=User
         if (!is_numeric($device['rack']))                               { $Result->show("danger", _('Invalid rack identifier').'!', true); }
         if (!is_numeric($device['rack_start']))                         { $Result->show("danger", _('Invalid rack start position').'!', true); }
         if (!is_numeric($device['rack_size']))                          { $Result->show("danger", _('Invalid rack size').'!', true); }
-        # validate rack
-        $rack = $Racks->fetch_rack_details ($device['rack']);
-        if ($rack===false)                                              { $Result->show("danger", _('Rack does not exist').'!', true); }
+		# validate rack
+		$rack = $Racks->fetch_rack_details($device['rack']);
+		if (!is_numeric($device['rack']) || ($rack > 0 && !is_object($rack))) {
+			$Result->show("danger", _('Rack does not exist') . '!', true);
+		}
     }
 }
 
@@ -93,7 +95,7 @@ if(sizeof($custom) > 0) {
 
 # set update values
 $values = array(
-				"id"          =>$device['switchid'],
+				"id"          =>isset($device['switchid']) ? $device['switchid'] : null,
 				"hostname"    =>$device['hostname'],
 				"ip_addr"     =>$device['ip_addr'],
 				"type"        =>$device['type'],
@@ -117,10 +119,10 @@ if ($User->get_module_permissions ("locations")==User::ACCESS_NONE) {
 }
 
 # update device
-if(!$Admin->object_modify("devices", $_POST['action'], "id", $values))	{}
+if(!$Admin->object_modify("devices", $Params->action, "id", $values))	{}
 else { $Result->show("success", _("Device")." ".$device["action"]." "._("successful").'!', false); }
 
-if($_POST['action']=="delete"){
+if($Params->action=="delete"){
 	# remove all references from subnets and ip addresses
 	$Admin->remove_object_references ("subnets", "device", $values["id"]);
 	$Admin->remove_object_references ("nat", "device", $values["id"]);
diff --git a/app/admin/devices/edit.php b/app/admin/devices/edit.php
index 812e42cc7993c8f2a18c6f33f52ab80295371105..06924b4f8a1208c64b0ceaaba1d4c6429d7a6833 100755
--- a/app/admin/devices/edit.php
+++ b/app/admin/devices/edit.php
@@ -13,11 +13,12 @@ $User 		= new User ($Database);
 $Admin	 	= new Admin ($Database, false);
 $Tools	 	= new Tools ($Database);
 $Result 	= new Result ();
+$Params		= new Params ($User->strip_input_tags ($_POST));
 
 # verify that user is logged in
 $User->check_user_session();
 # perm check popup
-if($_POST['action']=="edit") {
+if($Params->action=="edit") {
     $User->check_module_permissions ("devices", User::ACCESS_RW, true, true);
 }
 else {
@@ -27,21 +28,19 @@ else {
 # create csrf token
 $csrf = $User->Crypto->csrf_cookie ("create", "device");
 
-# strip tags - XSS
-$_POST = $User->strip_input_tags ($_POST);
 
 # validate action
-$Admin->validate_action ($_POST['action'], true);
+$Admin->validate_action ($Params->action, true);
 
 # fetch custom fields
 $custom = $Tools->fetch_custom_fields('devices');
 
 # ID must be numeric
-if($_POST['action']!="add" && !is_numeric($_POST['switchid']))		{ $Result->show("danger", _("Invalid ID"), true, true); }
+if($Params->action!="add" && !is_numeric($Params->switchid))		{ $Result->show("danger", _("Invalid ID"), true, true); }
 
 # fetch device details
-if( ($_POST['action'] == "edit") || ($_POST['action'] == "delete") ) {
-	$device = (array) $Admin->fetch_object("devices", "id", $_POST['switchid']);
+if( ($Params->action == "edit") || ($Params->action == "delete") ) {
+	$device = (array) $Admin->fetch_object("devices", "id", $Params->switchid);
 	// false
 	if ($device===false)                                            { $Result->show("danger", _("Invalid ID"), true, true);  }
 }
@@ -51,10 +50,12 @@ else {
 	$device['type']       = 9;
 	$device['rack_start'] = 1;
 	$device['rack_size']  = 1;
+	$device['location'] = null;
+	$device['rack'] = null;
 }
 
 # set readonly flag
-$readonly = $_POST['action']=="delete" ? "readonly" : "";
+$readonly = $Params->action=="delete" ? "readonly" : "";
 
 
 # all locations
@@ -193,10 +194,10 @@ $('#switchManagementEdit select[name=rack]').change(function() {
 		<td>
 			<textarea name="description" class="form-control input-sm" placeholder="<?php print _('Description'); ?>" <?php print $readonly; ?>><?php if(isset($device['description'])) print $device['description']; ?></textarea>
 			<?php
-			if( ($_POST['action'] == "edit") || ($_POST['action'] == "delete") ) {
-				print '<input type="hidden" name="switchid" value="'. $_POST['switchid'] .'">'. "\n";
+			if( ($Params->action == "edit") || ($Params->action == "delete") ) {
+				print '<input type="hidden" name="switchid" value="'. $Params->switchid .'">'. "\n";
 			} ?>
-			<input type="hidden" name="action" value="<?php print escape_input($_POST['action']); ?>">
+			<input type="hidden" name="action" value="<?php print escape_input($Params->action); ?>">
 			<input type="hidden" name="csrf_cookie" value="<?php print $csrf; ?>">
 		</td>
 	</tr>
@@ -265,7 +266,7 @@ $('#switchManagementEdit select[name=rack]').change(function() {
 <div class="pFooter">
 	<div class="btn-group">
 		<button class="btn btn-sm btn-default hidePopups"><?php print _('Cancel'); ?></button>
-		<button class="btn btn-sm btn-default <?php if($_POST['action']=="delete") { print "btn-danger"; } else { print "btn-success"; } ?>" id="editSwitchsubmit"><i class="fa <?php if($_POST['action']=="add") { print "fa-plus"; } else if ($_POST['action']=="delete") { print "fa-trash-o"; } else { print "fa-check"; } ?>"></i> <?php print escape_input(ucwords(_($_POST['action']))); ?></button>
+		<button class="btn btn-sm btn-default <?php if($Params->action=="delete") { print "btn-danger"; } else { print "btn-success"; } ?>" id="editSwitchsubmit"><i class="fa <?php if($Params->action=="add") { print "fa-plus"; } else if ($Params->action=="delete") { print "fa-trash-o"; } else { print "fa-check"; } ?>"></i> <?php print escape_input(ucwords(_($Params->action))); ?></button>
 	</div>
 
 	<!-- result -->
diff --git a/config.dist.php b/config.dist.php
index dd5993df69a07df655ae00ccc774177a649354d7..32b810652b4eb15221f44139c3d5aa2edbd727f0 100755
--- a/config.dist.php
+++ b/config.dist.php
@@ -30,7 +30,6 @@ $db['webhost'] = '';
      Please update these settings before setting 'ssl' to true.
      All settings can be commented out or set to NULL if not needed
 
-     php 5.3.7 required
  ******************************/
 $db['ssl']        = false;                             // true/false, enable or disable SSL as a whole
 // $db['ssl_key']    = '/path/to/cert.key';               // path to an SSL key file. Only makes sense combined with ssl_cert
@@ -43,6 +42,21 @@ $db['ssl']        = false;                             // true/false, enable or
 $db['tmptable_engine_type'] = "MEMORY";                // Temporary table type to construct complex queries (MEMORY, InnoDB)
 $db['use_cte'] = 1;                                    // Use recursive CTE queries [>=MariaDB 10.2.2, >=MySQL 8.0] (0=disabled, 1=autodetect, 2=force enable)
 
+/**
+ * Reverse proxy settings
+ *
+ * If operating behind a reverse proxy set $trust_x_forwarded_headers=true; to accept the following headers
+ *
+ * WARNING! These headers shoud be filtered and/or overwritten by the reverse-proxy to avoid potential abuse by end-clients.
+ *
+ *   X_FORWARDED_FOR
+ *   X_FORWARDED_HOST
+ *   X_FORWARDED_PORT
+ *   X_FORWARDED_PROTO
+ *   X_FORWARDED_SSL
+ *   X_FORWARDED_URI
+ */
+$trust_x_forwarded_headers = false;
 
 /**
  * Mail sending and other parameters for pingCheck and DiscoveryCheck scripts
diff --git a/config.docker.php b/config.docker.php
index f76b837764ac941d69295c922008c2a4ec611851..b9dec3c9486303b2c1d094894ba4df5c92442bda 100644
--- a/config.docker.php
+++ b/config.docker.php
@@ -48,6 +48,22 @@ $db['name']    = file_env('IPAM_DATABASE_NAME',    $db['name']);
 $db['port']    = file_env('IPAM_DATABASE_PORT',    $db['port']);
 $db['webhost'] = file_env('IPAM_DATABASE_WEBHOST', $db['webhost']);
 
+/**
+ * Reverse proxy settings
+ *
+ * If operating behind a reverse proxy set IPAM_TRUST_X_FORWARDED=true to accept the following headers
+ *
+ * WARNING! These headers shoud be filtered and/or overwritten by the reverse-proxy to avoid potential abuse by end-clients.
+ *
+ *   X_FORWARDED_FOR
+ *   X_FORWARDED_HOST
+ *   X_FORWARDED_PORT
+ *   X_FORWARDED_PROTO
+ *   X_FORWARDED_SSL
+ *   X_FORWARDED_URI
+ */
+$trust_x_forwarded_headers = filter_var(file_env('IPAM_TRUST_X_FORWARDED', $trust_x_forwarded_headers), FILTER_VALIDATE_BOOLEAN);
+
 /**
  * proxy connection details
  ******************************/
@@ -82,3 +98,9 @@ $cookie_samesite = file_env('COOKIE_SAMESITE', $cookie_samesite);
  * @var string
  */
 $session_storage = "database";
+
+
+/**
+ * General tweaks
+ ******************************/
+$config['footer_message'] = file_env('IPAM_FOOTER_MESSAGE', $config['footer_message']);
diff --git a/functions/checks/check_php_build.php b/functions/checks/check_php_build.php
index a3237bb5b118709c28688a388b8e925b737c557f..612f0618e5be43a49656111265d79ac7e744eb95 100755
--- a/functions/checks/check_php_build.php
+++ b/functions/checks/check_php_build.php
@@ -12,10 +12,10 @@ $requiredExt  = array("session", "sockets", "filter", "openssl", "gmp", "json",
 $requiredFns  = array("simplexml_load_string");
 
 if(!defined('PHPIPAM_PHP_MIN'))
-define('PHPIPAM_PHP_MIN', "5.4");
+define('PHPIPAM_PHP_MIN', "7.2");
 
 if(!defined('PHPIPAM_PHP_UNTESTED'))
-define('PHPIPAM_PHP_UNTESTED', "9.0");  // PHP 8.2 or greater is untested & unsupported
+define('PHPIPAM_PHP_UNTESTED', "8.4");  // PHP 8.4 or greater is untested, use at own risk and expect issues
 
 if (phpversion() >= PHPIPAM_PHP_UNTESTED) {
     $_SESSION['footer_warnings']['php_version'] = _('Unsupported PHP version ') . phpversion();
diff --git a/functions/classes/class.Common.php b/functions/classes/class.Common.php
index cde9153e58e52ecc24c0210df0796260729d1ab4..b49cc99d39d5c89135948d535b6428b28b5f3779 100644
--- a/functions/classes/class.Common.php
+++ b/functions/classes/class.Common.php
@@ -997,19 +997,20 @@ class Common_functions  {
 	 * @return  int
 	 */
 	private function httpPort() {
-		// If only HTTP_X_FORWARDED_PROTO='https' is set assume port=443. Override if required by setting HTTP_X_FORWARDED_PORT
-		if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && !isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
-			return ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ? 443 : 80;
-		}
-		elseif (isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
-			return $_SERVER['HTTP_X_FORWARDED_PORT'];
+		if (Config::ValueOf('trust_x_forwarded_headers') === true) {
+			// If only HTTP_X_FORWARDED_PROTO='https' is set assume port=443. Override if required by setting HTTP_X_FORWARDED_PORT
+			if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && !isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
+				return ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ? 443 : 80;
+			}
+			if (isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
+				return $_SERVER['HTTP_X_FORWARDED_PORT'];
+			}
 		}
-		elseif (isset($_SERVER['SERVER_PORT'])) {
+		if (isset($_SERVER['SERVER_PORT'])) {
 			return $_SERVER['SERVER_PORT'];
 		}
-		else {
-			return 80;
-		}
+
+		return 80;
 	}
 
 	/**
@@ -1019,21 +1020,22 @@ class Common_functions  {
 	* @return bool
 	*/
 	public function isHttps () {
-		if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
-			return ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https');
-		}
-		elseif (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') {
-			return true;
+		if (Config::ValueOf('trust_x_forwarded_headers') === true) {
+			if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
+				return ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https');
+			}
+			if (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') {
+				return true;
+			}
 		}
-		elseif(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
+		if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
 			return true;
 		}
-		elseif($this->httpPort() == 443) {
+		if ($this->httpPort() == 443) {
 			return true;
 		}
-		else {
-			return false;
-		}
+
+		return false;
 	}
 
 	/**
@@ -1045,8 +1047,11 @@ class Common_functions  {
 		if (php_sapi_name() === "cli")
 			return null;
 
-		if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
-			return $_SERVER['HTTP_X_FORWARDED_FOR'];
+		if (Config::ValueOf('trust_x_forwarded_headers') === true) {
+			if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP)) {
+				return $_SERVER['HTTP_X_FORWARDED_FOR'];
+			}
+		}
 
 		if (isset($_SERVER['REMOTE_ADDR']) && filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP))
 			return $_SERVER['REMOTE_ADDR'];
@@ -1063,16 +1068,13 @@ class Common_functions  {
 	public function createURL () {
 		$proto = $this->isHttps() ? 'https' : 'http';
 
-		if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
+		if (Config::ValueOf('trust_x_forwarded_headers') === true && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
 			$url = $_SERVER['HTTP_X_FORWARDED_HOST'];
-		}
-		elseif (isset($_SERVER['HTTP_HOST'])) {
+		} elseif (isset($_SERVER['HTTP_HOST'])) {
 			$url = $_SERVER['HTTP_HOST'];
-		}
-		elseif (isset($_SERVER['SERVER_NAME'])) {
+		} elseif (isset($_SERVER['SERVER_NAME'])) {
 			$url = $_SERVER['SERVER_NAME'];
-		}
-		else {
+		} else {
 			$url = "localhost";
 		}
 		$host = parse_url("$proto://$url", PHP_URL_HOST) ?: "localhost";
@@ -1253,8 +1255,8 @@ class Common_functions  {
 		$country = strtolower($country);
 		// set regexes
 		$country_regex = array(
-			'united kingdom' => '/\\A\\b[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2}\\b\\z/i',
-			'england'        => '/\\A\\b[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][ABD-HJLNP-UW-Z]{2}\\b\\z/i',
+			'united kingdom' => '/^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$/i',
+			'england'        => '/^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$/i',
 			'canada'         => '/\\A\\b[ABCEGHJKLMNPRSTVXY][0-9][A-Z][ ]?[0-9][A-Z][0-9]\\b\\z/i',
 			'italy'          => '/^[0-9]{5}$/i',
 			'deutschland'    => '/^[0-9]{5}$/i',
diff --git a/functions/classes/class.User.php b/functions/classes/class.User.php
index 515ad5adb06a004be5c7046eceb48fd90b509d43..abc658d91c21eaabad60317b3df9bd0610b70c25 100644
--- a/functions/classes/class.User.php
+++ b/functions/classes/class.User.php
@@ -511,8 +511,7 @@ class User extends Common_functions {
                 return;
             }
         }
-
-        if (isset($_SERVER['HTTP_X_FORWARDED_URI'])) {
+        if (Config::ValueOf('trust_x_forwarded_headers') === true && isset($_SERVER['HTTP_X_FORWARDED_URI'])) {
             $uri = $_SERVER['HTTP_X_FORWARDED_URI'];
         }
         elseif (isset($_SERVER['REQUEST_URI'])) {
diff --git a/functions/global_functions.php b/functions/global_functions.php
index 252b23c943df83a545e41578efb8d4582a64390b..d1b400fa974fb487cbd8fab41b20d87998c45bcc 100644
--- a/functions/global_functions.php
+++ b/functions/global_functions.php
@@ -18,89 +18,6 @@ function disable_php_errors() {
 	ini_set('display_startup_errors', 0);
 }
 
-/**
- * Supported in PHP 5 >= 5.6.0
- * A timing safe equals comparison more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
- */
-if(!function_exists('hash_equals')) {
-	function hash_equals($safeString, $userString) {
-		$safeLen = strlen($safeString);
-		$userLen = strlen($userString);
-
-		if ($userLen != $safeLen) { return false; }
-
-		$result = 0;
-		for ($i = 0; $i < $userLen; ++$i) {
-			$result |= (ord($safeString[$i]) ^ ord($userString[$i]));
-		}
-		// They are only identical strings if $result is exactly 0...
-		return $result === 0;
-	}
-}
-
-/**
- * Supported in PHP 5 >= 5.6.0
- * ldap_escape — Escape a string for use in an LDAP filter or DN
- */
-if (!function_exists('ldap_escape')) {
-	if (!defined('LDAP_ESCAPE_FILTER')) {
-		define('LDAP_ESCAPE_FILTER', 1);
-	}
-	if (!defined('LDAP_ESCAPE_DN')) {
-		define('LDAP_ESCAPE_DN', 2);
-	}
-	function ldap_escape($value, $ignore = null, $flags = 0) {
-		if (!is_string($value) || strlen($value) == 0)
-			return '';
-
-		$search = [];
-		$replace = [];
-
-		if ($flags & LDAP_ESCAPE_FILTER) {
-			$search = array_merge($search, ['\\', '*', '(', ')', "\x00"]);
-		}
-		if ($flags & LDAP_ESCAPE_DN) {
-			$search = array_merge($search, ['\\', ',', '=', '+', '<', '>', ';', '"', '#', "\r"]);
-		}
-
-		$search = array_unique($search);
-
-		if (empty($search)) {
-			$v = [];
-			foreach (str_split($value) as $s) {
-				$v[] = sprintf('\\%02x', ord($s));
-			}
-			$value = implode($v);
-		}
-
-		foreach ($search as $s) {
-			$replace[] = sprintf('\\%02x', ord($s));
-		}
-
-		return str_replace($search, $replace, $value);
-	}
-}
-
-/**
- *  Supported in PHP 5 >= 5.5.0
- *  For older php versions make sure that function "json_last_error_msg" exist and create it if not
-*/
-if (!function_exists('json_last_error_msg')) {
-	function json_last_error_msg() {
-		static $ERRORS = [
-			JSON_ERROR_NONE => 'No error',
-			JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
-			JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
-			JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
-			JSON_ERROR_SYNTAX => 'Syntax error',
-			JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
-		];
-
-		$error = json_last_error();
-		return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
-	}
-}
-
 /**
  * create links function
  *
diff --git a/functions/version.php b/functions/version.php
index 7c2483938c3ba3a68b095648212ccda0aea1b216..8a8489b18650c53f7eb7eaab540cbeb53efc104f 100644
--- a/functions/version.php
+++ b/functions/version.php
@@ -8,7 +8,7 @@ define("REVISION", "003");									//increment on static content changes (js/css
 /* set last possible upgrade */
 define("LAST_POSSIBLE", "1.4");							    //minimum required version to be able to upgrade
 /* set published - hide dbversion in footer */
-define("PUBLISHED", false);									//hide dbversion in footer
+define("PUBLISHED", true);									//hide dbversion in footer
 
 // Automatically set DBVERSION as everyone forgets!
 function get_dbversion() {
diff --git a/misc/CHANGELOG b/misc/CHANGELOG
index 3515bab834b120ddb888ad1966080e894bbbd8a5..48936dbc36370b960731a049aa0fb90bd19391b8 100755
--- a/misc/CHANGELOG
+++ b/misc/CHANGELOG
@@ -15,8 +15,9 @@
 
     Enhancements, changes:
     ----------------------------
-    + php8.4 compatibility;;
+    + php8.3 compatibility;
     + MySQL 5.5.3+ is now required (support for utf8mb4);
+    + Reverse-proxy users should review the new config.php $trust_x_forwarded_headers setting;
 
     Security Fixes:
     ----------------------------