Index: /trunk/js/Utilities.js
===================================================================
--- /trunk/js/Utilities.js	(revision 670)
+++ /trunk/js/Utilities.js	(revision 671)
@@ -165,5 +165,5 @@
 Uppercase the first letter of string.
 ---------------------------------------------------------------------
-> 'hello world'.trim()
+> 'hello world'.ucfirst()
 Hello world
 ---------------------------------------------------------------------
@@ -178,2 +178,49 @@
 }
 
+
+/*
+Returns a human readable amount of time for the given amount of seconds.
+Months are calculated using the real number of days in a year: 365.2422 / 12.
+@param    int seconds Seconds of time.
+@param    string max_unit Key value from the units array.
+@return   string Value of units elapsed.
+---------------------------------------------------------------------
+> Strangecode.humanTime(3600)
+1 hour
+---------------------------------------------------------------------
+* @access   public
+* @version  1.0
+* @since    06 Mar 2019
+*/
+Strangecode.humanTime = function(seconds, max_unit) {
+    // Units: array of seconds in the unit, singular and plural unit names.
+    var units = {
+        'second': [1, 'second', 'seconds'],
+        'minute': [60, 'minute', 'minutes'],
+        'hour': [3600, 'hour', 'hours'],
+        'day': [86400, 'day', 'days'],
+        'week': [604800, 'week', 'weeks'],
+        'month': [2629743.84, 'month', 'months'],
+        'year': [31556926.08, 'year', 'years'],
+        'decade': [315569260.8, 'decade', 'decades'],
+        'century': [3155692608, 'century', 'centuries'],
+    };
+
+    // Max unit to calculate.
+    max_unit = typeof max_unit === 'string' && units[max_unit] ? max_unit : 'year';
+
+    var final_time = seconds;
+    var final_unit = 'second';
+    for (var k in units) {
+        if (seconds >= units[k][0]) {
+            final_time = seconds / units[k][0];
+            final_unit = k;
+        }
+        if (max_unit == final_unit) {
+            break;
+        }
+    }
+    final_time = Number(final_time).toFixed(0);
+    return '{1} {2}'.format(final_time, (1 == final_time ? units[final_unit][1] : units[final_unit][2]));
+}
+
Index: /trunk/lib/App.inc.php
===================================================================
--- /trunk/lib/App.inc.php	(revision 670)
+++ /trunk/lib/App.inc.php	(revision 671)
@@ -479,5 +479,5 @@
          */
 
-        $safe_http_host = preg_replace('/[^a-z\d.-]/', '', getenv('HTTP_HOST'));
+        $safe_http_host = preg_replace('/[^a-z\d.:-]/', '', getenv('HTTP_HOST'));
         if ('' != $safe_http_host && '' == $this->getParam('site_hostname')) {
             $this->setParam(array('site_hostname' => $safe_http_host));
Index: /trunk/lib/Auth_SQL.inc.php
===================================================================
--- /trunk/lib/Auth_SQL.inc.php	(revision 670)
+++ /trunk/lib/Auth_SQL.inc.php	(revision 671)
@@ -381,5 +381,10 @@
             $_SESSION['_auth_sql'][$this->_ns]['user_data'] = array();
         }
-        $_SESSION['_auth_sql'][$this->_ns]['user_data'][$key] = $val;
+
+        if (isset($_SESSION['_auth_sql'][$this->_ns][$key])) {
+            $_SESSION['_auth_sql'][$this->_ns][$key] = $val;
+        } else {
+            $_SESSION['_auth_sql'][$this->_ns]['user_data'][$key] = $val;
+        }
     }
 
@@ -617,12 +622,23 @@
             // Check the login status of a specific user.
             $qid = $db->query("
-                SELECT 1 FROM " . $this->_params['db_table'] . "
+                SELECT
+                    TIMESTAMPDIFF(SECOND, last_login_datetime, NOW()) AS seconds_since_last_login,
+                    TIMESTAMPDIFF(SECOND, last_access_datetime, NOW()) AS seconds_since_last_access
+                FROM " . $this->_params['db_table'] . "
                 WHERE " . $this->_params['db_primary_key'] . " = '" . $db->escapeString($user_id) . "'
-                AND last_login_datetime > DATE_SUB(NOW(), INTERVAL '" . $this->_params['login_timeout'] . "' SECOND)
-                AND last_access_datetime > DATE_SUB(NOW(), INTERVAL '" . $this->_params['idle_timeout'] . "' SECOND)
+                AND last_login_datetime > DATE_SUB(NOW(), INTERVAL '" . $db->escapeString($this->_params['login_timeout']) . "' SECOND)
+                AND last_access_datetime > DATE_SUB(NOW(), INTERVAL '" . $db->escapeString($this->_params['idle_timeout']) . "' SECOND)
             ");
-            $login_status = (mysql_num_rows($qid) > 0);
-            $app->logMsg(sprintf('Returning %s login status for user_id %s', ($login_status ? 'true' : 'false'), $user_id), LOG_DEBUG, __FILE__, __LINE__);
-            return $login_status;
+            $result = mysql_fetch_assoc($qid);
+            if (mysql_num_rows($qid) > 0 && isset($result['seconds_since_last_login']) && isset($result['seconds_since_last_access'])) {
+                $seconds_until_login_timeout = max(0, $this->_params['login_timeout'] - $result['seconds_since_last_login']);
+                $seconds_until_idle_timeout = max(0, $this->_params['idle_timeout'] - $result['seconds_since_last_access']);
+                $session_expiry_seconds = min($seconds_until_login_timeout, $seconds_until_idle_timeout);
+                $app->logMsg(sprintf('Returning true login status for user_id %s (session expires in %s seconds)', $user_id, $session_expiry_seconds), LOG_DEBUG, __FILE__, __LINE__);
+                return $session_expiry_seconds;
+            } else {
+                $app->logMsg(sprintf('Returning false login status for user_id %s', $user_id), LOG_DEBUG, __FILE__, __LINE__);
+                return false;
+            }
         }
 
@@ -672,5 +688,7 @@
         ) {
             // User is authenticated!
-            $_SESSION['_auth_sql'][$this->_ns]['last_access_datetime'] = date('Y-m-d H:i:s');
+
+            // Update the last_access_datetime to now.
+            $this->set('last_access_datetime', date('Y-m-d H:i:s'));
 
             // Update the DB with the last_access_datetime and increment the seconds_online.
Index: /trunk/lib/Utilities.inc.php
===================================================================
--- /trunk/lib/Utilities.inc.php	(revision 670)
+++ /trunk/lib/Utilities.inc.php	(revision 671)
@@ -1405,5 +1405,5 @@
 function absoluteMe()
 {
-    $safe_http_host = preg_replace('/[^a-z\d.-]/', '', getenv('HTTP_HOST'));
+    $safe_http_host = preg_replace('/[^a-z\d.:-]/', '', getenv('HTTP_HOST'));
     return sprintf('%s://%s%s', (getenv('HTTPS') ? 'https' : 'http'), $safe_http_host, getenv('REQUEST_URI'));
 }
