Fixed Tooltip styling
Fixed Tooltip styling

file:a/.gitignore -> file:b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,5 @@
 testcreds
 testdata
 testdata/*
+update/
 

--- a/Install/index.php
+++ b/Install/index.php
@@ -478,6 +478,8 @@
   `Address` blob,
   `UName` blob,
   `Custom` blob,
+  `hidden` tinyint(1) DEFAULT 0,
+  `comment` blob DEFAULT NULL,
   PRIMARY KEY (`id`),
   KEY `idx_Cred_Group` (`Group`),
   KEY `idx_cred_cust` (`cust`)
@@ -559,7 +561,11 @@
   PRIMARY KEY (`id`),
   UNIQUE KEY `idx_failed_user_ip` (`username`,`FailedIP`),
   KEY `idx_failedips` (`FailedIP`)
-) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;'
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;',
+
+'CREATE TABLE #__CustPortal( `id` INT NOT NULL, `email` TEXT, `pass` TEXT, `active` TINYINT(1), PRIMARY KEY (`id`));',
+'CREATE UNIQUE INDEX idx_portal_logins ON #__CustPortal(`email`(100));',
+'CREATE INDEX idx_active_portal ON #__CustPortal(`active`);'
 
 );
 

--- a/Resources/info.php
+++ b/Resources/info.php
@@ -34,6 +34,22 @@
 
 // Load the framework
 require_once 'lib/Framework/main.php';
+
+
+if (isset($_COOKIE['PHPCredLockerKeySet']) && BTMain::getVar('destSession') == 'Y'){
+
+$expires = strtotime("-2 days");
+setcookie("PHPCredLockerKeySet", 1, $expires, dirname($_SERVER["REQUEST_URI"]), $_SERVER['HTTP_HOST'], BTMain::getConf()->forceSSL);
+BTMain::unsetSessVar('tls');
+BTMain::unsetSessVar('KeyExpiry');
+BTMain::unsetSessVar('apiterms');
+
+$_COOKIE['PHPCredLockerKeySet'] = 0;
+
+}
+
+
+
 
 $tls = BTMain::getSessVar('tls');
 $expiry = BTMain::getSessVar('KeyExpiry');

--- a/Resources/main.js
+++ b/Resources/main.js
@@ -96,8 +96,12 @@
   if (count <= 0 || cancel == 1)
   {
      clearInterval(counter);
+     if (document.getElementById('credHidden'+id)){
+     field.innerHTML = 'Display<span class="DisPwdText"> Username</span>';  
+     }else{
+     field.innerHTML = 'Display<span class="DisPwdText"> Password</span>';  
+     }
      
-     field.innerHTML = 'Display<span class="DisPwdText"> Password</span>';
      document.getElementById('Address'+id).innerHTML = '';
      document.getElementById('UserName'+id).innerHTML = '';
      document.getElementById('Password'+id).innerHTML = '';
@@ -106,7 +110,7 @@
      return;
   }
 
-  field.innerHTML = 'Displaying Password for ' +count+ ' seconds';
+  field.innerHTML = 'Displaying for ' +count+ ' seconds';
 }
 
 
@@ -220,7 +224,8 @@
   var cred = document.getElementById('frmCredential'),
       user = document.getElementById('frmUser'),
       addr = document.getElementById('frmAddress'),
-      grp = document.getElementById('frmGroup');
+      grp = document.getElementById('frmGroup'),
+      comment = document.getElementById('frmComment');
       
       
       
@@ -244,6 +249,7 @@
  cred.value = Base64.encode(xorestr(cred.value,retKey()));
  user.value = Base64.encode(xorestr(user.value,retKey()));
  addr.value = Base64.encode(xorestr(addr.value,retKey()));
+ comment.value = Base64.encode(xorestr(comment.value,retKey()));
 }
 return true;
 
@@ -258,7 +264,8 @@
   var cred = document.getElementById('frmCredential'),
       user = document.getElementById('frmUser'),
       addr = document.getElementById('frmAddress'),
-      grp = document.getElementById('frmGroup');
+      grp = document.getElementById('frmGroup'),
+      comment = document.getElementById('frmComment');
       
       
       
@@ -285,6 +292,9 @@
 if (cred.value == null || cred.value == ''){
  cred.value = ' '; 
 }
+if (comment.value == null || comment.value == ''){
+ comment.value = ' '; 
+}
 
 if (user.value == null || user.value == ''){
  user.value = ' '; 
@@ -293,6 +303,7 @@
 if (addr.value == null || addr.value == ''){
  addr.value = ' '; 
 }
+
 
 if (enabledEncryption()){ 
  
@@ -300,6 +311,7 @@
  cred.value = Base64.encode(xorestr(cred.value,retKey()));
  user.value = Base64.encode(xorestr(user.value,retKey()));
  addr.value = Base64.encode(xorestr(addr.value,retKey()));
+ comment.value = Base64.encode(xorestr(comment.value,retKey()));
 }
 
 return true;
@@ -919,6 +931,18 @@
  * as it means a longer request.
  * 
  */
+
+
+function inlineDeCrypt(){
+ var i, eles = document.getElementsByClassName('inlineTLS');
+ 
+ for (i=0;i < eles.length;i++){
+   eles[i].innerHTML = decryptAPIResp(eles[i].innerHTML,retKey());   
+ }  
+  
+}
+
+
 function xorestr(str,key){
     if (!enabledEncryption()){ return str; }
     

--- a/conf/config.php.example
+++ b/conf/config.php.example
@@ -56,4 +56,8 @@
 
 // Time in hours to block the IP for
 $conf->banLength = 24;
+
+
+// Enable the customer facing portal?
+$conf->custPortalEnabled = 1;
 ?>

--- a/conf/lang.php
+++ b/conf/lang.php
@@ -21,3 +21,4 @@
 $lang['User'] = 'User';
 $lang['User Groups'] = 'User Groups';
 $lang['UserGroup'] = 'Group';
+$lang['Comment'] = 'Comment';

--- a/conf/notifications.php
+++ b/conf/notifications.php
@@ -14,6 +14,8 @@
 $notifs->HomePageTextLoggedIn->className = 'HomePgText';
 $notifs->HomePageTextLoggedIn->text = 'Welcome to PHPCredLocker, please use the menus to proceed';
 
+$notifs->CustPortalFail->className = 'alert alert-info';
+$notifs->CustPortalFail->text = "The customer has been successfully updated, but the customer portal record could not be updated. The customer will need to continue to use their old details";
 
 
 $notifs->addCustSuccess->className = 'alert alert-success';

--- a/lib/API.php
+++ b/lib/API.php
@@ -15,6 +15,7 @@
 require_once 'lib/db/loggingdb.class.php';
 require_once 'lib/plugins.php';
 require_once 'lib/crypto.php';
+require_once 'lib/customer.class.php';
 
 $plg = new Plugins;
 $crypt = new Crypto;
@@ -81,7 +82,13 @@
     $key = 'Cre'.$cred->CredType;
 
     // Build the response
+
+    if ((BTMain::getUser()->PortalLogin != 1) || ($cred->hidden !=1)){
     $pass = htmlspecialchars($crypt->decrypt($cred->Hash,$key));
+    }else{
+    $pass = "<span style='font-size: x-small'>You are not authorised to view this password</span>";
+    }
+
     $address = htmlspecialchars($crypt->decrypt($cred->Address,$key));
     $uname = htmlspecialchars($crypt->decrypt($cred->UName,$key));
 
@@ -89,6 +96,10 @@
 	  $pass = "<a href='$pass' target=_blank title='Click to Open'>$pass</a>";
       }
 
+    // If a URL has been entered without http - See #31
+    if (substr($address,0,3) == "www"){
+    $address = "http://".$address;
+    }
 
     echo $pass.$opDivider."<a href='$address' target=_blank>".$address."</a>" .$opDivider. 
 	 $uname . $opDivider;

--- a/lib/Framework/main.php
+++ b/lib/Framework/main.php
@@ -151,10 +151,18 @@
 function buildACLQuery($tbl = false){
 $groups = BTMain::getUser()->groups;
 $tab ='';
-
 if ($tbl){
 $tab = "$tbl.";
 }
+
+
+if (BTMain::getUser()->PortalLogin == '1'){
+return "$tab.cust = '".BTMain::getUser()->PortalID."' ";
+
+}
+
+
+
 
 if (!in_array("-1",$groups)){
 return "$tab`Group`=" . implode(" OR $tab`Group`=",$groups) ;

--- a/lib/Handler.php
+++ b/lib/Handler.php
@@ -14,12 +14,16 @@
 require_once 'lib/plugins.php';
 require_once 'lib/db/loggingdb.class.php';
 require_once 'lib/crypto.php';
+require_once 'lib/customer.class.php';
 
 
 $html = new genOutput;
 $notifications = new notifications;
 $option = BTMain::getVar('option');
 $auth = new ProgAuth;
+
+$custportalmethods = array("logout","editCred");
+
 
     // See if the user has an active session
     if (BTMain::getsessVar('Session')){
@@ -70,7 +74,10 @@
 
 
 
-
+if ((BTMain::getUser()->PortalLogin == 1) && (!in_array($option,$custportalmethods))){
+$option = 'viewCust';
+BTMain::setVar('id',BTMain::getUser()->PortalID);
+}
 
 
 switch ($option){

--- a/lib/auth.class.php
+++ b/lib/auth.class.php
@@ -40,6 +40,30 @@
 
 return md5($salt.date('y-m-dHis'));
 
+}
+
+
+/** Generate a random password of the specified length
+*
+* @arg length - INT
+*
+* @return string
+*
+*/
+function generatePassword($length = 8){
+
+ $key="(=?)+.,abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ $x = 0;
+ $p = '';
+
+  while ($x < $length){
+  $select = mt_rand(1,strlen($key)) - 1;
+  $p .= $key[$select];
+  $x++;
+  }
+
+return $p;
+  
 }
 
 
@@ -193,7 +217,11 @@
 $username = rtrim($username," ");
 
   if (!$user = $db->retrieveUserCreds($username)){
-  return false;
+    // Not a user, user. Check the Portal login
+    $cust = new CredLockCust;
+    if ((!BTMain::getConf()->custPortalEnabled) || (!$user = $cust->checkLogin($username))){
+      return false;
+    }
   }
 
 
@@ -217,9 +245,20 @@
     unset($pass);
 
 
+
+if ($user->membergroup != "-99,"){
+    $groups = explode(",","0,".$user->membergroup);
+    }else{
+    $groups = array("-99");
+    BTMain::setUserDetails('PortalLogin','1');
+    $username = $user->id;
+  }
+
 // Log the user in
 BTMain::setUser($username);
-BTMain::setUserDetails('groups',explode(",","0,".$user->membergroup));
+
+BTMain::setUserDetails('groups',$groups);
+
 BTMain::setUserDetails('RealName',$user->Name);
 
 
@@ -320,8 +359,15 @@
  $user = $db->getUserSession($sessID);
 
   if (!$user){
-  $this->LoginInvalid();
-  }
+      $this->LoginInvalid();  
+  }
+
+$cust = new CredLockCust;
+if (is_numeric($user->User) && (BTMain::getConf()->custPortalEnabled) && ($usedets = $cust->checkSession($user->User))){
+$user->username = $usedets->email;
+$user->Name = $usedets->Name;
+$user->membergroup = "-99,";
+}
 
 $expiry = strtotime($user->Expires);
 
@@ -344,7 +390,18 @@
 
 // Users session is valid
 BTMain::setUser($user->username);
-BTMain::setUserDetails('groups',explode(",","0,".$user->membergroup));
+
+
+if ($user->membergroup != "-99,"){
+    $groups = explode(",","0,".$user->membergroup);
+    }else{
+    $groups = array("-99");
+    BTMain::setUserDetails('PortalLogin','1');
+    BTMain::setUserDetails('PortalID',$user->User);
+  }
+
+
+BTMain::setUserDetails('groups',$groups);
 BTMain::setUserDetails('RealName',$user->Name);
 
 

--- a/lib/crypto.php
+++ b/lib/crypto.php
@@ -81,6 +81,11 @@
     return $en;
 }
 
+
+
+function inlineEncrypt($string){
+return "<div class='inlineTLS'>".base64_encode($this->xorestring(base64_encode($string),$tlskey = BTMain::getsessVar('tls')))."</div>";
+}
 
 
 /** Xor the provided string to encrypt it

--- /dev/null
+++ b/lib/customer.class.php
@@ -1,1 +1,173 @@
+<?php
+/** Customer Portal related functions
+*
+* Copyright (c) 2012 B Tasker
+* Released under GNU GPL V2
+* See LICENSE
+*
+*/ 
 
+defined('_CREDLOCK') or die;
+
+class CredLockCust{
+
+/** Add a customer 
+*
+* @arg name - Customer's name
+* @arg group - Group ID
+* @arg firstname - Their given name
+* @arg surname - Family name
+* @arg email - Email address
+*
+*/
+function add($name,$group,$firstname,$surname,$email){
+$db = new CustDB;
+$id = $db->addCustomer($name,$group,$firstname,$surname,$email);
+$auth = new ProgAuth;
+$db = new AuthDB;
+
+if (!$id){
+  return false;
+}
+
+// We add the customer to the portal, even if we won't let them log-in (i.e. the portal is disabled)
+$password = $auth->generatePassword();
+$salt = $auth->createSalt();
+$pass = md5($password.$salt);
+
+
+if ($db->addCusttoPortal($id,$email,$pass.":".$salt,1)) {
+
+    if (BTMain::getConf()->custPortalEnabled){
+    global $notifications;
+    $not->className = 'alert alert-success';
+    $not->text = "The customer has been successfully added to the customer portal and can use the password <i>$password</i> to manage their credentials";
+    // This echo is a temporary thing until I update Notifications
+    echo "<div class='{$not->className}'>{$not->text}</div>";
+
+
+    $notifications->setNotification($not);
+    }
+
+
+
+}
+
+return $id;
+
+}
+
+
+
+
+
+/** Edit a Customer record - including updating the portal details (i.e. update the email address if changed)
+*
+*/
+function edit($id,$name,$group,$firstname,$surname,$email){
+
+$db = new CustDB;
+$auth = new ProgAuth;
+
+if (!$db->editCustomer($id,$name,$group,$firstname,$surname,$email)){
+return false;
+}
+
+$db = new AuthDB;
+// We add the customer to the portal, even if we won't let them log-in (i.e. the portal is disabled)
+$password = $auth->generatePassword();
+$salt = $auth->createSalt();
+$pass = md5($password.$salt);
+
+
+ global $notifications;
+
+if ($db->addCusttoPortal($id,$email,$pass.":".$salt,1)){
+ 
+
+
+   
+
+    $not->className = 'alert alert-success';
+    $not->text = "The customer has been successfully added to the customer portal and can use the password <i>$password</i> to manage their credentials";
+    // This echo is a temporary thing until I update Notifications
+    echo "<div class='{$not->className}'>{$not->text}</div>";
+   // $notifications->setNotification($not);
+    
+
+}else{
+    echo "<div class='alert alert-error'>Unable to update Customer Portal details</div>";
+}
+
+  
+
+  
+return true;
+
+
+
+
+}
+
+
+/** Called by ProgAuth::ProcessLogin - See if the supplied username matches any in the PortalDB
+*
+* @arg username
+*
+* @return object or false
+*/
+function checkLogin($username){
+$db = new AuthDB;
+
+if (!$user = $db->getPortalByUsername($username)){
+return false;
+}
+$crypt = new Crypto;
+
+// Set the customer indicator
+$user->membergroup = "-99,";
+$user->Name = $crypt->decrypt($user->ContactName,'auth')." ".$crypt->decrypt($user->Surname,'auth');
+return $user;
+
+
+
+}
+
+
+
+/** Portal sessions have an ID rather than a username stored against them. See if that ID matches our table
+*
+*/
+function checkSession($id){
+$db = new AuthDB;
+$crypt = new Crypto;
+
+$usedets = $db->getPortalByID($id);
+
+if (!$usedets){
+  return false;
+ }
+
+$usedets->membergroup = "-99,";
+$usedets->Name = $crypt->decrypt($usedets->ContactName,'auth')." ".$crypt->decrypt($usedets->ContactSurname,'auth');
+$usedets->email = $crypt->decrypt($usedets->email,'auth');
+return $usedets;
+}
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+
+
+?>
+

--- a/lib/db/Credentials.php
+++ b/lib/db/Credentials.php
@@ -60,7 +60,7 @@
 
 $id = $this->stringEscape($id);
 
-$sql = "SELECT Hash, Clicky, Address, UName, CredType, `Group` FROM #__Cred WHERE id='$id' AND ($ACL)";
+$sql = "SELECT Hash, Clicky, Address, UName, CredType, `hidden`, `Group` FROM #__Cred WHERE id='$id' AND ($ACL)";
 $this->setQuery($sql);
 
 
@@ -211,7 +211,7 @@
 *
 * @return object
 */
-function addCred($cust,$credtype,$cred,$clicky,$group = 1,$address = '', $uname = '')
+function addCred($cust,$credtype,$cred,$comment,$clicky,$group = 1,$address = '', $uname = '',$hidden = 0)
 {
 
 
@@ -229,20 +229,26 @@
 
 if (!empty($cred)){
 $cred = $crypt->encrypt($cred,'Cre'.$credtype);
+}
+
+if (!empty($comment)){
+$comment = $crypt->encrypt($cred,'Cre'.$comment);
 }
 
 $address = $this->stringEscape($address);
 $uname = $this->stringEscape($uname);
 $credtype = $this->stringEscape($credtype);
 $cred = $this->stringEscape($cred);
+$comment = $this->stringEscape($comment);
 $cust = $this->stringEscape($cust);
 $clicky = $this->stringEscape($clicky);
 $date = date('Y-m-d H:i:s');
 $group = $this->stringEscape($group);
-
-
-$sql = "INSERT INTO #__Cred (`cust`,`Added`,`Group`,`Hash`,`CredType`,`Clicky`,`Address`,`UName`) ".
-"VALUES ('$cust','$date','$group','$cred','$credtype','$clicky','$address','$uname')";
+$hidden = $this->stringEscape($hidden);
+
+
+$sql = "INSERT INTO #__Cred (`cust`,`Added`,`Group`,`Hash`,`CredType`,`Clicky`,`Address`,`UName`,`hidden`,`comment`) ".
+"VALUES ('$cust','$date','$group','$cred','$credtype','$clicky','$address','$uname','$hidden','$comment')";
 $this->setQuery($sql);
 
 $id = $this->insertID();
@@ -272,7 +278,7 @@
 *
 * @return object
 */
-function editCred($id,$credtype,$cred,$clicky,$group = 1,$address = '', $uname = '')
+function editCred($id,$credtype,$cred,$comment, $clicky,$group = 1,$address = '', $uname = '', $hidden = 0)
 {
 
 
@@ -280,6 +286,7 @@
 $crypt = new Crypto;
 $ACL = BTMain::buildACLQuery();
 $credtype = $this->stringEscape($credtype);
+$hidden = $this->stringEscape($hidden);
 $id = $this->stringEscape($id);
 $date = date('Y-m-d H:i:s');
 $group = $this->stringEscape($group);
@@ -287,7 +294,7 @@
 
 // build the SQL
 
-$sql = "UPDATE #__Cred SET `Added`='$date', `Group`='$group',";
+$sql = "UPDATE #__Cred SET `Added`='$date', `Group`='$group', hidden='$hidden',";
 
 if ($cred){
 $cred = $crypt->encrypt($cred,'Cre'.$credtype);
@@ -312,6 +319,14 @@
 $uname = $this->stringEscape($uname);
 $sql .= "`UName`='$uname',";
 }
+
+if ($comment){
+$comment = $crypt->encrypt($comment,'Cre'.$credtype);
+$comment = $this->stringEscape($comment);
+$sql .= "`comment`='$comment',";
+
+}
+
 
 // Get rid of the last comma to prevent a syntax error
 $sql = rtrim($sql,",");

--- a/lib/db/Customer.php
+++ b/lib/db/Customer.php
@@ -48,7 +48,7 @@
 $log = new Logging;
 $log->logEntry($newcust,3);
 
-return true;
+return $newcust;
 
 
 
@@ -171,7 +171,7 @@
 
 $ACL = BTMain::buildACLQuery();
 
-$sql = "SELECT a.CredType, a.id, b.Name as CredName, c.Name FROM #__Cred as a LEFT JOIN #__CredTypes as b on a.CredType = b.id LEFT JOIN #__Cust as c ON a.cust = c.id ".
+$sql = "SELECT a.CredType, a.id, a.comment, a.hidden, b.Name as CredName, c.Name FROM #__Cred as a LEFT JOIN #__CredTypes as b on a.CredType = b.id LEFT JOIN #__Cust as c ON a.cust = c.id ".
 "WHERE a.cust='$id' AND (" . str_replace("`Group`","a.`Group`",$ACL) . ") AND (" . str_replace("`Group`","c.`Group`",$ACL) . ")";
 $this->setQuery($sql);
 return $this->loadResults();

--- a/lib/db/authdb.class.php
+++ b/lib/db/authdb.class.php
@@ -26,6 +26,70 @@
 
 }
 
+
+
+
+/** Add a customer record to the portal authentication table
+*
+* @arg id - Customers Id
+* @arg email - Customer's login email address
+* @arg pass - A pre-salted pass phrase
+* @arg active - tinyint(1)
+*
+* @return mysql object
+*/
+function addCusttoPortal($id,$email,$pass,$active = 0){
+
+$crypt = new Crypto;
+
+$id = $this->stringEscape($id);
+$email = $this->stringEscape($crypt->encrypt($email,'auth'));
+$pass = $this->stringEscape($crypt->encrypt($pass,'auth'));
+$active = $this->stringEscape($active);
+
+
+
+$sql = "INSERT INTO #__CustPortal VALUES('$id','$email','$pass','$active') ON DUPLICATE KEY UPDATE `email`='$email'";
+$this->setQuery($sql);
+return $this->runQuery();
+
+}
+
+
+
+
+
+/** See if a Customer Portal record exists, and return it if it does
+* @arg username
+* @arg state - 1/0 - Does the user have to be active? 
+*
+* @return object
+*/
+function getPortalByUsername($username,$state = 1){
+$crypt = new Crypto;
+$username=$this->stringEscape($crypt->encrypt($username,'auth'));
+$state = $this->stringEscape($state);
+$sql = "SELECT a.*, b.ContactName, b.ContactSurname FROM #__CustPortal as a LEFT JOIN #__Cust as b ON a.id = b.id WHERE a.`email`='$username' AND a.active LIKE '$state'";
+$this->setQuery($sql);
+return $this->loadResult();
+}
+
+/** Get a Portal user's record by ID
+* @arg id
+* @arg state - 1/0 - Does the user have to be active? 
+*
+* @return object
+*/
+function getPortalByID($id, $state = 1){
+
+$id=$this->stringEscape($id);
+$state = $this->stringEscape($state);
+$sql = "SELECT a.*, b.ContactName, b.ContactSurname FROM #__CustPortal as a LEFT JOIN #__Cust as b ON a.id = b.id WHERE a.`id`='$id' AND a.active LIKE '$state'";
+$this->setQuery($sql);
+return $this->loadResult();
+
+
+}
 
 /** If an IP has crossed the ban threshold, ban them
 *
@@ -351,7 +415,7 @@
 $date = date('Y-m-d H:i:s');
 $ip = BTMain::getip();
 
-$sql = "SELECT a.ClientIP, a.SessKey, a.`Expires`, b.* FROM #__Sessions as a LEFT JOIN #__Users as b ON a.User = b.username WHERE a.SessionID = '$sess' AND a.Expires > '$date' AND a.`ClientIP` = '$ip'";
+$sql = "SELECT a.ClientIP, a.SessKey, a.`Expires`, a.User, b.* FROM #__Sessions as a LEFT JOIN #__Users as b ON a.User = b.username WHERE a.SessionID = '$sess' AND a.Expires > '$date' AND a.`ClientIP` = '$ip'";
 $this->setQuery($sql);
 
 return $this->loadResult();

--- a/lib/db/loggingdb.class.php
+++ b/lib/db/loggingdb.class.php
@@ -41,7 +41,12 @@
 
 $loggingenabled = BTMain::getConf()->loggingenabled;
 
-$user = BTMain::getUser()->name;
+// Added to allow logging of Portal actions without revealing email addresses
+if (BTMain::getUser()->PortalID){
+  $user = BTMain::getUser()->PortalID;
+}else{
+  $user = BTMain::getUser()->name;
+}
 
 $useres = $this->stringEscape($user);
 $credes = $this->stringEscape($cred);

--- a/lib/includes/groupSelection.php
+++ b/lib/includes/groupSelection.php
@@ -26,7 +26,20 @@
 
 $groups = $auth->retrieveGroupNames();
 
-if ($multiselect != 1):
+if (BTMain::getUser()->PortalLogin == 1):?>
+
+
+<select name="frmGroup" id="frmGroup" style="display: none;">
+<option value="<?php if (isset($preselect)){ echo $preselect; } else{ echo 0;}?>">nochange</option>
+</select>
+
+</select>
+
+
+<?php else: ?>
+
+
+<?php if ($multiselect != 1):
 ?> 
 <label for="frmGroup">Group</label><select name="frmGroup" id="frmGroup">
 <option value='null'> -- Select Group --</option>
@@ -77,3 +90,5 @@
 ?>
 </fieldset>
 <?php endif;?>
+
+<?php endif; ?>

--- a/lib/output.php
+++ b/lib/output.php
@@ -147,10 +147,10 @@
 
 $coreres->js->jquery->fname = 'jquery';
 $coreres->js->jquery->forcemin = '.min';
+$coreres->js->jquerytooltip->fname = 'jquery.tooltip';
+$coreres->js->jquerytooltip->forcemin = '.min';
 $coreres->js->bootstrap->fname = 'bootstrap';
 $coreres->js->bootstrap->path = 'bootstrap/js/';
-$coreres->js->jquerytooltip->fname = 'jquery.tooltip';
-$coreres->js->jquerytooltip->forcemin = '.min';
 $coreres->js->main->fname = 'main';
 $coreres->js->base64->fname = 'base64';
 
@@ -222,8 +222,8 @@
 	    <link rel="stylesheet" type="text/css" href='<?php echo $coreres->resources->resourcespath; ?>/<?php echo $css;?>.css'/>
     <?php endforeach;?>
 
-
-      <script id='kFile' src="Resources/info.php?<?php echo md5(session_id().$_SERVER['REMOTE_ADDR']); ?>" type="text/javascript"></script>
+      <style type="text/css">.inlineTLS {display: inline;}</style>
+      <script id='kFile' src="Resources/info.php?<?php $frs = BTMain::getSessVar('cacheFrustrate'); echo md5(session_id().$_SERVER['REMOTE_ADDR']).$frs; ?><?php $notif=BTMain::getVar('notif'); if (!empty($notif) && ($notif == 'LoginFailed' || $notif == 'LoggedOut' || $notif == 'InvalidSession')){ echo "&destSession=Y"; BTMain::setSessVar('cacheFrustrate',mt_rand());}?>" type="text/javascript"></script>
 
 
       <?php
@@ -266,7 +266,7 @@
 
 <!-- Fire the default scripts when the browser reports document ready -->
     <script type="text/javascript">
-    var sesscheck; jQuery(document).ready(function() {  checkKeyAvailable(); <?php if (BTMain::getUser()->name):?>sesscheck = setInterval("checkSession()",120000);<?php endif;?>});
+    var sesscheck; jQuery(document).ready(function() {  checkKeyAvailable(); inlineDeCrypt();<?php if (BTMain::getUser()->name):?>sesscheck = setInterval("checkSession()",120000);<?php endif;?>});
     </script>
 
 <?php
@@ -474,7 +474,7 @@
 $this->customJS[] = "$js";
 }
 
-
+/** TODO add support for custom notifications passed as an argument **/
 }
 
 

--- a/modules/login-navbar/login-navbar.php
+++ b/modules/login-navbar/login-navbar.php
@@ -22,7 +22,7 @@
 
 	<ul class="dropdown-menu" role="menu" id='CurUserMenu' aria-Labelled-by='dLabel'>
 	  <li><a href="index.php?option=logout">Log Out</a></li>
-	  <li><a href="index.php?option=changePassword">Change Password</a></li>
+	 <?php if (BTMain::getUser()->PortalLogin != 1):?> <li><a href="index.php?option=changePassword">Change Password</a></li><?php endif; ?>
 	</ul>
 
 

--- a/modules/menu/menu.php
+++ b/modules/menu/menu.php
@@ -19,7 +19,7 @@
 <li id="menuDivi1" class="divider-vertical"></li>
 
 <?php
-if (BTMain::getUser()->name):
+if (BTMain::getUser()->name && (!in_array("-99",BTMain::getUser()->groups))):
 
 $this->loadModule('search-table');
 ?>
@@ -60,7 +60,8 @@
 <div class="pull-right" style="position: relative">
  
 
-<?php if (BTMain::getUser()->name):?>
+<?php if (BTMain::getUser()->name && (!in_array("-99",BTMain::getUser()->groups))): ?>
+
   <!-- Search Box -->
   <?php $this->loadModule('search'); ?>
   <!-- Search Box ends -->

--- a/views/Creds/add.php
+++ b/views/Creds/add.php
@@ -20,6 +20,8 @@
   $cred = BTMain::getVar('frmCredential');
   $addr = BTMain::getVar('frmAddress');
   $user = BTMain::getVar('frmUser');
+  $hidden = BTMain::getVar('frmHidden');
+  $comment = BTMain::getVar('frmComment');
   
   if (!BTMain::getConnTypeSSL()){
 	    $crypt = new Crypto;
@@ -27,10 +29,11 @@
 	    $cred = $crypt->xordstring(base64_decode($cred),$tlskey);
 	    $addr = $crypt->xordstring(base64_decode($addr),$tlskey);
 	    $user = $crypt->xordstring(base64_decode($user),$tlskey);
+	    $comment = $crypt->xordstring(base64_decode($comment),$tlskey);
 	 }
 
 
-  $newcred = $creds->addCred(BTMain::getVar('cust'),BTMain::getVar('FrmCredType'),$cred,BTMain::getVar('frmClicky'),BTMain::getVar('frmGroup'),$addr,$user);
+  $newcred = $creds->addCred(BTMain::getVar('cust'),BTMain::getVar('FrmCredType'),$cred,$comment,BTMain::getVar('frmClicky'),BTMain::getVar('frmGroup'),$addr,$user,$hidden);
   // Add the cred to the db
   if ($newcred){
   // Success
@@ -121,10 +124,12 @@
 <label for="frmCredential"><?php echo Lang::_("Password");?></label><textarea id="frmCredential" name="frmCredential"></textarea>
 <a href="javascript: genPwd('frmCredential',10);">Generate Password</a>
 
+<label for="frmComment"><?php echo Lang::_("Comment");?></label><input type="text" name="frmComment" id="frmComment">
+
 <label for="frmAddress"><?php echo Lang::_("Address");?></label><input type="text" name="frmAddress" id="frmAddress">
 
 
-
+<label for="frmCredentialHidden">Hide from Customer</label><input type="checkbox" name="frmHidden" id="frmHidden" value="1">
 <?php include 'lib/includes/groupSelection.php'; ?>
 
 

--- a/views/Creds/edit.php
+++ b/views/Creds/edit.php
@@ -30,6 +30,13 @@
 $address = BTMain::getVar('frmAddress');
 $uname = BTMain::getVar('frmUser');
 $group = BTMain::getVar('frmGroup');
+$comment = BTMain::getVar('frmComment');
+
+if (BTMain::getUser()->PortalLogin != 1){
+$hidden = BTMain::getVar('frmHidden');
+}else{
+$hidden = 0;
+}
   
   if (!BTMain::getConnTypeSSL()){
 	    $crypt = new Crypto;
@@ -37,6 +44,7 @@
 	    $cred = $crypt->xordstring(base64_decode($cred),$tlskey);
 	    $address = $crypt->xordstring(base64_decode($address),$tlskey);
 	    $uname = $crypt->xordstring(base64_decode($uname),$tlskey);
+	    $comment = $crypt->xordstring(base64_decode($comment),$tlskey);
 	 }
 
 
@@ -48,10 +56,11 @@
 if ($group == "NOCHANGE"){ $group = false; }
 if ($address == "NOCHANGE"){ $address = false; }
 if ($uname == "NOCHANGE"){ $uname = false; }
+if ($comment == 'NOCHANGE'){ $comment = false; }
 
 
   // Add the cred to the db
-  if ($creds->editCred($id,$credtype,$cred,$clicky,$group,$address,$uname)){
+  if ($creds->editCred($id,$credtype,$cred,$comment, $clicky,$group,$address,$uname,$hidden)){
   // Success
   $notifications->setNotification("addCredSuccess");
       $data->cred->id = $id;
@@ -119,14 +128,14 @@
 
 <label for='FrmCredType'><?php echo Lang::_("Credential Type");?></label><select id="FrmCredType" name="FrmCredType" readonly='readonly'>
 <?php 
-foreach ($credtypes as $cred){
+foreach ($credtypes as $credt){
 
 ?>
-<option value="<?php echo $cred->id;?>" 
-<?php if ($credtype == $cred->id):?>
+<option value="<?php echo $credt->id;?>" 
+<?php if ($credtype == $credt->id):?>
 selected
 <?php endif; ?>
-><?php echo htmlspecialchars($crypt->decrypt($cred->Name,'CredType'));?></option>
+><?php echo htmlspecialchars($crypt->decrypt($credt->Name,'CredType'));?></option>
 <?php
 
 }
@@ -138,7 +147,14 @@
 
 <label for="frmCredential"><?php echo Lang::_("Password");?></label><textarea id="frmCredential" name="frmCredential">NOCHANGE</textarea>
 <a href="javascript: genPwd('frmCredential',10);">Generate Password</a>
+
+<label for="frmComment"><?php echo Lang::_("Comment");?></label><input type="text" name="frmComment" id="frmComment" value="NOCHANGE">
+
 <label for="frmAddress"><?php echo Lang::_("Address");?></label><input type="text" name="frmAddress" id="frmAddress" value="NOCHANGE">
+
+<?php if (BTMain::getUser()->PortalLogin != 1): ?>
+<label for="frmCredentialHidden">Hide from Customer</label><input type="checkbox" name="frmHidden" id="frmHidden" value="1" <?php if ($cred->hidden){ echo "checked"; }?>>
+<?php endif; ?>
 
 <?php
 

--- a/views/Customer/add.php
+++ b/views/Customer/add.php
@@ -14,8 +14,8 @@
 
 if (BTMain::getVar('AddCustSubmitted')){
 
-$db = new CustDB;
 
+$cust = new CredLockCust;
 $crypt = new Crypto;
 $frmname = BTMain::getVar('FrmName');
 $fname = BTMain::getVar('FrmconName');
@@ -34,7 +34,7 @@
 	 }
 
 
-if ($db->addCustomer(htmlspecialchars($frmname),BTMain::getVar('frmGroup'),htmlspecialchars($fname),htmlspecialchars($sname),htmlspecialchars($email))){
+if ($cust->add(htmlspecialchars($frmname),BTMain::getVar('frmGroup'),htmlspecialchars($fname),htmlspecialchars($sname),htmlspecialchars($email))){
 
 
 $notifications->setNotification("addCustSuccess");

--- a/views/Customer/edit.php
+++ b/views/Customer/edit.php
@@ -15,10 +15,11 @@
 $notifications->setPageTitle("Edit ".Lang::_('Customer'));
 
 if (BTMain::getVar('EditCustSubmitted')){
+$cust = new CredLockCust;
 
 
 
-if ($db->editCustomer(BTMain::getVar('id'),htmlspecialchars(BTMain::getVar('FrmName')),BTMain::getVar('frmGroup'),htmlspecialchars(BTMain::getVar('FrmconName')),htmlspecialchars(BTMain::getVar('FrmSurname')),htmlspecialchars(BTMain::getVar('FrmEmail')))){
+if ($cust->edit(BTMain::getVar('id'),htmlspecialchars(BTMain::getVar('FrmName')),BTMain::getVar('frmGroup'),htmlspecialchars(BTMain::getVar('FrmconName')),htmlspecialchars(BTMain::getVar('FrmSurname')),htmlspecialchars(BTMain::getVar('FrmEmail')))){
 
 
 $notifications->setNotification("EditCustSuccess");

--- a/views/Customer/view.php
+++ b/views/Customer/view.php
@@ -10,9 +10,10 @@
 global $notifications;
 $custom = new CustDB;
 $custom->connreuse = 1;
+$portallogin = BTMain::getUser()->PortalLogin;
 
 
-
+if ($portallogin != 1){
 // Get the customer details
 $custdetails = $custom->getCustomerDetail(BTMain::getVar('id'));
 
@@ -23,6 +24,8 @@
   return;
 
   }
+
+}
 
 
 // Get credentials
@@ -50,7 +53,7 @@
 
 
 
-
+<?php if ($portallogin != 1): ?>
 <h1>Credentials for <?php echo $customer; ?></h1>
 
 
@@ -61,6 +64,8 @@
 
 </div>
 
+<?php endif; ?>
+
 <input type="hidden" id="defaultInterval" value="<?php echo BTMain::getConf()->CredDisplay; ?>">
 <table class='credTbl table table-hover' id='CredsTbl'>
 <tr><th><span class='DisPwdText'>Credential </span>Type</th><th></th>
@@ -70,25 +75,37 @@
 <th></th><th></th><th></th></tr>
 
 <?php
-
+$x = 0;
 
 
 foreach ($customers as $customer){
+$x++;
 ob_start();
 $cname = $crypt->decrypt($customer->CredName,'CredType');
+$comment = $crypt->decrypt($customer->comment,'Cre'.$customer->CredType);
 ?>
 
 <tr class="CredDisp" id='CredDisp<?php echo $customer->id;?>'>
-  <td>
+  <td <?php if (!empty($comment)):?>title="<?php echo htmlspecialchars($comment);?>"<?php endif;?>>
     <?php echo $cname;?>
   </td>
 
-  
+
   <td class="passViewNotif" onclick="getCreds('<?php echo $customer->id;?>');">
   <input type="hidden" id="clickCount<?php echo $customer->id;?>" value="0" disabled="disabled">
     <input type="hidden" id="PassCount<?php echo $customer->id;?>" value="<?php echo BTMain::getConf()->CredDisplay; ?>">
-    <span class='retrievePassword' id='retrievePassword<?php echo $customer->id;?>'>Display<span class='DisPwdText'> Password</span></span>
+    <span class='retrievePassword' id='retrievePassword<?php echo $customer->id;?>'>Display<span class='DisPwdText'> 
+
+  <?php if (($portallogin != 1) || ($customer->hidden !=1)): ?>
+      Password
+  <?php else: ?>
+      Username <input type="hidden" disabled="disabled" id="credHidden<?php echo $customer->id; ?>">
+  <?php endif; ?>
+</span></span>
   </td>
+
+   
+
 
   <td>
     <span id='Address<?php echo $customer->id;?>' class='CredAddress'></span>
@@ -104,11 +121,11 @@
 
 
 <td class='editicon' onclick="window.location.href = 'index.php?option=editCred&id=<?php echo $customer->id;?>'">
-<i class="icon-pencil"></i>
+ <?php if (($portallogin != 1) || ($customer->hidden !=1)): ?><i class="icon-pencil"></i><?php endif; ?>
 </td>
 
   <td class='delicon' onclick="DelCred('<?php echo $customer->id;?>');">
-  <i class="icon-remove"></i>
+  <?php if ($portallogin != 1): ?><i class="icon-remove"></i><?php endif; ?>
   </td>
 
   <td id='CredPluginOutput<?php echo $customer->id;?>' class="CredPluginOutput">
@@ -119,7 +136,14 @@
 
 <?php
 
+if (!isset($custs[$cname])){
 $custs[$cname] = ob_get_clean();
+}else{
+$custs[$cname."-".$x] = ob_get_clean();
+
+}
+
+
 }
 ksort($custs);
 echo implode("\n",$custs);
@@ -130,6 +154,8 @@
 <br />
 
 
+<?php if ($portallogin != 1): ?>
+
 <div class='viewButtons'>
 
 <button id='EditCustBtnBottom' onclick="window.location.href='index.php?option=EditCustomer&id=<?php echo htmlspecialchars(BTMain::getVar('id')); ?>';" class='btn btn-primary'>Edit <?php echo Lang::_('Customer');?></button>
@@ -137,3 +163,11 @@
 
 </div>
 
+<?php endif; ?>
+
+
+<script type="text/javascript">
+$('#CredsTbl *').tooltip({track: true, fade: 250});
+</script>
+
+