├── .gitignore ├── LICENSE ├── composer.json ├── readme.md └── src ├── AuthenticationHandler.php ├── Middleware ├── DeviceCheck.php └── SessionTracker.php ├── Models ├── Device.php ├── Session.php └── SessionRequest.php ├── SessionTracker.php ├── SessionTrackerFacade.php ├── SessionTrackerServiceProvider.php ├── Traits └── SessionTrackerUserTrait.php ├── config └── config.php └── migrations ├── 2016_01_02_091755_create_sessions_table.php ├── 2016_01_02_092453_create_session_requests_table.php ├── 2016_01_03_152221_add_block_colomn_to_sessions_table.php ├── 2016_01_03_153846_add_blocked_by_colomn_to_sessions_table.php ├── 2016_01_10_092114_create_devices_table.php └── 2016_01_10_114304_add_device-uid_and_login_code_columns_to_sessions_table.php /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | composer.lock 3 | docs 4 | vendor 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Hamed Mehryar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hamedmehryar/laravel-session-tracker", 3 | "description": "This package provides session tracking functionalities, multisession management and user device management features for laravel applications.", 4 | "type": "library", 5 | "require": { 6 | "php": ">=5.4.0", 7 | "laravel/framework": ">5.0", 8 | "nesbot/carbon": "~1.0", 9 | "jenssegers/agent": "^2.3" 10 | }, 11 | "license": "MIT", 12 | "authors": [ 13 | { 14 | "name": "Hamed Mehryar", 15 | "email": "hamed@netlinks.af" 16 | } 17 | ], 18 | "autoload": { 19 | "psr-4": { 20 | "Hamedmehryar\\SessionTracker\\": "src/" 21 | } 22 | }, 23 | "minimum-stability": "stable" 24 | } 25 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Laravel Session Tracker 2 | This package provides session tracking functionalities, multisession management and user device management features for laravel applications. 3 | 4 | 5 | ## Features 6 | * Session Management 7 | * Session Log 8 | * Multiple session for users 9 | * Request Log 10 | * User Devices 11 | 12 | 13 | ## Installation (Laravel 5.x) 14 | In composer.json: 15 | 16 | "require": { 17 | "hamedmehryar/laravel-session-tracker" "1.0.0" 18 | } 19 | 20 | Run: 21 | 22 | composer update 23 | 24 | Add the service provider to `config/app.php` under `providers`: 25 | 26 | 'providers' => [ 27 | Hamedmehryar\SessionTracker\SessionTrackerServiceProvider::class, 28 | ] 29 | 30 | Add the SessionTracker alias to `config/app.php` under `aliases`: 31 | 32 | 'aliases' => [ 33 | 'SessionTracker' => 'Hamedmehryar\SessionTracker\SessionTrackerFacade', 34 | ] 35 | 36 | Update config file to reference your login and logout route names: 37 | 38 | config/sessionTracker.php 39 | 40 | Migrate your database: 41 | 42 | php artisan migrate 43 | 44 | Add the trait to your user model: 45 | 46 | use Hamedmehryar\SessionTracker\Traits\SessionTrackerUserTrait; 47 | 48 | class User extends Model { 49 | use SessionTrackerUserTrait; 50 | } 51 | 52 | 53 | Add the DeviceCheck middleware in your kernel.php file: 54 | 55 | protected $middleware = [ 56 | 'Hamedmehryar\SessionTracker\Middleware\DeviceCheck', 57 | ]; 58 | 59 | 60 | In Your routes.php file you should add 'session' middleware for routes which you want to keep track of: 61 | 62 | Route::group(['middleware'=>'session'], function(){ 63 | 64 | Route::get('your-route', 'YourController@yourAction'); 65 | 66 | }); 67 | 68 | ## Usage 69 | 70 | From your user models: 71 | 72 | $user->sessions(); //returns all the sessions of the user form the begining of usage of the package 73 | 74 | $user->activeSessions(); //returns all currently active sessions for the user. (User may be logged in with same credentials from different devices) 75 | 76 | $user->activeSessions(true); //return all active sessions for the user except the current session. 77 | 78 | $user->getFreshestSession(); //Returns the most recent session of the user 79 | 80 | $user->devices(); //Returns the collection of users saved trusted devices. 81 | 82 | $user->devicesUids(); //Returns array of users saved trusted devices Ids. 83 | 84 | From SessionTrackerFacade: 85 | 86 | SessionTracker::startSession(); //Creates a new session for current user 87 | 88 | SessionTracker::endSession(); //End the current session for the current user 89 | 90 | SessionTracker::endSession(true); //End the current session for the current user and forgets the session 91 | 92 | SessionTracker::renewSession(); //Restarts the ended session which is not forgotten for the current user. Usefull for restarting the session after locking it for inactivity 93 | 94 | SessionTracker::refreshSession($request); //Keeps the session alive for each request. Useful in middleware 95 | 96 | SessionTracker::logSession($request); //Logs the current request for the current session. (request logs stored in sessiontracker_session_requests table) 97 | 98 | SessionTracker::isSessionInactive(); //Checks if the session is inactive. Determines the inactiveness by subtracting the **delay between last activity and current time** from the **inactivity_seconds** in sessionTracker config file. 99 | 100 | SessionTracker::isSessionInactive($user); //Checks if the session for a specific user is inactive. Determines the inactiveness by subtracting the **delay between last activity and current time** from the **inactivity_seconds** in sessionTracker config file. 101 | 102 | SessionTracker::blockSession($sessionId); //Blocks (ends and forgets) the current session for the user. (Useful if the user wants to controll all her sessions and block a specific session in a specific location) 103 | 104 | SessionTracker::sessionRequests($sessionId); //Returns all requests done by a specific session 105 | 106 | SessionTracker::isSessionBlocked(); //Checks if current user does not have an active session 107 | 108 | SessionTracker::lockSessionByCode(); //Locks a session by a security code to be unlocked by that code and returns the code. (Usefull for two-step authentication implementation) 109 | 110 | SessionTracker::securityCode(); //Returns the security code (hash) for the locked session. 111 | 112 | SessionTracker::isSessionLocked(); //Checks if the current session is locked by a security code. 113 | 114 | SessionTracker::unlockSessionByCode($code); //Unlocks the locked session by passing the security code. (returns -1 if the code is invalid, -2 if it's expired and 0 if success) 115 | 116 | SessionTracker::isUserDevice(); //Returns true if the current device is trusted by the user 117 | 118 | SessionTracker::deleteDevice($id); //Deletes a trusted device for the user 119 | 120 | SessionTracker::addUserDevice(); //Add the current device as trusted by the user 121 | 122 | SessionTracker::forgotSession(); //Checks if the session if forgotten 123 | 124 | SessionTracker::sessionId(); //Returns the sessionId for the current session 125 | 126 | SessionTracker::deleteSession(); //Deletes and forgets the current session 127 | 128 | SessionTracker::refreshSecurityCode(); //Renews the security code by which the current session is locked 129 | 130 | ## Author 131 | 132 | - [Hamed Mehryar](https://github.com/hamedmehryar) 133 | 134 | -------------------------------------------------------------------------------- /src/AuthenticationHandler.php: -------------------------------------------------------------------------------- 1 | listen('Illuminate\Auth\Events\Login', 'Hamedmehryar\SessionTracker\AuthenticationHandler@onLogin'); 28 | } 29 | } -------------------------------------------------------------------------------- /src/Middleware/DeviceCheck.php: -------------------------------------------------------------------------------- 1 | auth = $auth; 27 | } 28 | 29 | /** 30 | * Handle an incoming request. 31 | * 32 | * @param \Illuminate\Http\Request $request 33 | * @param \Closure $next 34 | * @return mixed 35 | */ 36 | public function handle($request, Closure $next) 37 | { 38 | if ($this->auth->guest()) 39 | { 40 | if ($request->ajax()) 41 | { 42 | return response('Unauthorized.', 401); 43 | } 44 | else 45 | { 46 | return redirect()->route(Config::get('sessionTracker.logout_route_name')); 47 | } 48 | SessionTrackerFacade::endSession(true); 49 | }else{ 50 | if(SessionTrackerFacade::isSessionBlocked() || SessionTrackerFacade::isSessionInactive()){ 51 | if ($request->ajax()) 52 | { 53 | return response('Unauthorized.', 401); 54 | } 55 | else 56 | { 57 | return redirect()->route(Config::get('sessionTracker.logout_route_name')); 58 | } 59 | } 60 | elseif(SessionTrackerFacade::isSessionLocked()){ 61 | return redirect()->route(Config::get('sessionTracker.security_code_route_name')); 62 | } 63 | SessionTrackerFacade::refreshSession($request); 64 | SessionTrackerFacade::logSession($request); 65 | } 66 | return $next($request); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/Models/Device.php: -------------------------------------------------------------------------------- 1 | devicesUids())){ 18 | return true; 19 | } 20 | } 21 | return false; 22 | } 23 | 24 | public static function addUserDevice(){ 25 | if(Cookie::has('d_i')){ 26 | self::create([ 27 | 'user_id' => Auth::user()->id, 28 | 'uid' => Cookie::get('d_i'), 29 | 'browser' => Agent::browser(), 30 | 'platform'=> Agent::platform(), 31 | 'device' => Agent::device() 32 | ]); 33 | return true; 34 | }else{ 35 | return false; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Models/Session.php: -------------------------------------------------------------------------------- 1 | hasMany('Hamedmehryar\SessionTracker\Models\SessionRequest')->orderBy('id', 'desc'); 22 | } 23 | 24 | public static function start(){ 25 | 26 | $deviceId = Cookie::get('d_i', NULL); 27 | $userId = Auth::user()->id; 28 | $dateNow = Carbon::now(); 29 | if($deviceId){ 30 | self::where('device_uid', $deviceId)->where('user_id', $userId)->whereNull('end_date')->update(['end_date' => $dateNow]); 31 | } 32 | $session = self::create([ 33 | 'user_id' => $userId, 34 | "browser" => Agent::browser(), 35 | "browser_version" => Agent::version(Agent::browser()), 36 | "platform" => Agent::platform(), 37 | "platform_version" => Agent::version(Agent::platform()), 38 | "mobile" => Agent::isMobile(), 39 | "device" => Agent::device(), 40 | "robot" => Agent::isRobot(), 41 | "device_uid" => $deviceId, 42 | 'ip' => $_SERVER['REMOTE_ADDR'], 43 | 'last_activity'=> $dateNow 44 | ]); 45 | \Illuminate\Support\Facades\Session::put('dbsession.id', $session->id); 46 | return $session; 47 | } 48 | 49 | public static function end($forgetSession){ 50 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 51 | try { 52 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 53 | } catch (\Exception $e) { 54 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 55 | return false; 56 | } 57 | $session->end_date = Carbon::now(); 58 | $session->save(); 59 | if($forgetSession){ 60 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 61 | } 62 | return true; 63 | } 64 | return false; 65 | } 66 | 67 | public static function renew(){ 68 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 69 | try { 70 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 71 | } catch (\Exception $e) { 72 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 73 | return false; 74 | } 75 | $session->last_activity = Carbon::now(); 76 | $session->end_date = null; 77 | $session->save(); 78 | return true; 79 | } 80 | return false; 81 | } 82 | 83 | public static function refresh($request){ 84 | foreach(Config::get('sessionTracker.ignore_refresh', array()) as $ignore){ 85 | if(($request->route()->getName() == $ignore['route'] || $request->route()->getUri() == $ignore['route']) && $request->route()->methods()[0] == $ignore['method']){ 86 | break; 87 | }else{ 88 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 89 | try { 90 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 91 | } catch (\Exception $e) { 92 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 93 | return false; 94 | } 95 | $session->last_activity = Carbon::now(); 96 | $session->save(); 97 | return true; 98 | } 99 | } 100 | } 101 | return false; 102 | } 103 | 104 | public static function log($request){ 105 | if(self::latestRequest() == null ||$request->getRequestUri() != self::latestRequest()->uri){ 106 | foreach(Config::get('sessionTracker.ignore_log', array()) as $ignore){ 107 | if(($request->route()->getName() == $ignore['route'] || $request->route()->getUri() == $ignore['route']) && $request->route()->methods()[0] == $ignore['method']){ 108 | break; 109 | }else{ 110 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 111 | $sessionRequest = SessionRequest::create([ 112 | 'session_id' => \Illuminate\Support\Facades\Session::get('dbsession.id'), 113 | 'route' => $request->route()->getUri(), 114 | 'uri' => $request->getRequestUri(), 115 | 'method' => count($request->route()->getMethods())>0?$request->route()->getMethods()[0]:NULL, 116 | 'name' => $request->route()->getName(), 117 | 'parameters' => count($request->route()->parameters())>0?json_encode($request->route()->parameters()):NULL, 118 | 'type' => $request->ajax()?1:0, 119 | ]); 120 | if($sessionRequest){ 121 | return true; 122 | }else{ 123 | return false; 124 | } 125 | } 126 | } 127 | } 128 | } 129 | return false; 130 | } 131 | 132 | public static function latestRequest(){ 133 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 134 | try { 135 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 136 | } catch (\Exception $e) { 137 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 138 | return null; 139 | } 140 | if($session->requests()->count() > 0){ 141 | return $session->requests()->orderBy('created_at', 'desc')->first(); 142 | }else{ 143 | return null; 144 | } 145 | } 146 | } 147 | public static function isInactive($user){ 148 | if($user != null){ 149 | if($user->sessions->count() > 0) 150 | { 151 | if($user->getFreshestSession()->last_activity != null && abs(strtotime($user->getFreshestSession()->last_activity)-(strtotime(date('Y-m-d H:i:s')))) > Config::get('sessionTracker.inactivity_seconds', 1200)){ 152 | return true; 153 | }else{ 154 | return false; 155 | } 156 | } 157 | return true; 158 | }else{ 159 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 160 | try { 161 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 162 | } catch (\Exception $e) { 163 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 164 | return false; 165 | } 166 | if($session->last_activity != null && abs(strtotime($session->last_activity)-(strtotime(date('Y-m-d H:i:s')))) > 1200){ 167 | return true; 168 | }else{ 169 | return false; 170 | } 171 | } 172 | return true; 173 | } 174 | 175 | } 176 | 177 | public static function blockById($sessionId){ 178 | try { 179 | $session = self::findOrFail($sessionId); 180 | } catch (\Exception $e) { 181 | return false; 182 | } 183 | $session->block(); 184 | return true; 185 | 186 | } 187 | public function block(){ 188 | $this->block = self::STATUS_BLOCKED; 189 | $this->blocked_by = Auth::user()->id; 190 | $this->save(); 191 | } 192 | 193 | public static function isBlocked(){ 194 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 195 | try { 196 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 197 | } catch (\Exception $e) { 198 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 199 | return true; 200 | } 201 | if($session->block == self::STATUS_BLOCKED){ 202 | return true; 203 | }else{ 204 | return false; 205 | } 206 | } 207 | return true; 208 | 209 | } 210 | 211 | 212 | public static function isLocked(){ 213 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 214 | try { 215 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 216 | } catch (\Exception $e) { 217 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 218 | return true; 219 | } 220 | if($session->login_code != null){ 221 | return true; 222 | }else{ 223 | return false; 224 | } 225 | } 226 | return true; 227 | 228 | } 229 | 230 | public static function loginCode(){ 231 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 232 | try { 233 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 234 | } catch (\Exception $e) { 235 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 236 | return null; 237 | } 238 | return $session->login_code; 239 | } 240 | return null; 241 | 242 | } 243 | 244 | 245 | public static function lockByCode(){ 246 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 247 | try { 248 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 249 | } catch (\Exception $e) { 250 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 251 | return NULL; 252 | } 253 | $code = rand(100000, 999999); 254 | $session->login_code = md5($code); 255 | $session->save(); 256 | return $code; 257 | 258 | } 259 | return NULL; 260 | } 261 | 262 | 263 | public static function refreshCode(){ 264 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 265 | try { 266 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 267 | } catch (\Exception $e) { 268 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 269 | return NULL; 270 | } 271 | $code = rand(100000, 999999); 272 | $session->login_code = md5($code); 273 | $session->created_at = Carbon::now(); 274 | $session->save(); 275 | return $code; 276 | 277 | } 278 | return NULL; 279 | } 280 | 281 | 282 | public static function unlockByCode($code){ 283 | if(\Illuminate\Support\Facades\Session::has('dbsession.id')){ 284 | try { 285 | $session = self::findOrFail(\Illuminate\Support\Facades\Session::get('dbsession.id')); 286 | } catch (\Exception $e) { 287 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 288 | return -1; 289 | } 290 | if(time() - strtotime($session->created_at) > Config::get('sessionTracker.security_code_lifetime', 1200)){ 291 | return -2; 292 | }else{ 293 | if(md5($code) == $session->login_code){ 294 | $session->login_code = NULL; 295 | $session->save(); 296 | return 0; 297 | } 298 | } 299 | 300 | } 301 | return -1; 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /src/Models/SessionRequest.php: -------------------------------------------------------------------------------- 1 | belongsTo('Hamedmehryar\SessionTracker\Models\Session'); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/SessionTracker.php: -------------------------------------------------------------------------------- 1 | app = $app; 34 | } 35 | 36 | /** 37 | * @return static 38 | */ 39 | public function startSession(){ 40 | return Session::start(); 41 | } 42 | 43 | /** 44 | * @param bool $forgetSession 45 | * @return bool 46 | */ 47 | public function endSession($forgetSession = false){ 48 | return Session::end($forgetSession); 49 | } 50 | 51 | /** 52 | * @return bool 53 | */ 54 | public function renewSession(){ 55 | return Session::renew(); 56 | } 57 | 58 | /** 59 | * @param $request 60 | * @return bool 61 | */ 62 | public function refreshSession($request){ 63 | return Session::refresh($request); 64 | } 65 | 66 | /** 67 | * @param $request 68 | * @return bool 69 | */ 70 | public function logSession($request){ 71 | return Session::log($request); 72 | } 73 | 74 | /** 75 | * @param null $user 76 | * @return bool 77 | */ 78 | public function isSessionInactive($user = null){ 79 | return Session::isInactive($user); 80 | } 81 | 82 | /** 83 | * @param $sessionId 84 | * @return bool 85 | */ 86 | public function blockSession($sessionId){ 87 | return Session::blockById($sessionId); 88 | } 89 | 90 | public function sessionRequests($sessionId){ 91 | try { 92 | $session = Session::findOrFail($sessionId); 93 | } catch (ModelNotFoundException $e) { 94 | return null; 95 | } 96 | return $session->requests; 97 | } 98 | /** 99 | * @return bool 100 | */ 101 | public function isSessionBlocked(){ 102 | return Session::isBlocked(); 103 | } 104 | 105 | /** 106 | * @return bool 107 | */ 108 | public function isSessionLocked(){ 109 | return Session::isLocked(); 110 | } 111 | 112 | /** 113 | * @return int|null 114 | */ 115 | public function lockSessionByCode(){ 116 | return Session::lockByCode(); 117 | } 118 | 119 | /** 120 | * @param $code 121 | * @return bool 122 | */ 123 | public function unlockSessionByCode($code){ 124 | return Session::unlockByCode($code); 125 | } 126 | 127 | /** 128 | * @return bool 129 | */ 130 | public function isUserDevice(){ 131 | return Device::isUserDevice(); 132 | } 133 | 134 | public function deleteDevice($id){ 135 | return Device::destroy($id); 136 | } 137 | 138 | /** 139 | * @param $uid 140 | * @param $browser 141 | * @param $platform 142 | * @param $device 143 | * @return bool 144 | */ 145 | public function addUserDevice(){ 146 | return Device::addUserDevice(); 147 | } 148 | 149 | public function forgotSession(){ 150 | return ! \Illuminate\Support\Facades\Session::has('dbsession.id'); 151 | } 152 | 153 | public function sessionId(){ 154 | return \Illuminate\Support\Facades\Session::get('dbsession.id', NULL); 155 | } 156 | 157 | public function deleteSession(){ 158 | 159 | if($this->sessionId() != null){ 160 | Session::destroy($this->sessionId()); 161 | \Illuminate\Support\Facades\Session::forget('dbsession.id'); 162 | } 163 | } 164 | 165 | public function securityCode(){ 166 | return Session::loginCode(); 167 | } 168 | 169 | public function refreshSecurityCode(){ 170 | return Session::refreshCode(); 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /src/SessionTrackerFacade.php: -------------------------------------------------------------------------------- 1 | publishes([ 16 | base_path('vendor/hamedmehryar/laravel-session-tracker/src/config/config.php') => config_path('sessionTracker.php'), 17 | base_path('vendor/hamedmehryar/laravel-session-tracker/src/migrations') => base_path('database/migrations') 18 | ]); 19 | 20 | $router = $this->app['router']; 21 | $router->middleware('session', 'Hamedmehryar\SessionTracker\Middleware\SessionTracker'); 22 | } 23 | 24 | /** 25 | * Register the application services. 26 | * 27 | * @return void 28 | */ 29 | public function register() 30 | { 31 | $this->mergeConfigFrom( 32 | base_path('vendor/hamedmehryar/laravel-session-tracker/src/config/config.php'), 'sessionTracker' 33 | ); 34 | $this->registerSessionTracker(); 35 | $this->registerAuthenticationEventHandler(); 36 | } 37 | 38 | /** 39 | * Register the the sessionTracker facade. 40 | * 41 | * @return void 42 | */ 43 | private function registerSessionTracker() 44 | { 45 | $this->app->bind('sessionTracker', function ($app) { 46 | return new SessionTracker($app); 47 | }); 48 | } 49 | 50 | private function registerAuthenticationEventHandler(){ 51 | 52 | Event::subscribe('Hamedmehryar\SessionTracker\AuthenticationHandler'); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/Traits/SessionTrackerUserTrait.php: -------------------------------------------------------------------------------- 1 | sessions()->where('end_date', null)->where('block', SessionTrack::STATUS_DEFAULT)->where('login_code', null); 11 | if($exceptSelf){ 12 | if(Session::has('dbsession.id')){ 13 | $query->where('id', '!=', Session::get('dbsession.id')); 14 | } 15 | } 16 | return $query; 17 | } 18 | 19 | public function sessions(){ 20 | return $this->hasMany('Hamedmehryar\SessionTracker\Models\Session'); 21 | } 22 | 23 | public function getFreshestSession(){ 24 | return $this->sessions()->orderBy('last_activity', 'desc')->first(); 25 | } 26 | 27 | public function devices(){ 28 | return $this->hasMany('Hamedmehryar\SessionTracker\Models\Device'); 29 | } 30 | 31 | public function devicesUids(){ 32 | $query = $this->devices()->lists('uid'); 33 | if(! str_contains(Application::VERSION, '5.0')){ 34 | $query = $query->all(); 35 | } 36 | return $query; 37 | } 38 | } -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | [ 13 | | array('method'=>'get', 'route'=>'route.name'), 14 | | array('method'=>'post','route'=>'route/uri/{param}') 15 | | ], 16 | | 17 | */ 18 | 19 | 'ignore_log' => [], 20 | 21 | /* 22 | |-------------------------------------------------------------------------- 23 | | Ignore routes for refreshing the session 24 | |-------------------------------------------------------------------------- 25 | | This option specifies the routes which the session must not be refreshed 26 | | when they are requested,(e.g. poller requests and chat requests) 27 | | 28 | | The format is: 29 | | 'ignore_refresh' => [ 30 | | array('method'=>'get', 'route'=>'route.name'), 31 | | array('method'=>'post','route'=>'route/uri/{param}') 32 | | ], 33 | | 34 | */ 35 | 36 | 'ignore_refresh' => [], 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Session inactivity seconds 41 | |-------------------------------------------------------------------------- 42 | | 43 | | This option allows you to easily specify the period of time in seconds that 44 | | the session is considered inactive or idle. 45 | | 46 | */ 47 | 48 | 'inactivity_seconds' => 1200, 49 | 50 | /* 51 | |-------------------------------------------------------------------------- 52 | | Login route name 53 | |-------------------------------------------------------------------------- 54 | | 55 | | This option allows you to easily specify the route name for login form. 56 | | Session Tracker uses this config item to redirect the request to login page. 57 | | Note: Your login route must have a name. 58 | | 59 | */ 60 | 61 | 'login_route_name' => 'app.login', 62 | 63 | /* 64 | |-------------------------------------------------------------------------- 65 | | Logout route name 66 | |-------------------------------------------------------------------------- 67 | | 68 | | This option allows you to easily specify the route name for logout form. 69 | | Session Tracker uses this config item to redirect the request to login page. 70 | | Note: Your logout route must have a name. 71 | | 72 | */ 73 | 74 | 'logout_route_name' => 'app.logout', 75 | 76 | 77 | /* 78 | |-------------------------------------------------------------------------- 79 | | Login Code route name 80 | |-------------------------------------------------------------------------- 81 | | 82 | | This option allows you to easily specify the route name for login code page. 83 | | Session Tracker uses this config item to redirect the request to login page. 84 | | Note: Your login code route must have a name. 85 | | 86 | */ 87 | 88 | 'security_code_route_name' => 'app.securityCode', 89 | 90 | 91 | /* 92 | |-------------------------------------------------------------------------- 93 | | Security Code lifetime seconds 94 | |-------------------------------------------------------------------------- 95 | | 96 | | This option allows you to easily specify the period of time in seconds that 97 | | the security code of the sessions is considered as expired. 98 | | 99 | */ 100 | 'security_code_lifetime' => 1200, 101 | 102 | ]; 103 | -------------------------------------------------------------------------------- /src/migrations/2016_01_02_091755_create_sessions_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->timestamps(); 19 | $table->timestamp('end_date')->nullable(); 20 | $table->timestamp('last_activity')->nullable(); 21 | $table->string('ip')->nullable(); 22 | $table->string('browser')->nullable(); 23 | $table->string('browser_version')->nullable(); 24 | $table->string('platform')->nullable(); 25 | $table->string('platform_version')->nullable(); 26 | $table->tinyInteger('mobile')->nullable(); 27 | $table->string('device')->nullable(); 28 | $table->string('location')->nullable(); 29 | $table->tinyInteger('robot')->nullable(); 30 | $table->integer('user_id'); 31 | }); 32 | } 33 | 34 | /** 35 | * Reverse the migrations. 36 | * 37 | * @return void 38 | */ 39 | public function down() 40 | { 41 | Schema::drop('sessiontracker_sessions'); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/migrations/2016_01_02_092453_create_session_requests_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->integer('session_id')->nullable(); 19 | $table->timestamps(); 20 | $table->string('route')->nullable(); 21 | $table->text('uri')->nullable(); 22 | $table->string('name')->nullable(); 23 | $table->string('method')->nullable(); 24 | $table->text('parameters')->nullable(); 25 | $table->tinyInteger('type'); 26 | }); 27 | } 28 | 29 | /** 30 | * Reverse the migrations. 31 | * 32 | * @return void 33 | */ 34 | public function down() 35 | { 36 | Schema::drop('sessiontracker_session_request'); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/migrations/2016_01_03_152221_add_block_colomn_to_sessions_table.php: -------------------------------------------------------------------------------- 1 | tinyInteger('block')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('sessions', function(Blueprint $table) 29 | { 30 | $table->dropColumn('block'); 31 | }); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/migrations/2016_01_03_153846_add_blocked_by_colomn_to_sessions_table.php: -------------------------------------------------------------------------------- 1 | integer('blocked_by')->nullable(); 18 | }); 19 | } 20 | 21 | /** 22 | * Reverse the migrations. 23 | * 24 | * @return void 25 | */ 26 | public function down() 27 | { 28 | Schema::table('sessions', function(Blueprint $table) 29 | { 30 | $table->dropColumn('blocked_by'); 31 | }); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/migrations/2016_01_10_092114_create_devices_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->timestamps(); 19 | $table->string('uid'); 20 | $table->integer('user_id'); 21 | $table->string('browser')->nullable(); 22 | $table->string('platform')->nullable(); 23 | $table->string('device')->nullable(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::drop('sessiontracker_devices'); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/migrations/2016_01_10_114304_add_device-uid_and_login_code_columns_to_sessions_table.php: -------------------------------------------------------------------------------- 1 | string('device_uid')->nullable(); 18 | $table->string('login_code')->nullable(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::table('sessions', function(Blueprint $table) 30 | { 31 | $table->dropColumn('device_uid'); 32 | $table->dropColumn('login_code'); 33 | }); 34 | } 35 | 36 | } 37 | --------------------------------------------------------------------------------