Single login per user

Ι want any new login of a user to cancel the previous one.
So a user couldn’t be logged in multiple times.

How is this possible?

You could try enabling the ‘Validate User IP Address’ in Admin -> System Settings. This should prevent multiple sessions from multiple locations.

Thanks,

Will.

Ok. So we are half way to full accomplishment.
Different locations can be prevented by ‘Validate User IP Address’ in Admin.

How about multiple logins from same location/IP?

That’s not restricted out of the box, so you’d need to customise to achieve this.

Thanks,

Will.

I have notice that. Any suggestions?

After some research here is my result.
I need a after_login hook, a after_ui_frame hook and a field in db to store tha last login session id.
First i created “lastSID” field in users table as char(36) so the after_login hook can store session id to db

Second step.
I added in suitecrm/custom/modules/Users/logic_hooks.php this:
$hook_array[‘after_login’][] = Array(90, ‘Update Session’, ‘amc/SessionHooks.php’,‘SingleSID’, ‘UpdSID’);
Then created the “amc/SessionHooks.php” file with the following inside

class SingleSID{
	function UpdSID(){
		include ('/var/www/vhosts/localhost/suitecrm/config.php');
		
		$conn = new mysqli($sugar_config['dbconfig']['db_host_name'],$sugar_config['dbconfig']['db_user_name'],$sugar_config['dbconfig']['db_password'],$sugar_config['dbconfig']['db_name']);    //connect
		mysqli_set_charset($conn,'utf8');
		
		//Retrieve SID and UID
		$curSID='';
		$curUID='';
		
		//UPDATE SID
		$conn->query('UPDATE `suitecrm`.`users` SET lastSID='.$curSID.' where id='.$curUID.';');
	}
}

but i don’t know how to retrieve the current session ID($curSID) and current user id ($curUID)

Third step will be to check curSID and lastSID depending on curUID and if they match nothing happens, if not, the session will be destroyed.
Also i will use an “after_ui_frame” hook located here suitecrm/custom/modules/logic_hooks.php
I found /suitecrm/include/SugarObjects/SugarSession.php the must be related to session ids but i don’t know how to use it.

Anyone who can help with session and user id retrieve?
Thank you in advance.

I achieved the single session per user. I created a field inside users table and there will be saved the last session after a successful login.
Then an after_login hook will update the lastSID and an after_ui_frame hook will check the lastSID with current session id.

FIRST
Run

ALTER TABLE users ADD COLUMN lastSID VARCHAR(36) NULL AFTER is_group;

at your mysql database through phpmyadmin or workbench. This will add the necessary field in users table to save the session id after a successful login.
SECOND
Create a Hook_LoginSessionUpdate.php file and put the below code inside. Reaplace XXXX with your domain and/or suitecrm folder. This file will be used at after_login hook and stores into database the session id.

class SingleLogin{
	function UpdSID(){
		include  ('/var/www/vhosts/XXXX/config.php');
		global $current_user;		
		//Retrieve SID and UID (below code copied from /modules/Trackers/monitor/Monitor.php)
 		$curSID = session_id();
	    if(!empty($curSID) && strlen(curSID) > MAX_SESSION_LENGTH) {
	       $curSID = md5($curSID);
	    }		
		$curUID=$current_user->id;
	    	//UPDATE SID & UID
		$conn = new mysqli($sugar_config['dbconfig']['db_host_name'],$sugar_config['dbconfig']['db_user_name'],$sugar_config['dbconfig']['db_password'],$sugar_config['dbconfig']['db_name']);    //connect
		mysqli_set_charset($conn,'utf8');
		$conn->query("UPDATE users SET lastSID='".$curSID."' where id='".$curUID."';");
		$conn->close();
	}
}

Create a second file with name Hook_CheckSession.php and put inside the below code. Replace XXXX with your domain and/or suitecrm folder as you did with the previous file. This file will be used at after_ui_frame and compares current session id with last saved session id(lastSID).

class SingleLogin{
	function ChkSID(){
		include  ('/var/www/vhosts/XXXX/config.php');
		global $current_user;
		//Retrieve SID and UID
 		$curSID = session_id();
	    if(!empty($curSID) && strlen(curSID) > MAX_SESSION_LENGTH) {
	       $curSID = md5($curSID);
	    }
		$curUID=$current_user->id;
		//Compare current session with last login session based on user id
		$conn = new mysqli($sugar_config['dbconfig']['db_host_name'],$sugar_config['dbconfig']['db_user_name'],$sugar_config['dbconfig']['db_password'],$sugar_config['dbconfig']['db_name']);    //connect
		mysqli_set_charset($conn,'utf8');
		$result=$conn->query("select lastSID from users where id='".$curUID."';");
		$lastSID=$result->fetch_array();
		if ($lastSID[0]===$curSID){
			//Do nothing
		}
		else {//Destroy previous session
			session_destroy();
		}
		$result->free();
		$conn->close();
	}
}

THIRD
Create a folder in your suitecrm folder and upload the previous two files in that folder. Don’t forget to change the section with you own.
Then go to /custom/modules/Users/logic_hooks.php and add, before the ?>, the below line

$hook_array['after_login'][] = Array(90, 'Update Session', '<the-just-created-folder>/Hook_LoginSessionUpdate.php','SingleSID', 'UpdSID');

Then go to /custom/modules/logic_hooks.php and add, before the ?>, the below line

$hook_array['after_ui_frame'][] = Array(90, 'Check Session', '<the-just-created-folder>/Hook_CheckSession.php','SingleLogin', 'ChkSID');

To test it, login to your suitecrm from chrome.Leave the window open and then login again to your suitecrm from firefox this time. Leave the windows open and go back to you chrome window and refresh the page. It should reload and then redirects you to the login page.

Enjoy!

1 Like

Where is define “MAX_SESSION_LENGTH”?

According to my comments it is located and defined in file suitecrm-folder/modules/Trackers/monitor/Monitor.php

You can check here (lines 48 & 236)