Index: trunk/lib/Auth_SQL.inc.php
===================================================================
--- trunk/lib/Auth_SQL.inc.php	(revision 537)
+++ trunk/lib/Auth_SQL.inc.php	(revision 541)
@@ -627,7 +627,7 @@
             && !empty($_SESSION['_auth_sql'][$this->_ns]['username'])
             && isset($_SESSION['_auth_sql'][$this->_ns]['login_datetime'])
-            && strtotime($_SESSION['_auth_sql'][$this->_ns]['login_datetime']) > time() - $this->_params['login_timeout']
+            && strtotime($_SESSION['_auth_sql'][$this->_ns]['login_datetime']) > (time() - $this->_params['login_timeout'])
             && isset($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime'])
-            && strtotime($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime']) > time() - $this->_params['idle_timeout']
+            && strtotime($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime']) > (time() - $this->_params['idle_timeout'])
             && $remote_ip_is_matched
         ) {
@@ -650,5 +650,5 @@
         } else if (isset($_SESSION['_auth_sql'][$this->_ns]['authenticated']) && true === $_SESSION['_auth_sql'][$this->_ns]['authenticated']) {
             // User is authenticated, but login has expired.
-            if (strtotime($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime']) > time() - 43200) {
+            if (strtotime($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime']) > (time() - 43200)) {
                 // Only raise message if last session is less than 12 hours old.
                 $app->raiseMsg(_("Your session has expired. You need to log-in again."), MSG_NOTICE, __FILE__, __LINE__);
@@ -657,14 +657,14 @@
             // Log the reason for login expiration.
             $expire_reasons = array();
-            if (empty($_SESSION['_auth_sql'][$this->_ns]['username'])) {
+            if (!isset($_SESSION['_auth_sql'][$this->_ns]['username']) || empty($_SESSION['_auth_sql'][$this->_ns]['username'])) {
                 $expire_reasons[] = 'username not found';
             }
-            if (strtotime($_SESSION['_auth_sql'][$this->_ns]['login_datetime']) <= time() - $this->_params['login_timeout']) {
+            if (!isset($_SESSION['_auth_sql'][$this->_ns]['login_datetime']) || strtotime($_SESSION['_auth_sql'][$this->_ns]['login_datetime']) <= (time() - $this->_params['login_timeout'])) {
                 $expire_reasons[] = sprintf('login_timeout expired (%s older than %s seconds ago)', $_SESSION['_auth_sql'][$this->_ns]['login_datetime'], $this->_params['login_timeout']);
             }
-            if (strtotime($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime']) <= time() - $this->_params['idle_timeout']) {
+            if (!isset($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime']) || strtotime($_SESSION['_auth_sql'][$this->_ns]['last_access_datetime']) <= (time() - $this->_params['idle_timeout'])) {
                 $expire_reasons[] = sprintf('idle_timeout expired (%s older than %s seconds ago)', $_SESSION['_auth_sql'][$this->_ns]['last_access_datetime'], $this->_params['idle_timeout']);
             }
-            if ($_SESSION['_auth_sql'][$this->_ns]['remote_ip'] != getRemoteAddr()) {
+            if (!isset($_SESSION['_auth_sql'][$this->_ns]['remote_ip']) || $_SESSION['_auth_sql'][$this->_ns]['remote_ip'] != getRemoteAddr()) {
                 if ($this->getParam('match_remote_ip') && !$this->get('match_remote_ip_exempt') && !$user_in_trusted_network) {
                     // There are three cases when a remote IP match will be the cause of a session termination:
@@ -679,5 +679,5 @@
             $app->logMsg(sprintf('User_id %s (%s) session expired: %s', $this->get('user_id'), $this->get('username'), join(', ', $expire_reasons)), LOG_INFO, __FILE__, __LINE__);
         } else {
-            $app->logMsg('No authenticated token in _SESSION', LOG_DEBUG, __FILE__, __LINE__);
+            $app->logMsg('Session is not authenticated', LOG_DEBUG, __FILE__, __LINE__);
         }
 
@@ -943,5 +943,5 @@
         switch ($hash_type) {
         case self::ENCRYPT_CRYPT :
-            return $this->encryptPassword($password, $encrypted_password) == $encrypted_password;
+            return $this->encryptPassword($password, $encrypted_password, $hash_type) == $encrypted_password;
 
         case self::ENCRYPT_PLAINTEXT :
@@ -950,14 +950,15 @@
         case self::ENCRYPT_SHA1 :
         case self::ENCRYPT_SHA1_HARDENED :
-        default :
-            return $this->encryptPassword($password) == $encrypted_password;
+            return $this->encryptPassword($password, $encrypted_password, $hash_type) == $encrypted_password;
 
         case self::ENCRYPT_PASSWORD_BCRYPT :
         case self::ENCRYPT_PASSWORD_DEFAULT :
             return password_verify($password, $encrypted_password);
-        }
-
-        $app->logMsg(sprintf('Unknown hash type: %s', $hash_type), LOG_WARNING, __FILE__, __LINE__);
-        return false;
+
+        default :
+            $app->logMsg(sprintf('Unknown hash type: %s', $hash_type), LOG_WARNING, __FILE__, __LINE__);
+            return false;
+        }
+
     }
 
Index: trunk/lib/Prefs.inc.php
===================================================================
--- trunk/lib/Prefs.inc.php	(revision 537)
+++ trunk/lib/Prefs.inc.php	(revision 541)
@@ -87,6 +87,6 @@
         'user_id' => null,
 
-        // How long before we force a reload of the persistent prefs data? 3600 = once every hour.
-        'load_timeout' => 3600,
+        // How long before we force a reload of the persistent prefs data? 300 = every five minutes.
+        'load_timeout' => 300,
 
         // Name of database table to store prefs.
Index: trunk/lib/Utilities.inc.php
===================================================================
--- trunk/lib/Utilities.inc.php	(revision 537)
+++ trunk/lib/Utilities.inc.php	(revision 541)
@@ -215,30 +215,54 @@
 * @access   public
 * @param    string  $text   Text to search for URLs.
+* @param    bool    $strict True to only include URLs starting with a scheme (http:// ftp:// im://), or false to include URLs starting with 'www.'.
 * @param    mixed   $length Number of characters to truncate URL, or NULL to disable truncating.
 * @param    string  $delim  Delimiter to append, indicate truncation.
 * @return   string          Same input text, but URLs hyperlinked.
 * @author   Quinn Comendant <quinn@strangecode.com>
-* @version  1.0
+* @version  2.0
 * @since    22 Mar 2015 23:29:04
 */
-function hyperlinkTxt($text, $length=null, $delim='âŠ')
-{
-    return preg_replace_callback(
-        // Inspired by @stephenhay's regex from https://mathiasbynens.be/demo/url-regex
-        // Here we capture the full URL into the first match and only the first X characters into the second match.
-        sprintf('@\b(?<!")(?<!\')(?<!=)(((?:https?|s?ftps?)://[^\s/$.?#].[^\s]{0,%s})[^\s]*)@iS', $length),
-        // Use an anonymous function to decide when to append the delim.
-        // Also encode special chars with oTxt().
-        function ($m) use ($length, $delim) {
-            if (is_null($length) || $m[1] == $m[2]) {
-                // If not truncating, or URL was not truncated.
-                return sprintf('<a href="%s">%s</a>', oTxt($m[1]), oTxt($m[1]));
-            } else {
-                // Truncated URL.
-                return sprintf('<a href="%s">%s%s</a>', oTxt($m[1]), oTxt(trim($m[2])), $delim);
-            }
-        },
-        $text
+function hyperlinkTxt($text, $strict=false, $length=null, $delim='âŠ')
+{
+    // Capture the full URL into the first match and only the first X characters into the second match.
+    // This will match URLs not preceeded by " ' or = (URLs inside an attribute) or ` (Markdown quoted) or double-scheme (http://http://www.asdf.com)
+    // Valid URL characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
+    $regex = '@
+        \b                              # Start with a word-boundary.
+        (?<!"|\'|=|>|`|[\w-]{2}://)     # Negative look-behind to exclude URLs already in <a> tag, Markdown quoted, or double SCHEME://
+        (                               # Begin match 1
+            (                           # Begin match 2
+                (?:[\w-]{2,}://%s)      # URL starts with SCHEME:// or www. (if strict = false)
+                [^\s/$.?#]+             # Any domain-valid characters
+                \.                      # At least one point
+                [^\s"`<>]{1,%s}         # Match 2 is limited to a maximum of LENGTH valid URL characters
+            )
+            [^\s"`<>]*                  # Match 1 continues with any further valid URL characters
+            [^\P{Any}%s\sâŠ<>Â«Â»"ââ]      # Final character not a space or common end-of-sentence punctuation (.,:;?!, etc). Using double negation set, see http://stackoverflow.com/a/4786560/277303
+        )
+        @Suxi
+    ';
+    $regex = sprintf($regex,
+        ($strict ? '' : '|www\.'), // Strict=false allows URLs beginning with www.
+        $length,
+        ($strict ? '' : '?!.,:;)\'-') // Strict=false excludes these characters from set of the last character of URL.
     );
+
+    // Use a callback function to decide when to append the delim.
+    // Also encode special chars with oTxt().
+    return preg_replace_callback($regex, function ($m) use ($length, $delim) {
+        $url = $m[1];
+        $truncated_url = $m[2];
+        $absolute_url = preg_replace('!^www\.!', 'http://www.', $url);
+        if (is_null($length) || $url == $truncated_url) {
+            // If not truncating, or URL was not truncated.
+            $display_url = preg_replace('!^[\w-]{2,}://!', '', $url);
+            return sprintf('<a href="%s">%s</a>', oTxt($absolute_url), $display_url);
+        } else {
+            // Truncated URL.
+            $display_url = preg_replace('!^[\w-]{2,}://!', '', trim($truncated_url));
+            return sprintf('<a href="%s">%s%s</a>', oTxt($absolute_url), $display_url, $delim);
+        }
+    }, $text);
 }
 
@@ -452,5 +476,5 @@
 function URLSlug($str)
 {
-    $slug = preg_replace(array('/[^\w]+/', '/^-+|-+$/'), array('-', ''), $str);
+    $slug = preg_replace(array('/\W+/u', '/^-+|-+$/'), array('-', ''), $str);
     $slug = strtolower($slug);
     return $slug;
