2018-04-19 21:19:15 -04:00
/ *
Copyright 2018 Intel Corporation
2018-04-11 16:49:05 -04:00
2018-04-19 21:19:15 -04:00
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
2018-04-11 16:49:05 -04:00
2018-08-31 18:23:42 -04:00
var NOTIFY _FOR _THIS _SESSION = 0 ;
var NOTIFY _FOR _ALL _SESSIONS = 1 ;
var WM _WTSSESSION _CHANGE = 0x02B1 ;
2018-09-18 22:41:59 -04:00
var WM _POWERBROADCAST = 0x218 ;
var PBT _POWERSETTINGCHANGE = 0x8013 ;
var PBT _APMSUSPEND = 0x4 ;
var PBT _APMRESUMESUSPEND = 0x7 ;
var PBT _APMRESUMEAUTOMATIC = 0x12 ;
var PBT _APMPOWERSTATUSCHANGE = 0xA ;
2018-08-31 18:23:42 -04:00
var WTS _CONSOLE _CONNECT = ( 0x1 ) ;
var WTS _CONSOLE _DISCONNECT = ( 0x2 ) ;
var WTS _REMOTE _CONNECT = ( 0x3 ) ;
var WTS _REMOTE _DISCONNECT = ( 0x4 ) ;
var WTS _SESSION _LOGON = ( 0x5 ) ;
var WTS _SESSION _LOGOFF = ( 0x6 ) ;
var WTS _SESSION _LOCK = ( 0x7 ) ;
var WTS _SESSION _UNLOCK = ( 0x8 ) ;
var WTS _SESSION _REMOTE _CONTROL = ( 0x9 ) ;
var WTS _SESSION _CREATE = ( 0xA ) ;
var WTS _SESSION _TERMINATE = ( 0xB ) ;
2018-09-18 22:41:59 -04:00
var GUID _ACDC _POWER _SOURCE ;
var GUID _BATTERY _PERCENTAGE _REMAINING ;
var GUID _CONSOLE _DISPLAY _STATE ;
2018-04-11 16:49:05 -04:00
function UserSessions ( )
{
2018-08-29 21:47:22 -04:00
this . _ObjectID = 'user-sessions' ;
2018-08-31 18:23:42 -04:00
require ( 'events' ) . EventEmitter . call ( this , true )
. createEvent ( 'changed' )
. createEvent ( 'locked' )
. createEvent ( 'unlocked' ) ;
2018-04-11 16:49:05 -04:00
2018-08-29 21:47:22 -04:00
this . enumerateUsers = function enumerateUsers ( )
{
var promise = require ( 'promise' ) ;
var p = new promise ( function ( res , rej )
{
this . _ _resolver = res ;
this . _ _rejector = rej ;
} ) ;
p . _ _handler = function _ _handler ( users )
{
p . _ _resolver ( users ) ;
} ;
2018-09-18 22:41:59 -04:00
try
{
this . Current ( p . _ _handler ) ;
}
catch ( e )
{
p . _ _rejector ( e ) ;
}
p . parent = this ;
2018-08-29 21:47:22 -04:00
return ( p ) ;
}
if ( process . platform == 'win32' )
{
2018-08-31 18:23:42 -04:00
this . _serviceHooked = false ;
2018-04-11 16:49:05 -04:00
this . _marshal = require ( '_GenericMarshal' ) ;
this . _kernel32 = this . _marshal . CreateNativeProxy ( 'Kernel32.dll' ) ;
this . _kernel32 . CreateMethod ( 'GetLastError' ) ;
this . _wts = this . _marshal . CreateNativeProxy ( 'Wtsapi32.dll' ) ;
this . _wts . CreateMethod ( 'WTSEnumerateSessionsA' ) ;
this . _wts . CreateMethod ( 'WTSQuerySessionInformationA' ) ;
2018-08-31 18:23:42 -04:00
this . _wts . CreateMethod ( 'WTSRegisterSessionNotification' ) ;
this . _wts . CreateMethod ( 'WTSUnRegisterSessionNotification' ) ;
2018-04-11 16:49:05 -04:00
this . _wts . CreateMethod ( 'WTSFreeMemory' ) ;
2018-09-18 22:41:59 -04:00
this . _user32 = this . _marshal . CreateNativeProxy ( 'user32.dll' ) ;
this . _user32 . CreateMethod ( 'RegisterPowerSettingNotification' ) ;
this . _user32 . CreateMethod ( 'UnregisterPowerSettingNotification' ) ;
this . _rpcrt = this . _marshal . CreateNativeProxy ( 'Rpcrt4.dll' ) ;
this . _rpcrt . CreateMethod ( 'UuidFromStringA' ) ;
this . _rpcrt . StringToUUID = function StringToUUID ( guid )
{
var retVal = StringToUUID . us . _marshal . CreateVariable ( 16 ) ;
if ( StringToUUID . us . _rpcrt . UuidFromStringA ( StringToUUID . us . _marshal . CreateVariable ( guid ) , retVal ) . Val == 0 )
{
return ( retVal ) ;
}
else
{
throw ( 'Could not convert string to UUID' ) ;
}
}
this . _rpcrt . StringToUUID . us = this ;
GUID _ACDC _POWER _SOURCE = this . _rpcrt . StringToUUID ( '5d3e9a59-e9D5-4b00-a6bd-ff34ff516548' ) ;
GUID _BATTERY _PERCENTAGE _REMAINING = this . _rpcrt . StringToUUID ( 'a7ad8041-b45a-4cae-87a3-eecbb468a9e1' ) ;
GUID _CONSOLE _DISPLAY _STATE = this . _rpcrt . StringToUUID ( '6fe69556-704a-47a0-8f24-c28d936fda47' ) ;
2018-04-11 16:49:05 -04:00
this . SessionStates = [ 'Active' , 'Connected' , 'ConnectQuery' , 'Shadow' , 'Disconnected' , 'Idle' , 'Listening' , 'Reset' , 'Down' , 'Init' ] ;
this . InfoClass =
{
'WTSInitialProgram' : 0 ,
'WTSApplicationName' : 1 ,
'WTSWorkingDirectory' : 2 ,
'WTSOEMId' : 3 ,
'WTSSessionId' : 4 ,
'WTSUserName' : 5 ,
'WTSWinStationName' : 6 ,
'WTSDomainName' : 7 ,
'WTSConnectState' : 8 ,
'WTSClientBuildNumber' : 9 ,
'WTSClientName' : 10 ,
'WTSClientDirectory' : 11 ,
'WTSClientProductId' : 12 ,
'WTSClientHardwareId' : 13 ,
'WTSClientAddress' : 14 ,
'WTSClientDisplay' : 15 ,
'WTSClientProtocolType' : 16 ,
'WTSIdleTime' : 17 ,
'WTSLogonTime' : 18 ,
'WTSIncomingBytes' : 19 ,
'WTSOutgoingBytes' : 20 ,
'WTSIncomingFrames' : 21 ,
'WTSOutgoingFrames' : 22 ,
'WTSClientInfo' : 23 ,
'WTSSessionInfo' : 24 ,
'WTSSessionInfoEx' : 25 ,
'WTSConfigInfo' : 26 ,
'WTSValidationInfo' : 27 ,
'WTSSessionAddressV4' : 28 ,
'WTSIsRemoteSession' : 29
} ;
this . getSessionAttribute = function getSessionAttribute ( sessionId , attr )
{
var buffer = this . _marshal . CreatePointer ( ) ;
var bytesReturned = this . _marshal . CreateVariable ( 4 ) ;
if ( this . _wts . WTSQuerySessionInformationA ( 0 , sessionId , attr , buffer , bytesReturned ) . Val == 0 )
{
throw ( 'Error calling WTSQuerySessionInformation: ' + this . _kernel32 . GetLastError . Val ) ;
}
var retVal = buffer . Deref ( ) . String ;
this . _wts . WTSFreeMemory ( buffer . Deref ( ) ) ;
return ( retVal ) ;
} ;
2018-08-29 21:47:22 -04:00
this . Current = function Current ( cb )
2018-04-11 16:49:05 -04:00
{
var retVal = { } ;
var pinfo = this . _marshal . CreatePointer ( ) ;
var count = this . _marshal . CreateVariable ( 4 ) ;
if ( this . _wts . WTSEnumerateSessionsA ( 0 , 0 , 1 , pinfo , count ) . Val == 0 )
{
throw ( 'Error calling WTSEnumerateSessionsA: ' + this . _kernel32 . GetLastError ( ) . Val ) ;
}
for ( var i = 0 ; i < count . toBuffer ( ) . readUInt32LE ( ) ; ++ i )
{
var info = pinfo . Deref ( ) . Deref ( i * ( this . _marshal . PointerSize == 4 ? 12 : 24 ) , this . _marshal . PointerSize == 4 ? 12 : 24 ) ;
var j = { SessionId : info . toBuffer ( ) . readUInt32LE ( ) } ;
j . StationName = info . Deref ( this . _marshal . PointerSize == 4 ? 4 : 8 , this . _marshal . PointerSize ) . Deref ( ) . String ;
j . State = this . SessionStates [ info . Deref ( this . _marshal . PointerSize == 4 ? 8 : 16 , 4 ) . toBuffer ( ) . readUInt32LE ( ) ] ;
if ( j . State == 'Active' ) {
j . Username = this . getSessionAttribute ( j . SessionId , this . InfoClass . WTSUserName ) ;
j . Domain = this . getSessionAttribute ( j . SessionId , this . InfoClass . WTSDomainName ) ;
}
retVal [ j . SessionId ] = j ;
}
this . _wts . WTSFreeMemory ( pinfo . Deref ( ) ) ;
2018-04-19 21:19:15 -04:00
2018-08-29 21:47:22 -04:00
Object . defineProperty ( retVal , 'Active' , { value : showActiveOnly ( retVal ) } ) ;
if ( cb ) { cb ( retVal ) ; }
2018-04-11 16:49:05 -04:00
return ( retVal ) ;
} ;
2018-08-31 18:23:42 -04:00
2018-09-18 22:41:59 -04:00
// We need to spin up a message pump, and fetch a window handle
var message _pump = require ( 'win-message-pump' ) ;
this . _messagepump = new message _pump ( { filter : WM _WTSSESSION _CHANGE } ) ; this . _messagepump . parent = this ;
this . _messagepump . on ( 'exit' , function ( code ) { this . parent . _wts . WTSUnRegisterSessionNotification ( this . parent . hwnd ) ; } ) ;
this . _messagepump . on ( 'hwnd' , function ( h )
2018-08-31 18:23:42 -04:00
{
2018-09-18 22:41:59 -04:00
this . parent . hwnd = h ;
2018-08-31 18:23:42 -04:00
2018-09-18 22:41:59 -04:00
// Now that we have a window handle, we can register it to receive Windows Messages
this . parent . _wts . WTSRegisterSessionNotification ( this . parent . hwnd , NOTIFY _FOR _ALL _SESSIONS ) ;
2018-09-20 14:45:12 -04:00
//this.parent._user32.ACDC_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
//this.parent._user32.BATT_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
//this.parent._user32.DISP_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0); // Windows 8+ only, THIS WILL BLOCK ON WIN7
2018-09-18 22:41:59 -04:00
} ) ;
this . _messagepump . on ( 'message' , function ( msg )
{
switch ( msg . message )
2018-08-31 18:23:42 -04:00
{
2018-09-18 22:41:59 -04:00
case WM _WTSSESSION _CHANGE :
2018-08-31 18:23:42 -04:00
switch ( msg . wparam )
{
case WTS _SESSION _LOCK :
2018-09-18 22:41:59 -04:00
this . parent . enumerateUsers ( ) . then ( function ( users )
2018-08-31 18:23:42 -04:00
{
2018-09-18 22:41:59 -04:00
if ( users [ msg . lparam ] ) { this . parent . emit ( 'locked' , users [ msg . lparam ] ) ; }
2018-08-31 18:23:42 -04:00
} ) ;
break ;
case WTS _SESSION _UNLOCK :
2018-09-18 22:41:59 -04:00
this . parent . enumerateUsers ( ) . then ( function ( users )
2018-08-31 18:23:42 -04:00
{
2018-09-18 22:41:59 -04:00
if ( users [ msg . lparam ] ) { this . parent . emit ( 'unlocked' , users [ msg . lparam ] ) ; }
2018-08-31 18:23:42 -04:00
} ) ;
break ;
2018-09-18 22:41:59 -04:00
case WTS _SESSION _LOGON :
case WTS _SESSION _LOGOFF :
this . parent . emit ( 'changed' ) ;
break ;
2018-08-31 18:23:42 -04:00
}
2018-09-18 22:41:59 -04:00
break ;
case WM _POWERBROADCAST :
switch ( msg . wparam )
{
default :
console . log ( 'WM_POWERBROADCAST [UNKNOWN wparam]: ' + msg . wparam ) ;
break ;
case PBT _APMSUSPEND :
require ( 'power-monitor' ) . emit ( 'sx' , 'SLEEP' ) ;
break ;
case PBT _APMRESUMEAUTOMATIC :
require ( 'power-monitor' ) . emit ( 'sx' , 'RESUME_NON_INTERACTIVE' ) ;
break ;
case PBT _APMRESUMESUSPEND :
require ( 'power-monitor' ) . emit ( 'sx' , 'RESUME_INTERACTIVE' ) ;
break ;
case PBT _APMPOWERSTATUSCHANGE :
require ( 'power-monitor' ) . emit ( 'changed' ) ;
break ;
case PBT _POWERSETTINGCHANGE :
var lparam = this . parent . _marshal . CreatePointer ( Buffer . from ( msg . lparam _hex , 'hex' ) ) ;
var data = lparam . Deref ( 20 , lparam . Deref ( 16 , 4 ) . toBuffer ( ) . readUInt32LE ( 0 ) ) . toBuffer ( ) ;
switch ( lparam . Deref ( 0 , 16 ) . toBuffer ( ) . toString ( 'hex' ) )
{
case GUID _ACDC _POWER _SOURCE . Deref ( 0 , 16 ) . toBuffer ( ) . toString ( 'hex' ) :
switch ( data . readUInt32LE ( 0 ) )
{
case 0 :
require ( 'power-monitor' ) . emit ( 'acdc' , 'AC' ) ;
break ;
case 1 :
require ( 'power-monitor' ) . emit ( 'acdc' , 'BATTERY' ) ;
break ;
case 2 :
require ( 'power-monitor' ) . emit ( 'acdc' , 'HOT' ) ;
break ;
}
break ;
case GUID _BATTERY _PERCENTAGE _REMAINING . Deref ( 0 , 16 ) . toBuffer ( ) . toString ( 'hex' ) :
require ( 'power-monitor' ) . emit ( 'batteryLevel' , data . readUInt32LE ( 0 ) ) ;
break ;
case GUID _CONSOLE _DISPLAY _STATE . Deref ( 0 , 16 ) . toBuffer ( ) . toString ( 'hex' ) :
switch ( data . readUInt32LE ( 0 ) )
{
case 0 :
require ( 'power-monitor' ) . emit ( 'display' , 'OFF' ) ;
break ;
case 1 :
require ( 'power-monitor' ) . emit ( 'display' , 'ON' ) ;
break ;
case 2 :
require ( 'power-monitor' ) . emit ( 'display' , 'DIMMED' ) ;
break ;
}
break ;
}
break ;
}
break ;
default :
break ;
}
} ) ;
2018-04-11 16:49:05 -04:00
}
2018-09-18 22:41:59 -04:00
else if ( process . platform == 'linux' )
2018-04-11 16:49:05 -04:00
{
2018-09-18 22:41:59 -04:00
var dbus = require ( 'linux-dbus' ) ;
2018-08-31 18:23:42 -04:00
this . _linuxWatcher = require ( 'fs' ) . watch ( '/var/run/utmp' ) ;
this . _linuxWatcher . user _session = this ;
this . _linuxWatcher . on ( 'change' , function ( a , b )
{
this . user _session . emit ( 'changed' ) ;
} ) ;
2018-08-29 21:47:22 -04:00
this . Self = function Self ( )
{
var promise = require ( 'promise' ) ;
var p = new promise ( function ( res , rej )
{
this . _ _resolver = res ; this . _ _rejector = rej ;
this . _ _child = require ( 'child_process' ) . execFile ( '/usr/bin/id' , [ 'id' , '-u' ] ) ;
this . _ _child . promise = this ;
this . _ _child . stdout . _txt = '' ;
this . _ _child . stdout . on ( 'data' , function ( chunk ) { this . _txt += chunk . toString ( ) ; } ) ;
this . _ _child . on ( 'exit' , function ( code )
{
try
{
parseInt ( this . stdout . _txt ) ;
}
catch ( e )
{
this . promise . _ _rejector ( 'invalid uid' ) ;
return ;
}
var id = parseInt ( this . stdout . _txt ) ;
this . promise . _ _resolver ( id ) ;
} ) ;
} ) ;
return ( p ) ;
} ;
this . Current = function Current ( cb )
2018-04-11 16:49:05 -04:00
{
2018-04-19 21:19:15 -04:00
var retVal = { } ;
2018-08-29 21:47:22 -04:00
retVal . _ObjectID = 'UserSession'
Object . defineProperty ( retVal , '_callback' , { value : cb } ) ;
Object . defineProperty ( retVal , '_child' , { value : require ( 'child_process' ) . execFile ( '/usr/bin/last' , [ 'last' , '-f' , '/var/run/utmp' ] ) } ) ;
2018-04-19 21:19:15 -04:00
retVal . _child . Parent = retVal ;
retVal . _child . _txt = '' ;
retVal . _child . on ( 'exit' , function ( code )
{
var lines = this . _txt . split ( '\n' ) ;
var sessions = [ ] ;
2018-08-29 21:47:22 -04:00
var users = { } ;
2018-04-19 21:19:15 -04:00
for ( var i in lines )
{
if ( lines [ i ] )
{
2018-08-29 21:47:22 -04:00
var tokens = getTokens ( lines [ i ] ) ;
var s = { Username : tokens [ 0 ] , SessionId : tokens [ 1 ] }
if ( tokens [ 3 ] . includes ( 'still logged in' ) )
{
s . State = 'Active' ;
}
else
{
s . LastActive = tokens [ 3 ] ;
}
sessions . push ( s ) ;
2018-04-19 21:19:15 -04:00
}
}
sessions . pop ( ) ;
2018-08-29 21:47:22 -04:00
var usernames = { } ;
var promises = [ ] ;
for ( var i in sessions )
{
if ( sessions [ i ] . Username != 'reboot' )
{
users [ sessions [ i ] . SessionId ] = sessions [ i ] ;
if ( usernames [ sessions [ i ] . Username ] == null )
{
usernames [ sessions [ i ] . Username ] = - 1 ;
}
}
}
try
{
require ( 'promise' ) ;
}
catch ( e )
{
Object . defineProperty ( users , 'Active' , { value : showActiveOnly ( users ) } ) ;
if ( this . Parent . _callback ) { this . Parent . _callback . call ( this . Parent , users ) ; }
return ;
}
var promise = require ( 'promise' ) ;
for ( var n in usernames )
{
var p = new promise ( function ( res , rej )
{
this . _ _username = n ;
this . _ _resolver = res ; this . _ _rejector = rej ;
this . _ _child = require ( 'child_process' ) . execFile ( '/usr/bin/id' , [ 'id' , '-u' , n ] ) ;
this . _ _child . promise = this ;
this . _ _child . stdout . _txt = '' ;
this . _ _child . stdout . on ( 'data' , function ( chunk ) { this . _txt += chunk . toString ( ) ; } ) ;
this . _ _child . on ( 'exit' , function ( code )
{
try
{
parseInt ( this . stdout . _txt ) ;
}
catch ( e )
{
this . promise . _ _rejector ( 'invalid uid' ) ;
return ;
}
var id = parseInt ( this . stdout . _txt ) ;
this . promise . _ _resolver ( id ) ;
} ) ;
} ) ;
promises . push ( p ) ;
}
promise . all ( promises ) . then ( function ( plist )
{
// Done
var table = { } ;
for ( var i in plist )
{
table [ plist [ i ] . _ _username ] = plist [ i ] . _internal . completedArgs [ 0 ] ;
}
for ( var i in users )
{
users [ i ] . uid = table [ users [ i ] . Username ] ;
}
Object . defineProperty ( users , 'Active' , { value : showActiveOnly ( users ) } ) ;
if ( retVal . _callback ) { retVal . _callback . call ( retVal , users ) ; }
} , function ( reason )
{
// Failed
Object . defineProperty ( users , 'Active' , { value : showActiveOnly ( users ) } ) ;
if ( retVal . _callback ) { retVal . _callback . call ( retVal , users ) ; }
} ) ;
2018-04-19 21:19:15 -04:00
} ) ;
retVal . _child . stdout . Parent = retVal . _child ;
retVal . _child . stdout . on ( 'data' , function ( chunk ) { this . Parent . _txt += chunk . toString ( ) ; } ) ;
return ( retVal ) ;
}
2018-09-18 22:41:59 -04:00
this . _recheckLoggedInUsers = function _recheckLoggedInUsers ( )
{
this . enumerateUsers ( ) . then ( function ( u )
{
if ( u . Active . length > 0 )
{
// There is already a user logged in, so we can monitor DBUS for lock/unlock
if ( this . parent . _linux _lock _watcher != null && this . parent . _linux _lock _watcher . uid != u . Active [ 0 ] . uid )
{
delete this . parent . _linux _lock _watcher ;
}
this . parent . _linux _lock _watcher = new dbus ( process . env [ 'XDG_CURRENT_DESKTOP' ] == 'Unity' ? 'com.ubuntu.Upstart0_6' : 'org.gnome.ScreenSaver' , u . Active [ 0 ] . uid ) ;
this . parent . _linux _lock _watcher . user _session = this . parent ;
this . parent . _linux _lock _watcher . on ( 'signal' , function ( s )
{
var p = this . user _session . enumerateUsers ( ) ;
p . signalData = s . data [ 0 ] ;
p . then ( function ( u )
{
switch ( this . signalData )
{
case true :
case 'desktop-lock' :
this . parent . emit ( 'locked' , u . Active [ 0 ] ) ;
break ;
case false :
case 'desktop-unlock' :
this . parent . emit ( 'unlocked' , u . Active [ 0 ] ) ;
break ;
}
} ) ;
} ) ;
}
else if ( this . parent . _linux _lock _watcher != null )
{
delete this . parent . _linux _lock _watcher ;
}
} ) ;
} ;
this . on ( 'changed' , this . _recheckLoggedInUsers ) ; // For linux Lock/Unlock monitoring, we need to watch for LogOn/LogOff, and keep track of the UID.
// First step, is to see if there is a user logged in:
this . _recheckLoggedInUsers ( ) ;
}
else if ( process . platform == 'darwin' )
{
this . _idTable = function ( )
{
var table = { } ;
var child = require ( 'child_process' ) . execFile ( '/usr/bin/id' , [ 'id' ] ) ;
child . stdout . str = '' ;
child . stdout . on ( 'data' , function ( chunk ) { this . str += chunk . toString ( ) ; } ) ;
child . waitExit ( ) ;
var lines = child . stdout . str . split ( '\n' ) [ 0 ] . split ( ' ' ) ;
for ( var i = 0 ; i < lines . length ; ++ i ) {
var types = lines [ i ] . split ( '=' ) ;
var tokens = types [ 1 ] . split ( ',' ) ;
table [ types [ 0 ] ] = { } ;
for ( var j in tokens ) {
var idarr = tokens [ j ] . split ( '(' ) ;
var id = idarr [ 0 ] ;
var name = idarr [ 1 ] . substring ( 0 , idarr [ 1 ] . length - 1 ) . trim ( ) ;
table [ types [ 0 ] ] [ name ] = id ;
table [ types [ 0 ] ] [ id ] = name ;
}
}
return ( table ) ;
}
this . Current = function ( cb )
{
var users = { } ;
var table = this . _idTable ( ) ;
var child = require ( 'child_process' ) . execFile ( '/usr/bin/last' , [ 'last' ] ) ;
child . stdout . str = '' ;
child . stdout . on ( 'data' , function ( chunk ) { this . str += chunk . toString ( ) ; } ) ;
child . waitExit ( ) ;
var lines = child . stdout . str . split ( '\n' ) ;
for ( var i = 0 ; i < lines . length && lines [ i ] . length > 0 ; ++ i )
{
if ( ! users [ lines [ i ] . split ( ' ' ) [ 0 ] ] )
{
try
{
users [ lines [ i ] . split ( ' ' ) [ 0 ] ] = { Username : lines [ i ] . split ( ' ' ) [ 0 ] , State : lines [ i ] . split ( 'still logged in' ) . length > 1 ? 'Active' : 'Inactive' , uid : table . uid [ lines [ i ] . split ( ' ' ) [ 0 ] ] } ;
}
catch ( e )
{ }
}
else
{
if ( users [ lines [ i ] . split ( ' ' ) [ 0 ] ] . State != 'Active' && lines [ i ] . split ( 'still logged in' ) . length > 1 )
{
users [ lines [ i ] . split ( ' ' ) [ 0 ] ] . State = 'Active' ;
}
}
}
Object . defineProperty ( users , 'Active' , { value : showActiveOnly ( users ) } ) ;
if ( cb ) { cb . call ( this , users ) ; }
}
2018-04-19 21:19:15 -04:00
}
}
function showActiveOnly ( source )
{
var retVal = [ ] ;
2018-08-31 18:23:42 -04:00
var unique = { } ;
var usernames = [ ] ;
var tmp ;
2018-04-19 21:19:15 -04:00
for ( var i in source )
{
2018-08-29 21:47:22 -04:00
if ( source [ i ] . State == 'Active' )
2018-04-19 21:19:15 -04:00
{
retVal . push ( source [ i ] ) ;
2018-08-31 18:23:42 -04:00
tmp = ( source [ i ] . Domain ? ( source [ i ] . Domain + '\\' ) : '' ) + source [ i ] . Username ;
if ( ! unique [ tmp ] ) { unique [ tmp ] = tmp ; }
2018-04-11 16:49:05 -04:00
}
}
2018-08-31 18:23:42 -04:00
for ( var i in unique )
{
usernames . push ( i ) ;
}
Object . defineProperty ( retVal , 'usernames' , { value : usernames } ) ;
2018-04-19 21:19:15 -04:00
return ( retVal ) ;
}
function getTokens ( str )
{
var columns = [ ] ;
var i ;
columns . push ( str . substring ( 0 , ( i = str . indexOf ( ' ' ) ) ) ) ;
while ( str [ ++ i ] == ' ' ) ;
2018-08-29 21:47:22 -04:00
columns . push ( str . substring ( i , ( i = str . substring ( i ) . indexOf ( ' ' ) + i ) ) ) ;
while ( str [ ++ i ] == ' ' ) ;
columns . push ( str . substring ( i , ( i = str . substring ( i ) . indexOf ( ' ' ) + i ) ) ) ;
while ( str [ ++ i ] == ' ' ) ;
var status = str . substring ( i ) . trim ( ) ;
columns . push ( status ) ;
2018-04-19 21:19:15 -04:00
return ( columns ) ;
2018-04-11 16:49:05 -04:00
}
module . exports = new UserSessions ( ) ;