2019-06-28 21:31:18 -04:00
#!/usr/bin/env node
2022-01-24 02:21:24 -05:00
/ * *
* @ description MeshCentral command line tool
* @ author Ylian Saint - Hilaire
* @ copyright Intel Corporation 2018 - 2022
* @ license Apache - 2.0
* @ version v0 . 0.1
* /
2020-04-16 01:27:03 -04:00
// Make sure we have the dependency modules
try { require ( 'minimist' ) ; } catch ( ex ) { console . log ( 'Missing module "minimist", type "npm install minimist" to install it.' ) ; return ; }
try { require ( 'ws' ) ; } catch ( ex ) { console . log ( 'Missing module "ws", type "npm install ws" to install it.' ) ; return ; }
2019-06-28 21:31:18 -04:00
var settings = { } ;
2020-04-16 01:27:03 -04:00
const crypto = require ( 'crypto' ) ;
2019-06-28 21:31:18 -04:00
const args = require ( 'minimist' ) ( process . argv . slice ( 2 ) ) ;
2021-09-03 01:11:59 -04:00
const path = require ( 'path' ) ;
2024-11-26 11:46:14 -05:00
const possibleCommands = [ 'edituser' , 'listusers' , 'listusersessions' , 'listdevicegroups' , 'listdevices' , 'listusersofdevicegroup' , 'listevents' , 'logintokens' , 'serverinfo' , 'userinfo' , 'adduser' , 'removeuser' , 'adddevicegroup' , 'removedevicegroup' , 'editdevicegroup' , 'broadcast' , 'showevents' , 'addusertodevicegroup' , 'removeuserfromdevicegroup' , 'addusertodevice' , 'removeuserfromdevice' , 'sendinviteemail' , 'generateinvitelink' , 'config' , 'movetodevicegroup' , 'deviceinfo' , 'removedevice' , 'editdevice' , 'addlocaldevice' , 'addamtdevice' , 'addusergroup' , 'listusergroups' , 'removeusergroup' , 'runcommand' , 'shell' , 'upload' , 'download' , 'deviceopenurl' , 'devicemessage' , 'devicetoast' , 'addtousergroup' , 'removefromusergroup' , 'removeallusersfromusergroup' , 'devicesharing' , 'devicepower' , 'indexagenterrorlog' , 'agentdownload' , 'report' , 'grouptoast' , 'groupmessage' , 'webrelay' ] ;
2020-04-16 01:27:03 -04:00
if ( args . proxy != null ) { try { require ( 'https-proxy-agent' ) ; } catch ( ex ) { console . log ( 'Missing module "https-proxy-agent", type "npm install https-proxy-agent" to install it.' ) ; return ; } }
2019-06-28 21:31:18 -04:00
2019-06-30 14:34:27 -04:00
if ( args [ '_' ] . length == 0 ) {
console . log ( "MeshCtrl performs command line actions on a MeshCentral server." ) ;
2021-09-11 00:10:01 -04:00
console . log ( "Information at: https://meshcentral.com" ) ;
2019-06-28 21:31:18 -04:00
console . log ( "No action specified, use MeshCtrl like this:\r\n\r\n meshctrl [action] [arguments]\r\n" ) ;
console . log ( "Supported actions:" ) ;
2020-10-02 19:17:28 -04:00
console . log ( " Help [action] - Get help on an action." ) ;
console . log ( " ServerInfo - Show server information." ) ;
console . log ( " UserInfo - Show user information." ) ;
console . log ( " ListUsers - List user accounts." ) ;
console . log ( " ListUserSessions - List online users." ) ;
console . log ( " ListUserGroups - List user groups." ) ;
console . log ( " ListDevices - List devices." ) ;
console . log ( " ListDeviceGroups - List device groups." ) ;
console . log ( " ListUsersOfDeviceGroup - List the users in a device group." ) ;
2021-02-02 21:01:09 -05:00
console . log ( " ListEvents - List server events." ) ;
2021-05-07 15:15:44 -04:00
console . log ( " LoginTokens - List, create and remove login tokens." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " DeviceInfo - Show information about a device." ) ;
2024-10-25 05:34:16 -04:00
console . log ( " AddLocalDevice - Add a local device." ) ;
console . log ( " AddAmtDevice - Add a AMT device." ) ;
2021-06-11 15:48:43 -04:00
console . log ( " EditDevice - Make changes to a device." ) ;
2022-11-14 19:31:44 -05:00
console . log ( " RemoveDevice - Delete a device." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " Config - Perform operation on config.json file." ) ;
console . log ( " AddUser - Create a new user account." ) ;
2020-12-09 19:34:40 -05:00
console . log ( " EditUser - Change a user account." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " RemoveUser - Delete a user account." ) ;
console . log ( " AddUserGroup - Create a new user group." ) ;
console . log ( " RemoveUserGroup - Delete a user group." ) ;
2020-10-05 06:53:30 -04:00
console . log ( " AddToUserGroup - Add a user, device or device group to a user group." ) ;
console . log ( " RemoveFromUserGroup - Remove a user, device or device group from a user group." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " RemoveAllUsersFromUserGroup - Remove all users from a user group." ) ;
console . log ( " AddDeviceGroup - Create a new device group." ) ;
console . log ( " RemoveDeviceGroup - Delete a device group." ) ;
console . log ( " EditDeviceGroup - Change a device group values." ) ;
console . log ( " MoveToDeviceGroup - Move a device to a different device group." ) ;
console . log ( " AddUserToDeviceGroup - Add a user to a device group." ) ;
console . log ( " RemoveUserFromDeviceGroup - Remove a user from a device group." ) ;
console . log ( " AddUserToDevice - Add a user to a device." ) ;
console . log ( " RemoveUserFromDevice - Remove a user from a device." ) ;
console . log ( " SendInviteEmail - Send an agent install invitation email." ) ;
console . log ( " GenerateInviteLink - Create an invitation link." ) ;
console . log ( " Broadcast - Display a message to all online users." ) ;
console . log ( " ShowEvents - Display real-time server events in JSON format." ) ;
console . log ( " RunCommand - Run a shell command on a remote device." ) ;
console . log ( " Shell - Access command shell of a remote device." ) ;
console . log ( " Upload - Upload a file to a remote device." ) ;
console . log ( " Download - Download a file from a remote device." ) ;
2024-11-26 11:46:14 -05:00
console . log ( " WebRelay - Creates a HTTP/HTTPS webrelay link for a remote device." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " DeviceOpenUrl - Open a URL on a remote device." ) ;
console . log ( " DeviceMessage - Open a message box on a remote device." ) ;
console . log ( " DeviceToast - Display a toast notification on a remote device." ) ;
2024-01-25 04:44:27 -05:00
console . log ( " GroupMessage - Open a message box on remote devices in a specific device group." ) ;
console . log ( " GroupToast - Display a toast notification on remote devices in a specific device group." ) ;
2021-01-05 21:29:23 -05:00
console . log ( " DevicePower - Perform wake/sleep/reset/off operations on remote devices." ) ;
2021-01-05 20:02:24 -05:00
console . log ( " DeviceSharing - View, add and remove sharing links for a given device." ) ;
2021-08-05 04:13:44 -04:00
console . log ( " AgentDownload - Download an agent of a specific type for a device group." ) ;
2023-03-30 08:07:30 -04:00
console . log ( " Report - Create and show a CSV report." ) ;
2019-06-29 15:18:20 -04:00
console . log ( "\r\nSupported login arguments:" ) ;
2020-10-02 19:17:28 -04:00
console . log ( " --url [wss://server] - Server url, wss://localhost:443 is default." ) ;
console . log ( " - Use wss://localhost:443?key=xxx if login key is required." ) ;
console . log ( " --loginuser [username] - Login username, admin is default." ) ;
2023-11-12 16:49:20 -05:00
console . log ( " --loginpass [password] - Login password OR Leave blank to enter password at prompt" ) ;
2020-10-02 19:17:28 -04:00
console . log ( " --token [number] - 2nd factor authentication token." ) ;
console . log ( " --loginkey [hex] - Server login key in hex." ) ;
console . log ( " --loginkeyfile [file] - File containing server login key in hex." ) ;
console . log ( " --logindomain [domainid] - Domain id, default is empty, only used with loginkey." ) ;
2020-12-09 19:34:40 -05:00
console . log ( " --proxy [http://proxy:123] - Specify an HTTP proxy." ) ;
2019-06-28 21:31:18 -04:00
return ;
} else {
settings . cmd = args [ '_' ] [ 0 ] . toLowerCase ( ) ;
2019-06-29 15:18:20 -04:00
if ( ( possibleCommands . indexOf ( settings . cmd ) == - 1 ) && ( settings . cmd != 'help' ) ) { console . log ( "Invalid command. Possible commands are: " + possibleCommands . join ( ', ' ) + '.' ) ; return ; }
2019-06-28 21:31:18 -04:00
//console.log(settings.cmd);
var ok = false ;
switch ( settings . cmd ) {
2019-11-22 19:17:29 -05:00
case 'config' : { performConfigOperations ( args ) ; return ; }
2021-04-17 19:04:48 -04:00
case 'indexagenterrorlog' : { indexAgentErrorLog ( ) ; return ; }
2019-06-28 21:31:18 -04:00
case 'serverinfo' : { ok = true ; break ; }
case 'userinfo' : { ok = true ; break ; }
case 'listusers' : { ok = true ; break ; }
2020-05-14 16:20:45 -04:00
case 'listusersessions' : { ok = true ; break ; }
2020-05-27 20:23:38 -04:00
case 'listusergroups' : { ok = true ; break ; }
2019-06-30 15:30:03 -04:00
case 'listdevicegroups' : { ok = true ; break ; }
2019-07-05 16:28:41 -04:00
case 'listdevices' : { ok = true ; break ; }
2021-02-02 21:01:09 -05:00
case 'listevents' : { ok = true ; break ; }
2021-05-07 15:15:44 -04:00
case 'logintokens' : { ok = true ; break ; }
2022-11-14 19:31:44 -05:00
case 'listusersofdevicegroup' :
case 'deviceinfo' :
case 'removedevice' :
2021-06-11 15:48:43 -04:00
case 'editdevice' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else { ok = true ; }
break ;
}
2024-10-25 05:34:16 -04:00
case 'addlocaldevice' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else if ( args . devicename == null ) { console . log ( winRemoveSingleQuotes ( "Missing devicename, use --devicename [devicename]" ) ) ; }
else if ( args . hostname == null ) { console . log ( winRemoveSingleQuotes ( "Missing hostname, use --hostname [hostname]" ) ) ; }
else { ok = true ; }
break ;
}
case 'addamtdevice' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else if ( args . devicename == null ) { console . log ( winRemoveSingleQuotes ( "Missing devicename, use --devicename [devicename]" ) ) ; }
else if ( args . hostname == null ) { console . log ( winRemoveSingleQuotes ( "Missing hostname, use --hostname [hostname]" ) ) ; }
else if ( args . user == null ) { console . log ( winRemoveSingleQuotes ( "Missing user, use --user [user]" ) ) ; }
else if ( args . pass == null ) { console . log ( winRemoveSingleQuotes ( "Missing pass, use --pass [pass]" ) ) ; }
else { ok = true ; }
break ;
}
2019-07-01 17:44:26 -04:00
case 'addusertodevicegroup' : {
2020-07-17 17:29:02 -04:00
if ( ( args . id == null ) && ( args . group == null ) ) { console . log ( winRemoveSingleQuotes ( "Device group identifier missing, use --id '[groupid]' or --group [groupname]" ) ) ; }
2020-04-08 14:26:35 -04:00
else if ( args . userid == null ) { console . log ( "Add user to group missing useid, use --userid [userid]" ) ; }
2019-07-01 17:44:26 -04:00
else { ok = true ; }
break ;
}
case 'removeuserfromdevicegroup' : {
2020-07-17 17:29:02 -04:00
if ( ( args . id == null ) && ( args . group == null ) ) { console . log ( winRemoveSingleQuotes ( "Device group identifier missing, use --id '[groupid]' or --group [groupname]" ) ) ; }
2020-04-08 14:26:35 -04:00
else if ( args . userid == null ) { console . log ( "Remove user from group missing useid, use --userid [userid]" ) ; }
2019-07-01 17:44:26 -04:00
else { ok = true ; }
break ;
}
2020-04-01 16:15:14 -04:00
case 'addusertodevice' : {
2020-07-17 16:52:45 -04:00
if ( args . userid == null ) { console . log ( "Add user to device missing userid, use --userid [userid]" ) ; }
2020-07-17 17:29:02 -04:00
else if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Add user to device missing device id, use --id '[deviceid]'" ) ) ; }
2020-04-01 16:15:14 -04:00
else { ok = true ; }
break ;
}
case 'removeuserfromdevice' : {
2020-07-17 16:52:45 -04:00
if ( args . userid == null ) { console . log ( "Remove user from device missing userid, use --userid [userid]" ) ; }
2020-07-17 17:29:02 -04:00
else if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Remove user from device missing device id, use --id '[deviceid]'" ) ) ; }
2020-04-01 16:15:14 -04:00
else { ok = true ; }
break ;
}
2019-06-30 14:34:27 -04:00
case 'adddevicegroup' : {
if ( args . name == null ) { console . log ( "Message group name, use --name [name]" ) ; }
else { ok = true ; }
break ;
}
2020-07-24 15:32:43 -04:00
case 'editdevicegroup' :
2019-06-30 14:34:27 -04:00
case 'removedevicegroup' : {
2020-07-17 17:29:02 -04:00
if ( ( args . id == null ) && ( args . group == null ) ) { console . log ( winRemoveSingleQuotes ( "Device group identifier missing, use --id '[groupid]' or --group [groupname]" ) ) ; }
2019-06-30 14:34:27 -04:00
else { ok = true ; }
break ;
}
2020-04-16 11:46:53 -04:00
case 'movetodevicegroup' : {
2020-07-17 17:29:02 -04:00
if ( ( args . id == null ) && ( args . group == null ) ) { console . log ( winRemoveSingleQuotes ( "Device group identifier missing, use --id '[groupid]' or --group [groupname]" ) ) ; }
else if ( args . devid == null ) { console . log ( winRemoveSingleQuotes ( "Device identifier missing, use --devid '[deviceid]'" ) ) ; }
2020-04-16 11:46:53 -04:00
else { ok = true ; }
break ;
}
2019-06-30 14:34:27 -04:00
case 'broadcast' : {
if ( args . msg == null ) { console . log ( "Message missing, use --msg [message]" ) ; }
else { ok = true ; }
break ;
}
2020-03-20 18:47:22 -04:00
case 'showevents' : {
ok = true ;
break ;
}
2019-06-29 15:18:20 -04:00
case 'adduser' : {
if ( args . user == null ) { console . log ( "New account name missing, use --user [name]" ) ; }
2019-06-30 14:34:27 -04:00
else if ( ( args . pass == null ) && ( args . randompass == null ) ) { console . log ( "New account password missing, use --pass [password] or --randompass" ) ; }
2019-06-29 15:18:20 -04:00
else { ok = true ; }
break ;
}
2020-12-09 19:34:40 -05:00
case 'edituser' : {
if ( args . userid == null ) { console . log ( "Edit account user missing, use --userid [id]" ) ; }
else { ok = true ; }
break ;
}
2019-06-29 15:18:20 -04:00
case 'removeuser' : {
if ( args . userid == null ) { console . log ( "Remove account userid missing, use --userid [id]" ) ; }
else { ok = true ; }
break ;
}
2020-05-27 20:23:38 -04:00
case 'addusergroup' : {
if ( args . name == null ) { console . log ( "New user group name missing, use --name [name]" ) ; }
else { ok = true ; }
break ;
}
case 'removeusergroup' : {
2020-07-17 17:29:02 -04:00
if ( args . groupid == null ) { console . log ( winRemoveSingleQuotes ( "Remove user group id missing, use --groupid '[id]'" ) ) ; }
2020-05-27 20:23:38 -04:00
else { ok = true ; }
break ;
}
2020-10-05 06:53:30 -04:00
case 'addtousergroup' : {
2020-10-02 19:17:28 -04:00
if ( args . groupid == null ) { console . log ( winRemoveSingleQuotes ( "Group id missing, use --groupid '[id]'" ) ) ; }
2020-10-05 06:53:30 -04:00
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing identifier to add, use --id [id]" ) ) ; }
2020-10-02 19:17:28 -04:00
else { ok = true ; }
break ;
}
2020-10-05 06:53:30 -04:00
case 'removefromusergroup' : {
2020-10-02 19:17:28 -04:00
if ( args . groupid == null ) { console . log ( winRemoveSingleQuotes ( "Group id missing, use --groupid '[id]'" ) ) ; }
2020-10-05 06:53:30 -04:00
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing identifier to remove, use --id [id]" ) ) ; }
2020-10-02 19:17:28 -04:00
else { ok = true ; }
break ;
}
case 'removeallusersfromusergroup' : {
if ( args . groupid == null ) { console . log ( winRemoveSingleQuotes ( "Group id missing, use --groupid '[id]'" ) ) ; }
else { ok = true ; }
break ;
}
2019-07-05 16:28:41 -04:00
case 'sendinviteemail' : {
2020-07-17 16:52:45 -04:00
if ( ( args . id == null ) && ( args . group == null ) ) { console . log ( "Device group identifier missing, use --id '[groupid]' or --group [groupname]" ) ; }
2019-07-05 16:28:41 -04:00
else if ( args . email == null ) { console . log ( "Device email is missing, use --email [email]" ) ; }
2022-11-14 19:31:44 -05:00
else { ok = true ; }
2019-07-05 16:28:41 -04:00
break ;
}
2019-09-23 14:45:10 -04:00
case 'generateinvitelink' : {
2020-07-17 16:52:45 -04:00
if ( ( args . id == null ) && ( args . group == null ) ) { console . log ( "Device group identifier missing, use --id '[groupid]' or --group [groupname]" ) ; }
2019-09-23 14:45:10 -04:00
else if ( args . hours == null ) { console . log ( "Invitation validity period missing, use --hours [hours]" ) ; }
else { ok = true ; }
break ;
}
2020-07-13 15:25:14 -04:00
case 'runcommand' : {
2020-07-17 17:29:02 -04:00
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
2020-07-13 15:25:14 -04:00
else if ( args . run == null ) { console . log ( "Missing run, use --run \"command\"" ) ; }
else { ok = true ; }
break ;
}
2020-07-13 18:06:45 -04:00
case 'shell' : {
2020-07-17 17:29:02 -04:00
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
2020-07-13 18:06:45 -04:00
else { ok = true ; }
break ;
}
2021-01-05 21:29:23 -05:00
case 'devicepower' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else { ok = true ; }
break ;
}
2021-01-05 20:02:24 -05:00
case 'devicesharing' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
2022-01-17 14:38:49 -05:00
else if ( ( args . daily != null ) && ( args . weekly != null ) ) { console . log ( winRemoveSingleQuotes ( "Can't specify both --daily and --weekly at the same time." ) ) ; }
2021-01-05 20:02:24 -05:00
else { ok = true ; }
break ;
}
2021-08-05 04:13:44 -04:00
case 'agentdownload' : {
if ( args . type == null ) { console . log ( winRemoveSingleQuotes ( "Missing device type, use --type [agenttype]" ) ) ; }
2024-05-28 13:24:39 -04:00
else if ( ( parseInt ( args . type ) == null ) || isNaN ( parseInt ( args . type ) ) || ( parseInt ( args . type ) < 1 ) || ( parseInt ( args . type ) > 11000 ) ) { console . log ( winRemoveSingleQuotes ( "Invalid agent type, must be a number." ) ) ; }
else if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[meshid]'" ) ) ; }
else if ( ( typeof args . id != 'string' ) || ( args . id . length != 64 ) ) { console . log ( winRemoveSingleQuotes ( "Invalid meshid." ) ) ; }
2021-08-05 04:13:44 -04:00
else { ok = true ; }
break ;
}
2020-07-16 17:08:06 -04:00
case 'upload' : {
2020-07-17 17:29:02 -04:00
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
2020-07-16 17:08:06 -04:00
else if ( args . file == null ) { console . log ( "Local file missing, use --file [file] specify the file to upload" ) ; }
else if ( args . target == null ) { console . log ( "Remote target path missing, use --target [path] to specify the remote location" ) ; }
else if ( require ( 'fs' ) . existsSync ( args . file ) == false ) { console . log ( "Local file does not exists, check --file" ) ; }
else { ok = true ; }
break ;
}
case 'download' : {
2020-07-17 17:29:02 -04:00
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
2020-07-16 17:08:06 -04:00
else if ( args . file == null ) { console . log ( "Remote file missing, use --file [file] specify the remote file to download" ) ; }
else if ( args . target == null ) { console . log ( "Target path missing, use --target [path] to specify the local download location" ) ; }
else { ok = true ; }
break ;
}
2024-11-26 11:46:14 -05:00
case 'webrelay' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else if ( args . type == null ) { console . log ( winRemoveSingleQuotes ( "Missing protocol type, use --type [http,https]" ) ) ; }
else { ok = true ; }
break ;
}
2020-08-17 18:01:25 -04:00
case 'deviceopenurl' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else if ( args . openurl == null ) { console . log ( "Remote URL, use --openurl [url] specify the link to open." ) ; }
else { ok = true ; }
break ;
}
case 'devicemessage' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else if ( args . msg == null ) { console . log ( "Remote message, use --msg \"[message]\" specify a remote message." ) ; }
else { ok = true ; }
break ;
}
case 'devicetoast' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device id, use --id '[deviceid]'" ) ) ; }
else if ( args . msg == null ) { console . log ( "Remote message, use --msg \"[message]\" specify a remote message." ) ; }
else { ok = true ; }
break ;
}
2024-01-25 04:44:27 -05:00
case 'groupmessage' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device group id, use --id '[devicegroupid]'" ) ) ; }
else if ( args . msg == null ) { console . log ( "Remote message, use --msg \"[message]\" specify a remote message." ) ; }
else { ok = true ; }
break ;
}
case 'grouptoast' : {
if ( args . id == null ) { console . log ( winRemoveSingleQuotes ( "Missing device group id, use --id '[devicegroupid]'" ) ) ; }
else if ( args . msg == null ) { console . log ( "Remote message, use --msg \"[message]\" specify a remote message." ) ; }
else { ok = true ; }
break ;
}
2023-03-30 08:07:30 -04:00
case 'report' : {
if ( args . type == null ) { console . log ( winRemoveSingleQuotes ( "Missing report type, use --type '[reporttype]'" ) ) ; }
else { ok = true ; }
break ;
}
2019-06-29 15:18:20 -04:00
case 'help' : {
if ( args [ '_' ] . length < 2 ) {
console . log ( "Get help on an action. Type:\r\n\r\n help [action]\r\n\r\nPossible actions are: " + possibleCommands . join ( ', ' ) + '.' ) ;
} else {
switch ( args [ '_' ] [ 1 ] . toLowerCase ( ) ) {
2019-11-22 19:17:29 -05:00
case 'config' : {
2019-12-20 20:29:38 -05:00
displayConfigHelp ( ) ;
2019-11-22 19:17:29 -05:00
break ;
}
2019-07-05 16:28:41 -04:00
case 'sendinviteemail' : {
console . log ( "Send invitation email with instructions on how to install the mesh agent for a specific device group. Example usage:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl SendInviteEmail --id 'groupid' --message \"msg\" --email user@sample.com" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl SendInviteEmail --group \"My Computers\" --name \"Jack\" --email user@sample.com" ) ) ;
2019-07-05 16:28:41 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier (or --group)." ) ;
}
2020-04-07 19:13:02 -04:00
console . log ( " --group [groupname] - Device group name (or --id)." ) ;
2019-07-05 16:28:41 -04:00
console . log ( " --email [email] - Email address." ) ;
2020-04-07 19:13:02 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --name (name) - Name of recipient to be included in the email." ) ;
2022-11-14 19:31:44 -05:00
console . log ( " --message (msg) - Message to be included in the email." ) ;
2019-07-05 16:28:41 -04:00
break ;
}
2019-09-23 14:45:10 -04:00
case 'generateinvitelink' : {
console . log ( "Generate a agent invitation URL for a given group. Example usage:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl GenerateInviteLink --id 'groupid' --hours 24" ) ) ;
2020-04-07 19:13:02 -04:00
console . log ( " MeshCtrl GenerateInviteLink --group \"My Computers\" --hours 0" ) ;
2019-09-23 14:45:10 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier (or --group)." ) ;
}
2020-04-07 19:13:02 -04:00
console . log ( " --group [groupname] - Device group name (or --id)." ) ;
2022-07-19 17:52:30 -04:00
console . log ( " --hours [hours] - Validity period in hours or 0 for infinite." ) ;
2021-05-10 12:37:41 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --flags [mode] - Mode flag for link type (0 = both, 1 = interactive only, 2 = background only)" ) ;
2019-09-23 14:45:10 -04:00
break ;
}
2020-11-05 05:27:39 -05:00
case 'showevents' : {
console . log ( "Show the server's event stream for this user account. Example usage:\r\n" ) ;
console . log ( " MeshCtrl ShowEvents" ) ;
console . log ( " MeshCtrl ShowEvents --filter nodeconnect" ) ;
console . log ( " MeshCtrl ShowEvents --filter uicustomevent,changenode" ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --filter [actions] - Show only specified actions." ) ;
break ;
}
2019-06-29 15:18:20 -04:00
case 'serverinfo' : {
console . log ( "Get information on the MeshCentral server, Example usages:\r\n" ) ;
console . log ( " MeshCtrl ServerInfo --loginuser myaccountname --loginpass mypassword" ) ;
console . log ( " MeshCtrl ServerInfo --loginuser myaccountname --loginkeyfile key.txt" ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --json - Show result as JSON." ) ;
2019-06-29 15:18:20 -04:00
break ;
}
case 'userinfo' : {
console . log ( "Get account information for the login account, Example usages:\r\n" ) ;
console . log ( " MeshCtrl UserInfo --loginuser myaccountname --loginpass mypassword" ) ;
console . log ( " MeshCtrl UserInfo --loginuser myaccountname --loginkeyfile key.txt" ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --json - Show result as JSON." ) ;
2019-06-29 15:18:20 -04:00
break ;
}
case 'listusers' : {
console . log ( "List the account on the MeshCentral server, Example usages:\r\n" ) ;
console . log ( " MeshCtrl ListUsers" ) ;
console . log ( " MeshCtrl ListUsers --json" ) ;
console . log ( " MeshCtrl ListUsers --nameexists \"bob\"" ) ;
2019-12-12 14:44:03 -05:00
console . log ( " MeshCtrl ListUsers --filter 2fa" ) ;
2019-06-29 15:18:20 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --idexists [id] - Return 1 if id exists, 0 if not." ) ;
console . log ( " --nameexists [name] - Return id if name exists." ) ;
2019-12-12 14:44:03 -05:00
console . log ( " --filter [filter1,...] - Filter user names: 2FA, NO2FA." ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --json - Show result as JSON." ) ;
2019-06-29 15:18:20 -04:00
break ;
}
2020-05-14 16:20:45 -04:00
case 'listusersessions' : {
console . log ( "List active user sessions on the MeshCentral server, Example usages:\r\n" ) ;
console . log ( " MeshCtrl ListUserSessions" ) ;
console . log ( " MeshCtrl ListUserSessions --json" ) ;
break ;
}
2020-05-27 20:23:38 -04:00
case 'listusergroups' : {
console . log ( "List user groups on the MeshCentral server, Example usages:\r\n" ) ;
console . log ( " MeshCtrl ListUserGroups" ) ;
console . log ( " MeshCtrl ListUserGroups --json" ) ;
break ;
}
2019-06-30 14:34:27 -04:00
case 'listdevicegroups' : {
2021-02-02 21:01:09 -05:00
console . log ( "List the device groups for this account. Example usages:\r\n" ) ;
2019-06-30 14:34:27 -04:00
console . log ( " MeshCtrl ListDeviceGroups " ) ;
console . log ( " MeshCtrl ListDeviceGroups --json" ) ;
2019-06-29 15:18:20 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --idexists [id] - Return 1 if id exists, 0 if not." ) ;
console . log ( " --nameexists [name] - Return id if name exists." ) ;
console . log ( " --emailexists [email] - Return id if email exists." ) ;
2020-07-15 18:12:01 -04:00
console . log ( " --hex - Display meshid in hex format." ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --json - Show result as JSON." ) ;
2019-06-29 15:18:20 -04:00
break ;
}
2019-07-05 16:28:41 -04:00
case 'listdevices' : {
2021-02-02 21:01:09 -05:00
console . log ( "List devices. Example usages:\r\n" ) ;
2019-07-05 16:28:41 -04:00
console . log ( " MeshCtrl ListDevices" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl ListDevices -id '[groupid]' --json" ) ) ;
2019-07-05 16:28:41 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Filter by group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Filter by group identifier (or --group)." ) ;
}
2020-07-17 16:52:45 -04:00
console . log ( " --group [groupname] - Filter by group name (or --id)." ) ;
2019-07-05 16:28:41 -04:00
console . log ( " --count - Only return the device count." ) ;
console . log ( " --json - Show result as JSON." ) ;
2022-07-19 16:24:59 -04:00
console . log ( " --csv - Show result as comma separated values." ) ;
2021-09-07 16:32:31 -04:00
console . log ( " --filter \"[filter]\" - Filter devices using a filter string." ) ;
console . log ( " \"x\" - Devices with \"x\" in the name." ) ;
console . log ( " \"user:x or u:x\" - Devices with \"x\" in the name of currently logged in user." ) ;
console . log ( " \"ip:x\" - Devices \"x\" IP address." ) ;
console . log ( " \"group:x or g:x\" - Devices with \"x\" in device group name." ) ;
console . log ( " \"tag:x or t:x\" - Devices with \"x\" in device tag." ) ;
console . log ( " \"atag:x or a:x\" - Devices with \"x\" in device agent tag." ) ;
console . log ( " \"os:x\" - Devices with \"x\" in the device OS description." ) ;
console . log ( " \"amt:x\" - Devices with Intel AMT provisioning state (0, 1, 2)." ) ;
console . log ( " \"desc:x\" - Devices with \"x\" in device description." ) ;
console . log ( " \"wsc:ok\" - Devices with Windows Security Center ok." ) ;
console . log ( " \"wsc:noav\" - Devices with Windows Security Center with anti-virus problem." ) ;
console . log ( " \"wsc:noupdate\" - Devices with Windows Security Center with update problem." ) ;
console . log ( " \"wsc:nofirewall\" - Devices with Windows Security Center with firewall problem." ) ;
console . log ( " \"wsc:any\" - Devices with Windows Security Center with any problem." ) ;
console . log ( " \"a and b\" - Match both conditions with precedence over OR. For example: \"lab and g:home\"." ) ;
console . log ( " \"a or b\" - Math one of the conditions, for example: \"lab or g:home\"." ) ;
2021-03-14 17:18:50 -04:00
console . log ( " --filterid [id,id...] - Show only results for devices with included id." ) ;
2021-07-24 14:28:55 -04:00
console . log ( " --details - Show all device details." ) ;
2019-07-05 16:28:41 -04:00
break ;
}
case 'listusersofdevicegroup' : {
2021-02-02 21:01:09 -05:00
console . log ( "List users that have permissions for a given device group. Example usage:\r\n" ) ;
2019-07-05 16:28:41 -04:00
console . log ( " MeshCtrl ListUserOfDeviceGroup " ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier." ) ;
}
2019-07-05 16:28:41 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --json - Show result as JSON." ) ;
break ;
}
2021-02-02 21:01:09 -05:00
case 'listevents' : {
console . log ( "List server events optionally filtered by user or device. Example usage:\r\n" ) ;
console . log ( " MeshCtrl ListEvents " ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --userid [name] - User account identifier." ) ;
console . log ( " --id [deviceid] - The device identifier." ) ;
console . log ( " --limit [number] - Maximum number of events to list." ) ;
console . log ( " --raw - Output raw data in JSON format." ) ;
console . log ( " --json - Give results in JSON format." ) ;
break ;
}
2021-05-07 15:15:44 -04:00
case 'logintokens' : {
console . log ( "List account login tokens and allow addition and removal. Example usage:\r\n" ) ;
console . log ( " MeshCtrl LoginTokens " ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --remove [name] - Remove a login token." ) ;
console . log ( " --add [name] - Add a login token." ) ;
console . log ( " --expire [minutes] - When adding a token, minutes until expire." ) ;
console . log ( " --json - Show login tokens in JSON format." ) ;
break ;
}
2019-06-29 15:18:20 -04:00
case 'adduser' : {
2021-02-02 21:01:09 -05:00
console . log ( "Add a new user account. Example usages:\r\n" ) ;
2019-06-29 15:18:20 -04:00
console . log ( " MeshCtrl AddUser --user newaccountname --pass newpassword" ) ;
2020-12-09 19:34:40 -05:00
console . log ( " MeshCtrl AddUser --user newaccountname --randompass --rights full" ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
console . log ( " --user [name] - New account name." ) ;
console . log ( " --pass [password] - New account password." ) ;
console . log ( " --randompass - Create account with a random password." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --domain [domain] - Account domain, only for cross-domain admins." ) ;
console . log ( " --email [email] - New account email address." ) ;
console . log ( " --emailverified - New account email is verified." ) ;
console . log ( " --resetpass - Request password reset on next login." ) ;
console . log ( " --realname [name] - Set the real name for this account." ) ;
console . log ( " --phone [number] - Set the account phone number." ) ;
2022-07-19 16:24:59 -04:00
console . log ( " --rights [none|full|a,b,c] - Comma separated list of server permissions. Possible values:" ) ;
2024-04-09 08:31:00 -04:00
console . log ( " manageusers,serverbackup,serverrestore,serverupdate,fileaccess,locked,nonewgroups,notools,usergroups,recordings,locksettings,allevents,nonewdevices" ) ;
2020-12-09 19:34:40 -05:00
break ;
}
case 'edituser' : {
console . log ( "Edit a user account, Example usages:\r\n" ) ;
console . log ( " MeshCtrl EditUser --userid user --rights locked,locksettings" ) ;
console . log ( " MeshCtrl EditUser --userid user --realname Jones" ) ;
2019-06-29 15:18:20 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-12-09 19:34:40 -05:00
console . log ( " --userid [name] - User account identifier." ) ;
2019-06-29 15:18:20 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2020-12-09 19:34:40 -05:00
console . log ( " --domain [domain] - Account domain, only for cross-domain admins." ) ;
console . log ( " --email [email] - Account email address." ) ;
console . log ( " --emailverified - Account email is verified." ) ;
console . log ( " --resetpass - Request password reset on next login." ) ;
console . log ( " --realname [name] - Set the real name for this account." ) ;
console . log ( " --phone [number] - Set the account phone number." ) ;
2022-07-19 16:24:59 -04:00
console . log ( " --rights [none|full|a,b,c] - Comma separated list of server permissions. Possible values:" ) ;
2024-04-09 08:31:00 -04:00
console . log ( " manageusers,serverbackup,serverrestore,serverupdate,fileaccess,locked,nonewgroups,notools,usergroups,recordings,locksettings,allevents,nonewdevices" ) ;
2019-06-29 15:18:20 -04:00
break ;
}
case 'removeuser' : {
console . log ( "Delete a user account, Example usages:\r\n" ) ;
console . log ( " MeshCtrl RemoveUser --userid accountid" ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --userid [id] - Account identifier." ) ;
2019-06-29 15:18:20 -04:00
break ;
}
2020-10-02 19:17:28 -04:00
case 'addusergroup' : {
console . log ( "Create a new user group, Example usages:\r\n" ) ;
console . log ( " MeshCtrl AddUserGroup --name \"Test Group\"" ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
console . log ( " --name [name] - Name of the user group." ) ;
break ;
}
case 'removeusergroup' : {
console . log ( "Remove a user group, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveUserGroup --groupid 'ugrp//abcdf'" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --groupid [groupid] - User group identifier." ) ;
} else {
console . log ( " --groupid '[groupid]' - User group identifier." ) ;
}
break ;
}
2020-10-05 06:53:30 -04:00
case 'addtousergroup' : {
console . log ( "Add a user, device or device group to a user group, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddToUserGroup --id 'user//abcdef' --groupid 'ugrp//abcdf'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddToUserGroup --id 'node//abcdef' --groupid 'ugrp//abcdf' --rights [rights]" ) ) ;
2020-10-05 12:48:03 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddToUserGroup --id 'mesh//abcdef' --groupid 'ugrp//abcdf' --rights [rights]" ) ) ;
2020-10-02 19:17:28 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
2020-10-05 06:53:30 -04:00
console . log ( " --id [id] - Identifier to add." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " --groupid [groupid] - User group identifier." ) ;
} else {
2020-10-05 06:53:30 -04:00
console . log ( " --id '[id]' - Identifier to add." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " --groupid '[groupid]' - User group identifier." ) ;
}
2020-10-05 06:53:30 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2020-10-05 12:48:03 -04:00
console . log ( " --rights [number] - Rights granted for adding device or device group." ) ;
console . log ( " - 4294967295 for full admin or the sum of the following numbers." ) ;
console . log ( " 1 = Edit Device Group 2 = Manage Users " ) ;
console . log ( " 4 = Manage Computers 8 = Remote Control " ) ;
console . log ( " 16 = Agent Console 32 = Server Files " ) ;
console . log ( " 64 = Wake Device 128 = Set Notes " ) ;
console . log ( " 256 = Remote View Only 512 = No Terminal " ) ;
console . log ( " 1024 = No Files 2048 = No Intel AMT " ) ;
console . log ( " 4096 = Desktop Limited Input 8192 = Limit Events " ) ;
console . log ( " 16384 = Chat / Notify 32768 = Uninstall Agent " ) ;
console . log ( " 65536 = No Remote Desktop 131072 = Remote Commands " ) ;
console . log ( " 262144 = Reset / Power off " ) ;
2020-10-02 19:17:28 -04:00
break ;
}
2020-10-05 06:53:30 -04:00
case 'removefromusergroup' : {
console . log ( "Remove a user, device or device group from a user group, Example usages:\r\n" ) ;
2020-10-02 19:17:28 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveUserFromUserGroup --userid 'user//abcdef' --groupid 'ugrp//abcdf'" ) ) ;
2020-10-05 06:53:30 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveUserFromUserGroup --userid 'node//abcdef' --groupid 'ugrp//abcdf'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveUserFromUserGroup --userid 'mesh//abcdef' --groupid 'ugrp//abcdf'" ) ) ;
2020-10-02 19:17:28 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
2020-10-05 06:53:30 -04:00
console . log ( " --id [userid] - Identifier to remove." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " --groupid [groupid] - User group identifier." ) ;
} else {
2020-10-05 06:53:30 -04:00
console . log ( " --id '[userid]' - Identifier to remove." ) ;
2020-10-02 19:17:28 -04:00
console . log ( " --groupid '[groupid]' - User group identifier." ) ;
}
break ;
}
case 'removeallusersfromusergroup' : {
console . log ( "Remove all users from a user group, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveAllUsersFromUserGroup --groupid 'ugrp//abcdf'" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --groupid [groupid] - User group identifier." ) ;
} else {
console . log ( " --groupid '[groupid]' - User group identifier." ) ;
}
break ;
}
2019-06-30 14:34:27 -04:00
case 'adddevicegroup' : {
console . log ( "Add a device group, Example usages:\r\n" ) ;
console . log ( " MeshCtrl AddDeviceGroup --name newgroupname" ) ;
console . log ( " MeshCtrl AddDeviceGroup --name newgroupname --desc description --amtonly" ) ;
2020-10-05 20:12:19 -04:00
console . log ( " MeshCtrl AddDeviceGroup --name newgroupname --features 1 --consent 7" ) ;
2019-06-30 14:34:27 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --name [name] - Name of the new group." ) ;
2019-06-30 14:34:27 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2019-07-01 19:46:05 -04:00
console . log ( " --desc [description] - New group description." ) ;
console . log ( " --amtonly - New group is agent-less, Intel AMT only." ) ;
2022-09-19 08:50:46 -04:00
console . log ( " --agentless - New group is agent-less only." ) ;
2020-10-05 20:12:19 -04:00
console . log ( " --features [number] - Set device group features, sum of numbers below." ) ;
console . log ( " 1 = Auto-Remove 2 = Hostname Sync" ) ;
console . log ( " 4 = Record Sessions" ) ;
console . log ( " --consent [number] - Set device group user consent, sum of numbers below." ) ;
console . log ( " 1 = Desktop notify user 2 = Terminal notify user " ) ;
console . log ( " 4 = Files notify user 8 = Desktop prompt user " ) ;
console . log ( " 16 = Terminal prompt user 32 = Files prompt user " ) ;
console . log ( " 64 = Desktop Toolbar " ) ;
2019-06-30 14:34:27 -04:00
break ;
}
case 'removedevicegroup' : {
console . log ( "Remove a device group, Example usages:\r\n" ) ;
2020-07-24 15:39:14 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveDeviceGroup --id 'groupid'" ) ) ;
2019-06-30 14:34:27 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier (or --group)." ) ;
}
2020-04-08 14:26:35 -04:00
console . log ( " --group [groupname] - Device group name (or --id)." ) ;
2019-06-30 14:34:27 -04:00
break ;
}
2020-07-24 15:32:43 -04:00
case 'editdevicegroup' : {
console . log ( "Edit a device group, Example usages:\r\n" ) ;
2020-07-24 15:39:14 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl EditDeviceGroup --id 'groupid' --name \"New Name\"" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl EditDeviceGroup --id 'groupid' --desc \"Description\" --consent 63" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl EditDeviceGroup --id 'groupid' --invitecodes \"code1,code2\" --backgroundonly" ) ) ;
2020-07-24 15:32:43 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier (or --group)." ) ;
}
console . log ( " --group [groupname] - Device group name (or --id)." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --name [name] - Set new device group name." ) ;
2020-07-24 15:39:14 -04:00
console . log ( " --desc [description] - Set new device group description, blank to clear." ) ;
2020-07-24 15:32:43 -04:00
console . log ( " --flags [number] - Set device group flags, sum of the values below, 0 for none." ) ;
console . log ( " 1 = Auto remove device on disconnect." ) ;
console . log ( " 2 = Sync hostname." ) ;
console . log ( " --consent [number] - Set device group consent options, sum of the values below, 0 for none." ) ;
console . log ( " 1 = Desktop notify user." ) ;
console . log ( " 2 = Terminal notify user." ) ;
console . log ( " 4 = Files notify user." ) ;
console . log ( " 8 = Desktop prompt for user consent." ) ;
console . log ( " 16 = Terminal prompt for user consent." ) ;
console . log ( " 32 = Files prompt for user consent." ) ;
console . log ( " 64 = Desktop show connection toolbar." ) ;
2022-07-19 16:24:59 -04:00
console . log ( " --invitecodes [aa,bb] - Comma separated list of invite codes, blank to clear." ) ;
2020-07-24 15:32:43 -04:00
console . log ( " --backgroundonly - When used with invitecodes, set agent to only install in background." ) ;
console . log ( " --interactiveonly - When used with invitecodes, set agent to only run on demand." ) ;
break ;
}
2020-04-16 11:46:53 -04:00
case 'movetodevicegroup' : {
console . log ( "Move a device to a new device group, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl MoveToDeviceGroup --devid 'deviceid' --id 'groupid'" ) ) ;
2020-04-16 11:46:53 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier (or --group)." ) ;
}
2020-04-16 11:46:53 -04:00
console . log ( " --group [groupname] - Device group name (or --id)." ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --devid [deviceid] - Device identifier." ) ;
} else {
console . log ( " --devid '[deviceid]' - Device identifier." ) ;
}
2020-04-16 11:46:53 -04:00
break ;
}
2019-07-01 17:44:26 -04:00
case 'addusertodevicegroup' : {
console . log ( "Add a user to a device group, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddUserToDeviceGroup --id 'groupid' --userid userid --fullrights" ) ) ;
2020-04-08 14:26:35 -04:00
console . log ( " MeshCtrl AddUserToDeviceGroup --group groupname --userid userid --editgroup --manageusers" ) ;
2019-07-01 17:44:26 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier (or --group)." ) ;
}
2020-04-08 14:26:35 -04:00
console . log ( " --group [groupname] - Device group name (or --id)." ) ;
2019-07-01 17:44:26 -04:00
console . log ( " --userid [userid] - The user identifier." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --fullrights - Allow full rights over this device group." ) ;
console . log ( " --editgroup - Allow the user to edit group information." ) ;
console . log ( " --manageusers - Allow the user to add/remove users." ) ;
console . log ( " --managedevices - Allow the user to edit device information." ) ;
console . log ( " --remotecontrol - Allow device remote control operations." ) ;
console . log ( " --agentconsole - Allow agent console operations." ) ;
console . log ( " --serverfiles - Allow access to group server files." ) ;
console . log ( " --wakedevices - Allow device wake operation." ) ;
console . log ( " --notes - Allow editing of device notes." ) ;
console . log ( " --desktopviewonly - Restrict user to view-only remote desktop." ) ;
console . log ( " --limiteddesktop - Limit remote desktop keys." ) ;
console . log ( " --noterminal - Hide the terminal tab from this user." ) ;
console . log ( " --nofiles - Hide the files tab from this user." ) ;
console . log ( " --noamt - Hide the Intel AMT tab from this user." ) ;
2020-04-01 16:15:14 -04:00
console . log ( " --limitedevents - User can only see his own events." ) ;
console . log ( " --chatnotify - Allow chat and notification options." ) ;
console . log ( " --uninstall - Allow remote uninstall of the agent." ) ;
if ( args . limiteddesktop ) { meshrights |= 4096 ; }
if ( args . limitedevents ) { meshrights |= 8192 ; }
if ( args . chatnotify ) { meshrights |= 16384 ; }
if ( args . uninstall ) { meshrights |= 32768 ; }
2019-07-01 17:44:26 -04:00
break ;
}
case 'removeuserfromdevicegroup' : {
console . log ( "Remove a user from a device group, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveuserFromDeviceGroup --id 'groupid' --userid userid" ) ) ;
2019-07-01 17:44:26 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - Device group identifier (or --group)." ) ;
} else {
console . log ( " --id '[groupid]' - Device group identifier (or --group)." ) ;
}
2020-04-08 14:26:35 -04:00
console . log ( " --group [groupname] - Device group name (or --id)." ) ;
2019-07-01 17:44:26 -04:00
console . log ( " --userid [userid] - The user identifier." ) ;
break ;
}
2020-04-01 16:15:14 -04:00
case 'addusertodevice' : {
console . log ( "Add a user to a device, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddUserToDevice --id 'deviceid' --userid userid --fullrights" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddUserToDevice --id 'deviceid' --userid userid --remotecontrol" ) ) ;
2020-04-01 16:15:14 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
2020-04-01 16:15:14 -04:00
console . log ( " --userid [userid] - The user identifier." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --fullrights - Allow full rights over this device." ) ;
console . log ( " --remotecontrol - Allow device remote control operations." ) ;
console . log ( " --agentconsole - Allow agent console operations." ) ;
console . log ( " --serverfiles - Allow access to group server files." ) ;
console . log ( " --wakedevices - Allow device wake operation." ) ;
console . log ( " --notes - Allow editing of device notes." ) ;
console . log ( " --desktopviewonly - Restrict user to view-only remote desktop." ) ;
console . log ( " --limiteddesktop - Limit remote desktop keys." ) ;
console . log ( " --noterminal - Hide the terminal tab from this user." ) ;
console . log ( " --nofiles - Hide the files tab from this user." ) ;
console . log ( " --noamt - Hide the Intel AMT tab from this user." ) ;
console . log ( " --limitedevents - User can only see his own events." ) ;
console . log ( " --chatnotify - Allow chat and notification options." ) ;
console . log ( " --uninstall - Allow remote uninstall of the agent." ) ;
break ;
}
case 'removeuserfromdevice' : {
console . log ( "Remove a user from a device, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveuserFromDeviceGroup --id 'deviceid' --userid userid" ) ) ;
2020-04-01 16:15:14 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
2020-04-01 16:15:14 -04:00
console . log ( " --userid [userid] - The user identifier." ) ;
break ;
}
2019-06-30 14:34:27 -04:00
case 'broadcast' : {
2020-11-05 05:27:39 -05:00
console . log ( "Display a message to one or all logged in users, Example usages:\r\n" ) ;
2019-06-30 14:34:27 -04:00
console . log ( " MeshCtrl Broadcast --msg \"This is a test\"" ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-04-01 16:15:14 -04:00
console . log ( " --msg [message] - Message to display." ) ;
2020-11-05 05:27:39 -05:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2022-07-19 16:24:59 -04:00
console . log ( " --user [userid] - Send the message to the specified user." ) ;
2019-06-30 14:34:27 -04:00
break ;
}
2020-05-02 16:49:56 -04:00
case 'deviceinfo' : {
console . log ( "Display information about a device, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceInfo --id 'deviceid'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceInfo --id 'deviceid' --json" ) ) ;
2020-05-02 16:49:56 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
2020-05-02 16:49:56 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --raw - Output raw data in JSON format." ) ;
console . log ( " --json - Give results in JSON format." ) ;
break ;
}
2022-11-14 19:31:44 -05:00
case 'removedevice' : {
console . log ( "Delete a device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl RemoveDevice --id 'deviceid'" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
break ;
}
2024-10-25 05:34:16 -04:00
case 'addlocaldevice' : {
console . log ( "Add a Local Device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddLocalDevice --id 'meshid' --devicename 'devicename' --hostname 'hostname'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddLocalDevice --id 'meshid' --devicename 'devicename' --hostname 'hostname' --type 6" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [meshid] - The mesh identifier." ) ;
console . log ( " --devicename [devicename] - The device name." ) ;
console . log ( " --hostname [hostname] - The devices hostname or ip address." ) ;
} else {
console . log ( " --id '[meshid]' - The mesh identifier." ) ;
console . log ( " --devicename '[devicename]' - The device name." ) ;
console . log ( " --hostname '[hostname]' - The devices hostname or ip address." ) ;
}
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --type [TypeNumber] - With the following choices:" ) ;
console . log ( " type 4 - Default, Windows (RDP)" ) ;
console . log ( " type 6 - Linux (SSH/SCP/VNC)" ) ;
console . log ( " type 29 - macOS (SSH/SCP/VNC)" ) ;
break ;
}
case 'addamtdevice' : {
console . log ( "Add an Intel AMT Device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddAmtDevice --id 'meshid' --devicename 'devicename' --hostname 'hostname --user 'admin' --pass 'admin'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AddAmtDevice --id 'meshid' --devicename 'devicename' --hostname 'hostname --user 'admin' --pass 'admin' --notls" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [meshid] - The mesh identifier." ) ;
console . log ( " --devicename [devicename] - The device name." ) ;
console . log ( " --hostname [hostname] - The devices hostname or ip address." ) ;
console . log ( " --user [user] - The devices AMT username." ) ;
console . log ( " --pass [pass] - The devices AMT password." ) ;
console . log ( "" )
} else {
console . log ( " --id '[meshid]' - The mesh identifier." ) ;
console . log ( " --devicename '[devicename]' - The device name." ) ;
console . log ( " --hostname '[hostname]' - The devices hostname or ip address." ) ;
console . log ( " --user '[user]' - The devices AMT username." ) ;
console . log ( " --pass '[pass]' - The devices AMT password." ) ;
}
console . log ( "\r\nOptional arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --notls - Use No TLS Security." ) ;
} else {
console . log ( " --notls - Use No TLS Security." ) ;
}
break ;
}
2021-06-11 15:48:43 -04:00
case 'editdevice' : {
console . log ( "Change information about a device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl EditDevice --id 'deviceid' --name 'device1'" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
console . log ( "\r\nOptional arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --name [name] - Change device name." ) ;
console . log ( " --desc [description] - Change device description." ) ;
console . log ( " --tags [tag1,tags2] - Change device tags." ) ;
} else {
console . log ( " --name '[name]' - Change device name." ) ;
console . log ( " --desc '[description]' - Change device description." ) ;
console . log ( " --tags '[tag1,tags2]' - Change device tags." ) ;
}
console . log ( " --icon [number] - Change the device icon (1 to 8)." ) ;
console . log ( " --consent [flags] - Sum of the following numbers:" ) ;
console . log ( " 1 = Desktop notify 2 = Terminal notify" ) ;
console . log ( " 4 = Files notify 8 = Desktop prompt" ) ;
console . log ( " 16 = Terminal prompt 32 = Files prompt" ) ;
console . log ( " 64 = Desktop privacy bar" ) ;
break ;
}
2020-07-13 15:25:14 -04:00
case 'runcommand' : {
console . log ( "Run a shell command on a remote device, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl RunCommand --id 'deviceid' --run \"command\"" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl RunCommand --id 'deviceid' --run \"command\" --powershell" ) ) ;
2024-03-14 10:33:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl RunCommand --id 'deviceid' --run \"command\" --reply" ) ) ;
2020-07-13 15:25:14 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
2020-07-13 15:25:14 -04:00
console . log ( " --run \"[command]\" - Shell command to execute on the remote device." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --powershell - Run in Windows PowerShell." ) ;
2020-09-29 16:20:08 -04:00
console . log ( " --runasuser - Attempt to run the command as logged in user." ) ;
console . log ( " --runasuseronly - Only run the command as the logged in user." ) ;
2024-03-14 10:33:02 -04:00
console . log ( " --reply - Return with the output from running the command." ) ;
2020-07-13 15:25:14 -04:00
break ;
}
2020-07-13 18:06:45 -04:00
case 'shell' : {
console . log ( "Access a command shell on a remote device, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl Shell --id 'deviceid'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl Shell --id 'deviceid' --powershell" ) ) ;
2020-07-13 18:06:45 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
2020-07-13 18:06:45 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --powershell - Run a Windows PowerShell." ) ;
break ;
}
2021-01-05 21:29:23 -05:00
case 'devicepower' : {
console . log ( "Perform power operations on remote devices, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DevicePower --wake --id 'deviceid'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DevicePower --sleep --id 'deviceid'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DevicePower --reset --id 'deviceid'" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DevicePower --off --id 'deviceid1,deviceid2'" ) ) ;
console . log ( "\r\nNote that some power operations may take up to a minute to execute.\r\n" ) ;
console . log ( "Required arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid1,deviceid2] - Device identifiers." ) ;
} else {
console . log ( " --id '[deviceid1,deviceid2]' - Device identifiers." ) ;
}
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --wake - Attempt to wake up the remote device." ) ;
console . log ( " --reset - Attempt to remote the remote device." ) ;
console . log ( " --sleep - Attempt to place the remote device in low power mode." ) ;
console . log ( " --off - Attempt to power off the remote device." ) ;
2022-05-24 17:37:48 -04:00
console . log ( " --amtoff - Attempt to power off the remote device using Intel AMT." ) ;
console . log ( " --amton - Attempt to power on the remote device using Intel AMT." ) ;
console . log ( " --amtreset - Attempt to reset the remote device using Intel AMT." ) ;
2021-01-05 21:29:23 -05:00
break ;
}
2021-01-05 20:02:24 -05:00
case 'devicesharing' : {
var tzoffset = ( new Date ( ) ) . getTimezoneOffset ( ) * 60000 ; // Offset in milliseconds
var localISOTime = ( new Date ( Date . now ( ) - tzoffset ) ) . toISOString ( ) . slice ( 0 , - 5 ) ;
console . log ( "List sharing links for a specified device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceSharing --id 'deviceid'" ) ) ;
2021-10-08 16:24:04 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceSharing --id 'deviceid' --remove abcdef" ) ) ;
2021-01-05 20:02:24 -05:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceSharing --id 'deviceid' --add Guest --start " + localISOTime + " --duration 30" ) ) ;
2022-01-17 14:38:49 -05:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceSharing --id 'deviceid' --add Guest --start " + localISOTime + " --duration 30 --daily" ) ) ;
2021-10-08 21:35:30 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceSharing --id 'deviceid' --add Guest --type desktop,terminal --consent prompt" ) ) ;
2024-03-02 16:56:14 -05:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceSharing --id 'deviceid' --add Guest --type http --port 80" ) ) ;
2021-01-05 20:02:24 -05:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
console . log ( "\r\nOptional arguments:\r\n" ) ;
2024-03-02 16:56:14 -05:00
console . log ( " --remove [shareid] - Remove a device sharing link." ) ;
console . log ( " --add [guestname] - Add a device sharing link." ) ;
console . log ( " --type [desktop,terminal,files,http,https] - Type of sharing to add, can be combined. default is desktop." ) ;
console . log ( " --viewonly - Make desktop sharing view only." ) ;
console . log ( " --consent [notify,prompt,none] - Consent flags, default is notify." ) ;
console . log ( " --start [yyyy-mm-ddThh:mm:ss] - Start time, default is now." ) ;
console . log ( " --end [yyyy-mm-ddThh:mm:ss] - End time." ) ;
console . log ( " --duration [minutes] - Duration of the share, default is 60 minutes." ) ;
console . log ( " --daily - Add recurring daily device share." ) ;
console . log ( " --weekly - Add recurring weekly device share." ) ;
console . log ( " --port [portnumber] - Set alternative port for http or https, default is 80 for http and 443 for https." ) ;
2021-01-05 20:02:24 -05:00
break ;
}
2021-08-05 04:13:44 -04:00
case 'agentdownload' : {
console . log ( "Download an agent of a specific type for a given device group, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl AgentDownload --id 'groupid' --type 3" ) ) ;
2024-05-28 13:24:39 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl AgentDownload --id 'groupid' --type 3 --installflags 1" ) ) ;
2021-08-05 04:13:44 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
console . log ( " --type [ArchitectureNumber] - Agent architecture number." ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [groupid] - The device group identifier." ) ;
} else {
console . log ( " --id '[groupid]' - The device group identifier." ) ;
}
2024-05-28 13:24:39 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --installflags [InstallFlagsNumber] - With the following choices:" ) ;
console . log ( " installflags 0 - Default, Interactive & Background, offers connect button & install/uninstall" ) ;
console . log ( " installflags 1 - Interactive only, offers only connect button, not install/uninstall" ) ;
console . log ( " installflags 2 - Background only, offers only install/uninstall, not connect" ) ;
2021-08-05 04:13:44 -04:00
break ;
}
2020-07-16 17:08:06 -04:00
case 'upload' : {
console . log ( "Upload a local file to a remote device, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl Upload --id 'deviceid' --file sample.txt --target c:\\" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl Upload --id 'deviceid' --file sample.txt --target /tmp" ) ) ;
2020-07-16 17:08:06 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
2020-07-16 17:08:06 -04:00
console . log ( " --file [localfile] - The local file to upload." ) ;
console . log ( " --target [remotepath] - The remote path to upload the file to." ) ;
break ;
}
case 'download' : {
console . log ( "Download a file from a remote device, Example usages:\r\n" ) ;
2020-07-17 17:29:02 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl Download --id 'deviceid' --file C:\\sample.txt --target c:\\temp" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl Download --id 'deviceid' --file /tmp/sample.txt --target /tmp" ) ) ;
2020-07-16 17:08:06 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
2020-07-17 17:29:02 -04:00
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
2020-07-16 17:08:06 -04:00
console . log ( " --file [remotefile] - The remote file to download." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --target [localpath] - The local path to download the file to." ) ;
break ;
}
2024-11-26 11:46:14 -05:00
case 'webrelay' : {
console . log ( "Generate a webrelay URL to access a HTTP/HTTPS service on a remote device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl WebRelay --id 'deviceid' --type http --port 80" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl WebRelay --id 'deviceid' --type https --port 443" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
console . log ( " --type [http,https] - Type of relay from remote device, http or https." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --port [portnumber] - Set alternative port for http or https, default is 80 for http and 443 for https." ) ;
break ;
}
2020-08-17 18:01:25 -04:00
case 'deviceopenurl' : {
console . log ( "Open a web page on a remote device, Example usages:\r\n" ) ;
2020-08-17 18:24:33 -04:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceOpenUrl --id 'deviceid' --openurl http://meshcentral.com" ) ) ;
2020-08-17 18:01:25 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
console . log ( " --openurl [url] - Link to the web page." ) ;
break ;
}
case 'devicemessage' : {
console . log ( "Display a message on the remote device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceMessage --id 'deviceid' --msg \"message\"" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceMessage --id 'deviceid' --msg \"message\" --title \"title\"" ) ) ;
2024-01-12 17:46:12 -05:00
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceMessage --id 'deviceid' --msg \"message\" --title \"title\" --timeout 120000" ) ) ;
2020-08-17 18:01:25 -04:00
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
2024-01-12 17:46:12 -05:00
console . log ( " --id [deviceid] - The device identifier." ) ;
2020-08-17 18:01:25 -04:00
} else {
2024-01-12 17:46:12 -05:00
console . log ( " --id '[deviceid]' - The device identifier." ) ;
2020-08-17 18:01:25 -04:00
}
2024-01-12 17:46:12 -05:00
console . log ( " --msg [message] - The message to display." ) ;
2020-08-17 18:01:25 -04:00
console . log ( "\r\nOptional arguments:\r\n" ) ;
2024-01-12 17:46:12 -05:00
console . log ( " --title [title] - Messagebox title, default is \"MeshCentral\"." ) ;
console . log ( " --timeout [miliseconds] - After timeout messagebox vanishes, 0 keeps messagebox open until closed manually, default is 120000 (2 Minutes)." ) ;
2020-08-17 18:01:25 -04:00
break ;
}
case 'devicetoast' : {
console . log ( "Display a toast message on the remote device, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceToast --id 'deviceid' --msg \"message\"" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl DeviceToast --id 'deviceid' --msg \"message\" --title \"title\"" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [deviceid] - The device identifier." ) ;
} else {
console . log ( " --id '[deviceid]' - The device identifier." ) ;
}
console . log ( " --msg [message] - The message to display." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --title [title] - Toast title, default is \"MeshCentral\"." ) ;
break ;
}
2024-01-25 04:44:27 -05:00
case 'groupmessage' : {
console . log ( "Open a message box on remote devices in a specific device group, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl GroupMessage --id 'devicegroupid' --msg \"message\"" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl GroupMessage --id 'devicegroupid' --msg \"message\" --title \"title\"" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl GroupMessage --id 'devicegroupid' --msg \"message\" --title \"title\" --timeout 120000" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [devicegroupid] - The device identifier." ) ;
} else {
console . log ( " --id '[devicegroupid]' - The device identifier." ) ;
}
console . log ( " --msg [message] - The message to display." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --title [title] - Messagebox title, default is \"MeshCentral\"." ) ;
console . log ( " --timeout [miliseconds] - After timeout messagebox vanishes, 0 keeps messagebox open until closed manually, default is 120000 (2 Minutes)." ) ;
break ;
}
case 'grouptoast' : {
console . log ( "Display a toast notification on remote devices in a specific device group, Example usages:\r\n" ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl GroupToast --id 'devicegroupid' --msg \"message\"" ) ) ;
console . log ( winRemoveSingleQuotes ( " MeshCtrl GroupToast --id 'devicegroupid' --msg \"message\" --title \"title\"" ) ) ;
console . log ( "\r\nRequired arguments:\r\n" ) ;
if ( process . platform == 'win32' ) {
console . log ( " --id [devicegroupid] - The device identifier." ) ;
} else {
console . log ( " --id '[devicegroupid]' - The device identifier." ) ;
}
console . log ( " --msg [message] - The message to display." ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --title [title] - Toast title, default is \"MeshCentral\"." ) ;
break ;
}
2023-03-30 08:07:30 -04:00
case 'report' : {
console . log ( "Generate a CSV report, Example usages:\r\n" ) ;
console . log ( " MeshCtrl Report --type sessions --devicegroup mesh//..." ) ;
console . log ( " MeshCtrl Report --type traffic --json" ) ;
console . log ( " MeshCtrl Report --type logins --groupby day" ) ;
console . log ( " MeshCtrl Report --type db" ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --start [yyyy-mm-ddThh:mm:ss] - Filter the results starting at that date. Defaults to last 24h and last week when used with --groupby day. Usable with sessions, traffic and logins" ) ;
console . log ( " --end [yyyy-mm-ddThh:mm:ss] - Filter the results ending at that date. Defaults to now. Usable with sessions, traffic and logins" ) ;
console . log ( " --groupby [name] - How to group results. Options: user, day, device. Defaults to user. User and day usable in sessions and logins, device usable in sessions." ) ;
console . log ( " --devicegroup [devicegroupid] - Filter the results by device group. Usable in sessions" ) ;
console . log ( " --showtraffic - Add traffic data in sessions report" ) ;
break ;
}
2019-06-29 15:18:20 -04:00
default : {
console . log ( "Get help on an action. Type:\r\n\r\n help [action]\r\n\r\nPossible actions are: " + possibleCommands . join ( ', ' ) + '.' ) ;
}
}
}
break ;
}
2019-06-28 21:31:18 -04:00
}
2023-11-12 16:49:20 -05:00
if ( ok ) {
if ( args . loginpass === true ) {
const readline = require ( 'readline' ) ;
const rl = readline . createInterface ( {
input : process . stdin ,
output : process . stdout ,
terminal : false
} ) ;
process . stdout . write ( 'Enter your password: ' ) ;
const stdin = process . openStdin ( ) ;
stdin . setRawMode ( true ) ; // Set raw mode to prevent echoing of characters
stdin . resume ( ) ;
args . loginpass = '' ;
process . stdin . on ( 'data' , ( char ) => {
char = char + '' ;
switch ( char ) {
case '\n' :
case '\r' :
case '\u0004' : // They've finished entering their password
stdin . setRawMode ( false ) ;
stdin . pause ( ) ;
process . stdout . clearLine ( ) ; process . stdout . cursorTo ( 0 ) ;
rl . close ( ) ;
serverConnect ( ) ;
break ;
case '\u0003' : // Ctrl+C
process . stdout . write ( '\n' ) ;
process . exit ( ) ;
break ;
default : // Mask the password with "*"
args . loginpass += char ;
process . stdout . clearLine ( ) ; process . stdout . cursorTo ( 0 ) ;
process . stdout . write ( 'Enter your password: ' + '*' . repeat ( args . loginpass . length ) ) ;
break ;
}
} ) ;
} else {
serverConnect ( ) ;
}
}
2019-06-28 21:31:18 -04:00
}
2019-12-20 20:29:38 -05:00
function displayConfigHelp ( ) {
console . log ( "Perform operations on the config.json file. Example usage:\r\n" ) ;
console . log ( " MeshCtrl config --show" ) ;
console . log ( "\r\nOptional arguments:\r\n" ) ;
console . log ( " --show - Display the config.json file." ) ;
console . log ( " --listdomains - Display non-default domains." ) ;
console . log ( " --adddomain [domain] - Add a domain." ) ;
console . log ( " --removedomain [domain] - Remove a domain." ) ;
console . log ( " --settodomain [domain] - Set values to the domain." ) ;
console . log ( " --removefromdomain [domain] - Remove values from the domain." ) ;
console . log ( "\r\nWith adddomain, removedomain, settodomain and removefromdomain you can add the key and value pair. For example:\r\n" ) ;
console . log ( " --adddomain \"MyDomain\" --title \"My Server Name\" --newAccounts false" ) ;
console . log ( " --settodomain \"MyDomain\" --title \"My Server Name\"" ) ;
console . log ( " --removefromdomain \"MyDomain\" --title" ) ;
}
2019-11-22 19:17:29 -05:00
function performConfigOperations ( args ) {
2021-09-10 16:04:10 -04:00
var domainValues = [ 'title' , 'title2' , 'titlepicture' , 'trustedcert' , 'welcomepicture' , 'welcometext' , 'userquota' , 'meshquota' , 'newaccounts' , 'usernameisemail' , 'newaccountemaildomains' , 'newaccountspass' , 'newaccountsrights' , 'geolocation' , 'lockagentdownload' , 'userconsentflags' , 'Usersessionidletimeout' , 'auth' , 'ldapoptions' , 'ldapusername' , 'ldapuserbinarykey' , 'ldapuseremail' , 'footer' , 'certurl' , 'loginKey' , 'userallowedip' , 'agentallowedip' , 'agentnoproxy' , 'agentconfig' , 'orphanagentuser' , 'httpheaders' , 'yubikey' , 'passwordrequirements' , 'limits' , 'amtacmactivation' , 'redirects' , 'sessionrecording' , 'hide' ] ;
2022-11-14 19:31:44 -05:00
var domainObjectValues = [ 'ldapoptions' , 'httpheaders' , 'yubikey' , 'passwordrequirements' , 'limits' , 'amtacmactivation' , 'redirects' , 'sessionrecording' ] ;
var domainArrayValues = [ 'newaccountemaildomains' , 'newaccountsrights' , 'loginkey' , 'agentconfig' ] ;
2019-11-22 19:17:29 -05:00
var configChange = false ;
var fs = require ( 'fs' ) ;
var path = require ( 'path' ) ;
2020-06-12 15:39:51 -04:00
var configFile = 'config.json' ;
2019-12-20 20:29:38 -05:00
var didSomething = 0 ;
2019-12-12 14:44:03 -05:00
if ( fs . existsSync ( configFile ) == false ) { configFile = path . join ( 'meshcentral-data' , 'config.json' ) ; }
2020-06-12 15:39:51 -04:00
if ( fs . existsSync ( configFile ) == false ) { configFile = path . join ( _ _dirname , 'config.json' ) ; }
2019-11-22 19:17:29 -05:00
if ( fs . existsSync ( configFile ) == false ) { configFile = path . join ( _ _dirname , 'meshcentral-data' , 'config.json' ) ; }
if ( fs . existsSync ( configFile ) == false ) { configFile = path . join ( _ _dirname , '..' , 'meshcentral-data' , 'config.json' ) ; }
2020-06-23 15:35:23 -04:00
if ( fs . existsSync ( configFile ) == false ) { configFile = path . join ( _ _dirname , '..' , '..' , 'meshcentral-data' , 'config.json' ) ; }
2019-11-22 19:17:29 -05:00
if ( fs . existsSync ( configFile ) == false ) { console . log ( "Unable to find config.json." ) ; return ; }
var config = null ;
2020-06-23 15:35:23 -04:00
try { config = fs . readFileSync ( configFile ) . toString ( 'utf8' ) ; } catch ( ex ) { console . log ( "Error: Unable to read config.json" ) ; return ; }
2024-04-15 13:48:25 -04:00
try { config = JSON . parse ( fs . readFileSync ( configFile ) ) ; } catch ( e ) { console . log ( 'ERROR: Unable to parse ' + configFile + '.' ) ; return null ; }
2019-11-22 19:17:29 -05:00
if ( args . adddomain != null ) {
2019-12-20 20:29:38 -05:00
didSomething ++ ;
2019-11-22 19:17:29 -05:00
if ( config . domains == null ) { config . domains = { } ; }
if ( config . domains [ args . adddomain ] != null ) { console . log ( "Error: Domain \"" + args . adddomain + "\" already exists" ) ; }
else {
configChange = true ;
config . domains [ args . adddomain ] = { } ;
for ( var i in args ) {
if ( domainValues . indexOf ( i . toLowerCase ( ) ) >= 0 ) {
if ( args [ i ] == 'true' ) { args [ i ] = true ; } else if ( args [ i ] == 'false' ) { args [ i ] = false ; } else if ( parseInt ( args [ i ] ) == args [ i ] ) { args [ i ] = parseInt ( args [ i ] ) ; }
config . domains [ args . adddomain ] [ i ] = args [ i ] ;
configChange = true ;
}
}
}
}
if ( args . removedomain != null ) {
2019-12-20 20:29:38 -05:00
didSomething ++ ;
2019-11-22 19:17:29 -05:00
if ( config . domains == null ) { config . domains = { } ; }
if ( config . domains [ args . removedomain ] == null ) { console . log ( "Error: Domain \"" + args . removedomain + "\" does not exist" ) ; }
else { delete config . domains [ args . removedomain ] ; configChange = true ; }
}
if ( args . settodomain != null ) {
2019-12-20 20:29:38 -05:00
didSomething ++ ;
2019-11-22 19:17:29 -05:00
if ( config . domains == null ) { config . domains = { } ; }
2019-12-21 18:05:58 -05:00
if ( args . settodomain == true ) { args . settodomain = '' ; }
2019-11-22 19:17:29 -05:00
if ( config . domains [ args . settodomain ] == null ) { console . log ( "Error: Domain \"" + args . settodomain + "\" does not exist" ) ; }
else {
for ( var i in args ) {
2019-12-21 18:05:58 -05:00
if ( ( i == '_' ) || ( i == 'settodomain' ) ) continue ;
2019-11-22 19:17:29 -05:00
if ( domainValues . indexOf ( i . toLowerCase ( ) ) >= 0 ) {
2019-12-21 18:05:58 -05:00
var isObj = ( domainObjectValues . indexOf ( i . toLowerCase ( ) ) >= 0 ) ;
var isArr = ( domainArrayValues . indexOf ( i . toLowerCase ( ) ) >= 0 ) ;
if ( ( isObj == false ) && ( isArr == false ) ) {
// Simple value set
if ( args [ i ] == '' ) { delete config . domains [ args . settodomain ] [ i ] ; configChange = true ; } else {
if ( args [ i ] == 'true' ) { args [ i ] = true ; } else if ( args [ i ] == 'false' ) { args [ i ] = false ; } else if ( parseInt ( args [ i ] ) == args [ i ] ) { args [ i ] = parseInt ( args [ i ] ) ; }
config . domains [ args . settodomain ] [ i ] = args [ i ] ;
configChange = true ;
}
} else if ( isObj || isArr ) {
// Set an object/array value
if ( args [ i ] == '' ) { delete config . domains [ args . settodomain ] [ i ] ; configChange = true ; } else {
var x = null ;
try { x = JSON . parse ( args [ i ] ) ; } catch ( ex ) { }
if ( ( x == null ) || ( typeof x != 'object' ) ) { console . log ( "Unable to parse JSON for " + i + "." ) ; } else {
if ( isArr && Array . isArray ( x ) == false ) {
console . log ( "Value " + i + " must be an array." ) ;
} else if ( ! isArr && Array . isArray ( x ) == true ) {
console . log ( "Value " + i + " must be an object." ) ;
} else {
config . domains [ args . settodomain ] [ i ] = x ;
configChange = true ;
}
}
}
2019-11-22 19:17:29 -05:00
}
2019-12-21 18:05:58 -05:00
} else {
console . log ( 'Invalid configuration value: ' + i ) ;
2019-11-22 19:17:29 -05:00
}
}
}
}
if ( args . removefromdomain != null ) {
2019-12-20 20:29:38 -05:00
didSomething ++ ;
2019-11-22 19:17:29 -05:00
if ( config . domains == null ) { config . domains = { } ; }
if ( config . domains [ args . removefromdomain ] == null ) { console . log ( "Error: Domain \"" + args . removefromdomain + "\" does not exist" ) ; }
else { for ( var i in args ) { if ( domainValues . indexOf ( i . toLowerCase ( ) ) >= 0 ) { delete config . domains [ args . removefromdomain ] [ i ] ; configChange = true ; } } }
}
if ( configChange ) {
try { fs . writeFileSync ( configFile , JSON . stringify ( config , null , 2 ) ) ; } catch ( ex ) { console . log ( "Error: Unable to read config.json" ) ; return ; }
}
2019-12-20 20:29:38 -05:00
if ( args . show == 1 ) {
console . log ( JSON . stringify ( config , null , 2 ) ) ; return ;
} else if ( args . listdomains == 1 ) {
if ( config . domains == null ) {
console . log ( 'No domains found.' ) ; return ;
} else {
// Show the list of active domains, skip the default one.
for ( var i in config . domains ) { if ( ( i != '' ) && ( i [ 0 ] != '_' ) ) { console . log ( i ) ; } } return ;
}
} else {
if ( didSomething == 0 ) {
displayConfigHelp ( ) ;
} else {
2019-12-21 18:05:58 -05:00
console . log ( "Done." ) ;
2019-12-20 20:29:38 -05:00
}
}
2019-11-22 19:17:29 -05:00
}
2019-06-30 14:34:27 -04:00
function onVerifyServer ( clientName , certs ) { return null ; }
2019-06-28 21:31:18 -04:00
function serverConnect ( ) {
const WebSocket = require ( 'ws' ) ;
2019-06-29 15:18:20 -04:00
var url = 'wss://localhost/control.ashx' ;
if ( args . url ) {
url = args . url ;
if ( url . length < 5 ) { console . log ( "Invalid url." ) ; process . exit ( ) ; return ; }
if ( ( url . startsWith ( 'wss://' ) == false ) && ( url . startsWith ( 'ws://' ) == false ) ) { console . log ( "Invalid url." ) ; process . exit ( ) ; return ; }
2020-09-18 14:09:03 -04:00
var i = url . indexOf ( '?key=' ) , loginKey = null ;
if ( i >= 0 ) { loginKey = url . substring ( i + 5 ) ; url = url . substring ( 0 , i ) ; }
2019-06-29 15:18:20 -04:00
if ( url . endsWith ( '/' ) == false ) { url += '/' ; }
url += 'control.ashx' ;
2020-09-18 14:09:03 -04:00
if ( loginKey != null ) { url += '?key=' + loginKey ; }
2019-06-29 15:18:20 -04:00
}
2019-06-30 14:34:27 -04:00
// TODO: checkServerIdentity does not work???
2019-06-29 15:18:20 -04:00
var options = { rejectUnauthorized : false , checkServerIdentity : onVerifyServer }
2020-04-16 01:27:03 -04:00
// Setup the HTTP proxy if needed
if ( args . proxy != null ) {
const HttpsProxyAgent = require ( 'https-proxy-agent' ) ;
options . agent = new HttpsProxyAgent ( require ( 'url' ) . parse ( args . proxy ) ) ;
}
2019-06-29 15:18:20 -04:00
// Password authentication
if ( args . loginpass != null ) {
var username = 'admin' ;
2019-09-20 18:20:59 -04:00
if ( args . loginuser != null ) { username = args . loginuser ; }
2019-06-29 15:18:20 -04:00
var token = '' ;
if ( args . token != null ) { token = ',' + Buffer . from ( '' + args . token ) . toString ( 'base64' ) ; }
2021-04-15 15:19:03 -04:00
options . headers = { 'x-meshauth' : Buffer . from ( '' + username ) . toString ( 'base64' ) + ',' + Buffer . from ( '' + args . loginpass ) . toString ( 'base64' ) + token }
2019-06-29 15:18:20 -04:00
}
// Cookie authentication
2021-09-10 16:04:10 -04:00
var ckey = null , loginCookie = null ;
2019-06-29 15:18:20 -04:00
if ( args . loginkey != null ) {
2022-05-10 22:55:08 -04:00
// User key passed in as argument hex
2021-09-10 16:04:10 -04:00
if ( args . loginkey . length != 160 ) { loginCookie = args . loginkey ; }
2019-06-29 15:18:20 -04:00
ckey = Buffer . from ( args . loginkey , 'hex' ) ;
2022-05-10 22:55:08 -04:00
if ( ckey . length != 80 ) { ckey = null ; loginCookie = args . loginkey ; }
2019-06-29 15:18:20 -04:00
} else if ( args . loginkeyfile != null ) {
// Load key from hex file
var fs = require ( 'fs' ) ;
try {
var keydata = fs . readFileSync ( args . loginkeyfile , 'utf8' ) . split ( ' ' ) . join ( '' ) . split ( '\r' ) . join ( '' ) . split ( '\n' ) . join ( '' ) ;
ckey = Buffer . from ( keydata , 'hex' ) ;
2021-09-10 16:04:10 -04:00
if ( ckey . length != 80 ) { ckey = null ; loginCookie = args . loginkey ; }
2020-05-27 04:17:03 -04:00
} catch ( ex ) { console . log ( ex . message ) ; process . exit ( ) ; return ; }
2019-06-29 15:18:20 -04:00
}
2021-08-05 04:13:44 -04:00
settings . xxurl = url ;
2019-06-29 15:18:20 -04:00
if ( ckey != null ) {
var domainid = '' , username = 'admin' ;
2020-05-27 20:23:38 -04:00
if ( args . logindomain != null ) { domainid = args . logindomain ; }
2019-06-29 15:18:20 -04:00
if ( args . loginuser != null ) { username = args . loginuser ; }
2024-08-16 11:02:21 -04:00
url += ( url . indexOf ( '?key=' ) >= 0 ? '&auth=' : '?auth=' ) + encodeCookie ( { userid : 'user/' + domainid + '/' + username , domainid : domainid } , ckey ) ;
2020-04-20 16:31:01 -04:00
} else {
2020-05-27 20:23:38 -04:00
if ( args . logindomain != null ) { console . log ( "--logindomain can only be used along with --loginkey." ) ; process . exit ( ) ; return ; }
2024-08-16 11:02:21 -04:00
if ( loginCookie != null ) { url += ( url . indexOf ( '?key=' ) >= 0 ? '&auth=' : '?auth=' ) + loginCookie ; }
2019-06-29 15:18:20 -04:00
}
const ws = new WebSocket ( url , options ) ;
2021-09-11 00:10:01 -04:00
//console.log('Connecting to ' + url);
2019-06-28 21:31:18 -04:00
ws . on ( 'open' , function open ( ) {
2019-06-29 15:18:20 -04:00
//console.log('Connected.');
2019-06-28 21:31:18 -04:00
switch ( settings . cmd ) {
case 'serverinfo' : { break ; }
case 'userinfo' : { break ; }
2020-06-12 16:04:23 -04:00
case 'listusers' : { ws . send ( JSON . stringify ( { action : 'users' , responseid : 'meshctrl' } ) ) ; break ; }
2020-10-02 19:17:28 -04:00
case 'listusersessions' : { ws . send ( JSON . stringify ( { action : 'wssessioncount' , responseid : 'meshctrl' } ) ) ; break ; }
case 'removeallusersfromusergroup' :
case 'listusergroups' : { ws . send ( JSON . stringify ( { action : 'usergroups' , responseid : 'meshctrl' } ) ) ; break ; }
2020-06-12 16:04:23 -04:00
case 'listdevicegroups' : { ws . send ( JSON . stringify ( { action : 'meshes' , responseid : 'meshctrl' } ) ) ; break ; }
case 'listusersofdevicegroup' : { ws . send ( JSON . stringify ( { action : 'meshes' , responseid : 'meshctrl' } ) ) ; break ; }
2019-07-05 16:28:41 -04:00
case 'listdevices' : {
2021-07-24 14:28:55 -04:00
if ( args . details ) {
// Get list of devices with lots of details
2022-11-14 19:31:44 -05:00
ws . send ( JSON . stringify ( { action : 'getDeviceDetails' , type : ( args . csv ) ? 'csv' : 'json' } ) ) ;
2021-07-24 14:28:55 -04:00
} else if ( args . group ) {
2020-05-14 16:20:45 -04:00
ws . send ( JSON . stringify ( { action : 'nodes' , meshname : args . group , responseid : 'meshctrl' } ) ) ;
2020-04-16 16:18:45 -04:00
} else if ( args . id ) {
2020-05-14 16:20:45 -04:00
ws . send ( JSON . stringify ( { action : 'nodes' , meshid : args . id , responseid : 'meshctrl' } ) ) ;
2019-07-05 16:28:41 -04:00
} else {
ws . send ( JSON . stringify ( { action : 'meshes' } ) ) ;
2020-05-14 16:20:45 -04:00
ws . send ( JSON . stringify ( { action : 'nodes' , responseid : 'meshctrl' } ) ) ;
2019-07-05 16:28:41 -04:00
}
2020-05-14 16:20:45 -04:00
break ;
2019-07-05 16:28:41 -04:00
}
2021-02-02 21:01:09 -05:00
case 'listevents' : {
limit = null ;
2022-11-14 19:31:44 -05:00
if ( args . limit ) { limit = parseInt ( args . limit ) ; }
2021-02-02 21:01:09 -05:00
if ( ( typeof limit != 'number' ) || ( limit < 1 ) ) { limit = null ; }
var cmd = null ;
if ( args . userid ) {
cmd = { action : 'events' , user : args . userid , responseid : 'meshctrl' } ;
} else if ( args . id ) {
cmd = { action : 'events' , nodeid : args . id , responseid : 'meshctrl' } ;
} else {
cmd = { action : 'events' , responseid : 'meshctrl' } ;
}
if ( typeof limit == 'number' ) { cmd . limit = limit ; }
ws . send ( JSON . stringify ( cmd ) ) ;
break ;
}
2021-05-07 15:15:44 -04:00
case 'logintokens' : {
if ( args . add ) {
var cmd = { action : 'createLoginToken' , name : args . add , expire : 0 , responseid : 'meshctrl' } ;
if ( args . expire ) { cmd . expire = parseInt ( args . expire ) ; }
ws . send ( JSON . stringify ( cmd ) ) ;
} else {
var cmd = { action : 'loginTokens' , responseid : 'meshctrl' } ;
if ( args . remove ) { cmd . remove = [ args . remove ] ; }
ws . send ( JSON . stringify ( cmd ) ) ;
}
break ;
}
2019-06-29 15:18:20 -04:00
case 'adduser' : {
2020-12-09 19:34:40 -05:00
var siteadmin = getSiteAdminRights ( args ) ;
2019-06-30 14:34:27 -04:00
if ( args . randompass ) { args . pass = getRandomAmtPassword ( ) ; }
var op = { action : 'adduser' , username : args . user , pass : args . pass , responseid : 'meshctrl' } ;
2019-07-01 19:46:05 -04:00
if ( args . email ) { op . email = args . email ; if ( args . emailverified ) { op . emailVerified = true ; } }
2019-06-29 15:18:20 -04:00
if ( args . resetpass ) { op . resetNextLogin = true ; }
2020-12-09 19:34:40 -05:00
if ( siteadmin != - 1 ) { op . siteadmin = siteadmin ; }
2020-05-27 20:23:38 -04:00
if ( args . domain ) { op . domain = args . domain ; }
2020-12-09 19:34:40 -05:00
if ( args . phone === true ) { op . phone = '' ; }
if ( typeof args . phone == 'string' ) { op . phone = args . phone ; }
if ( typeof args . realname == 'string' ) { op . realname = args . realname ; }
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
case 'edituser' : {
var userid = args . userid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { userid = 'user/' + args . domain + '/' + userid ; }
var siteadmin = getSiteAdminRights ( args ) ;
var op = { action : 'edituser' , userid : userid , responseid : 'meshctrl' } ;
if ( args . email ) { op . email = args . email ; if ( args . emailverified ) { op . emailVerified = true ; } }
if ( args . resetpass ) { op . resetNextLogin = true ; }
if ( siteadmin != - 1 ) { op . siteadmin = siteadmin ; }
if ( args . domain ) { op . domain = args . domain ; }
if ( args . phone === true ) { op . phone = '' ; }
if ( typeof args . phone == 'string' ) { op . phone = args . phone ; }
if ( typeof args . realname == 'string' ) { op . realname = args . realname ; }
if ( args . realname === true ) { op . realname = '' ; }
2019-06-29 15:18:20 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
case 'removeuser' : {
2020-05-27 20:23:38 -04:00
var userid = args . userid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { userid = 'user/' + args . domain + '/' + userid ; }
ws . send ( JSON . stringify ( { action : 'deleteuser' , userid : userid , responseid : 'meshctrl' } ) ) ;
break ;
}
case 'addusergroup' : {
var op = { action : 'createusergroup' , name : args . name , desc : args . desc , responseid : 'meshctrl' } ;
if ( args . domain ) { op . domain = args . domain ; }
2019-06-30 14:34:27 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2020-05-27 20:23:38 -04:00
case 'removeusergroup' : {
var ugrpid = args . groupid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { ugrpid = 'ugrp/' + args . domain + '/' + ugrpid ; }
ws . send ( JSON . stringify ( { action : 'deleteusergroup' , ugrpid : ugrpid , responseid : 'meshctrl' } ) ) ;
break ;
}
2020-10-05 06:53:30 -04:00
case 'addtousergroup' : {
2020-10-02 19:17:28 -04:00
var ugrpid = args . groupid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { ugrpid = 'ugrp/' + args . domain + '/' + ugrpid ; }
2020-10-05 06:53:30 -04:00
// Add a user to a user group
if ( args . userid != null ) {
var userid = args . userid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { userid = 'user/' + args . domain + '/' + userid ; }
ws . send ( JSON . stringify ( { action : 'addusertousergroup' , ugrpid : ugrpid , usernames : [ userid . split ( '/' ) [ 2 ] ] , responseid : 'meshctrl' } ) ) ;
break ;
}
if ( ( args . id != null ) && ( args . id . startsWith ( 'user/' ) ) ) {
ws . send ( JSON . stringify ( { action : 'addusertousergroup' , ugrpid : ugrpid , usernames : [ args . id . split ( '/' ) [ 2 ] ] , responseid : 'meshctrl' } ) ) ;
break ;
}
var rights = 0 ;
if ( args . rights != null ) { rights = parseInt ( args . rights ) ; }
// Add a device group to a user group
if ( args . meshid != null ) {
var meshid = args . meshid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { meshid = 'mesh/' + args . domain + '/' + meshid ; }
ws . send ( JSON . stringify ( { action : 'addmeshuser' , meshid : meshid , userid : ugrpid , meshadmin : rights , responseid : 'meshctrl' } ) ) ;
break ;
}
if ( ( args . id != null ) && ( args . id . startsWith ( 'mesh/' ) ) ) {
ws . send ( JSON . stringify ( { action : 'addmeshuser' , meshid : args . id , userid : ugrpid , meshadmin : rights , responseid : 'meshctrl' } ) ) ;
break ;
}
// Add a device to a user group
if ( args . nodeid != null ) {
var nodeid = args . nodeid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { nodeid = 'node/' + args . domain + '/' + nodeid ; }
ws . send ( JSON . stringify ( { action : 'adddeviceuser' , nodeid : nodeid , userids : [ ugrpid ] , rights : rights , responseid : 'meshctrl' } ) ) ;
break ;
}
if ( ( args . id != null ) && ( args . id . startsWith ( 'node/' ) ) ) {
ws . send ( JSON . stringify ( { action : 'adddeviceuser' , nodeid : args . id , userids : [ ugrpid ] , rights : rights , responseid : 'meshctrl' } ) ) ;
break ;
}
2020-10-02 19:17:28 -04:00
break ;
}
2020-10-05 06:53:30 -04:00
case 'removefromusergroup' : {
2020-10-02 19:17:28 -04:00
var ugrpid = args . groupid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { ugrpid = 'ugrp/' + args . domain + '/' + ugrpid ; }
2020-10-05 06:53:30 -04:00
// Remove a user from a user group
if ( args . userid != null ) {
var userid = args . userid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { userid = 'user/' + args . domain + '/' + userid ; }
ws . send ( JSON . stringify ( { action : 'removeuserfromusergroup' , ugrpid : ugrpid , userid : userid , responseid : 'meshctrl' } ) ) ;
break ;
}
if ( ( args . id != null ) && ( args . id . startsWith ( 'user/' ) ) ) {
ws . send ( JSON . stringify ( { action : 'removeuserfromusergroup' , ugrpid : ugrpid , userid : args . id , responseid : 'meshctrl' } ) ) ;
break ;
}
// Remove a device group from a user group
if ( args . meshid != null ) {
var meshid = args . meshid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { meshid = 'mesh/' + args . domain + '/' + meshid ; }
ws . send ( JSON . stringify ( { action : 'removemeshuser' , meshid : meshid , userid : ugrpid , responseid : 'meshctrl' } ) ) ;
break ;
}
if ( ( args . id != null ) && ( args . id . startsWith ( 'mesh/' ) ) ) {
ws . send ( JSON . stringify ( { action : 'removemeshuser' , meshid : args . id , userid : ugrpid , responseid : 'meshctrl' } ) ) ;
break ;
}
// Remove a device from a user group
if ( args . nodeid != null ) {
var nodeid = args . nodeid ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { nodeid = 'node/' + args . domain + '/' + nodeid ; }
ws . send ( JSON . stringify ( { action : 'adddeviceuser' , nodeid : nodeid , userids : [ ugrpid ] , rights : 0 , responseid : 'meshctrl' , remove : true } ) ) ;
break ;
}
if ( ( args . id != null ) && ( args . id . startsWith ( 'node/' ) ) ) {
ws . send ( JSON . stringify ( { action : 'adddeviceuser' , nodeid : args . id , userids : [ ugrpid ] , rights : 0 , responseid : 'meshctrl' , remove : true } ) ) ;
break ;
}
2020-10-02 19:17:28 -04:00
break ;
}
2019-06-30 14:34:27 -04:00
case 'adddevicegroup' : {
var op = { action : 'createmesh' , meshname : args . name , meshtype : 2 , responseid : 'meshctrl' } ;
if ( args . desc ) { op . desc = args . desc ; }
if ( args . amtonly ) { op . meshtype = 1 ; }
2022-09-19 08:50:46 -04:00
if ( args . agentless ) { op . meshtype = 3 ; }
2020-10-05 20:12:19 -04:00
if ( args . features ) { op . flags = parseInt ( args . features ) ; }
if ( args . consent ) { op . consent = parseInt ( args . consent ) ; }
2019-06-30 14:34:27 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
case 'removedevicegroup' : {
2020-04-08 14:26:35 -04:00
var op = { action : 'deletemesh' , responseid : 'meshctrl' } ;
if ( args . id ) { op . meshid = args . id ; } else if ( args . group ) { op . meshname = args . group ; }
2019-06-30 14:34:27 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2024-10-25 05:34:16 -04:00
case 'addamtdevice' : {
var op = { action : 'addamtdevice' , amttls : 1 , responseid : 'meshctrl' } ;
if ( args . id ) { op . meshid = args . id ; }
if ( ( typeof args . devicename == 'string' ) && ( args . devicename != '' ) ) { op . devicename = args . devicename ; }
if ( ( typeof args . hostname == 'string' ) && ( args . hostname != '' ) ) { op . hostname = args . hostname ; }
if ( ( typeof args . user == 'string' ) && ( args . user != '' ) ) { op . amtusername = args . user ; }
if ( ( typeof args . pass == 'string' ) && ( args . pass != '' ) ) { op . amtpassword = args . pass ; }
if ( args . notls ) { op . amttls = 0 ; }
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
case 'addlocaldevice' : {
var op = { action : 'addlocaldevice' , type : 4 , responseid : 'meshctrl' } ;
if ( args . id ) { op . meshid = args . id ; }
if ( ( typeof args . devicename == 'string' ) && ( args . devicename != '' ) ) { op . devicename = args . devicename ; }
if ( ( typeof args . hostname == 'string' ) && ( args . hostname != '' ) ) { op . hostname = args . hostname ; }
if ( args . type ) {
if ( ( typeof parseInt ( args . type ) != 'number' ) || isNaN ( parseInt ( args . type ) ) ) { console . log ( "Invalid type." ) ; process . exit ( 1 ) ; return ; }
op . type = args . type ;
}
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2020-07-24 15:32:43 -04:00
case 'editdevicegroup' : {
var op = { action : 'editmesh' , responseid : 'meshctrl' } ;
if ( args . id ) { op . meshid = args . id ; } else if ( args . group ) { op . meshidname = args . group ; }
if ( ( typeof args . name == 'string' ) && ( args . name != '' ) ) { op . meshname = args . name ; }
if ( args . desc === true ) { op . desc = "" ; } else if ( typeof args . desc == 'string' ) { op . desc = args . desc ; }
if ( args . invitecodes === true ) { op . invite = "*" ; } else if ( typeof args . invitecodes == 'string' ) {
var invitecodes = args . invitecodes . split ( ',' ) , invitecodes2 = [ ] ;
for ( var i in invitecodes ) { if ( invitecodes [ i ] . length > 0 ) { invitecodes2 . push ( invitecodes [ i ] ) ; } }
if ( invitecodes2 . length > 0 ) {
op . invite = { codes : invitecodes2 , flags : 0 } ;
if ( args . backgroundonly === true ) { op . invite . flags = 2 ; }
else if ( args . interactiveonly === true ) { op . invite . flags = 1 ; }
}
}
if ( args . flags != null ) {
var flags = parseInt ( args . flags ) ;
if ( typeof flags == 'number' ) { op . flags = flags ; }
}
if ( args . consent != null ) {
var consent = parseInt ( args . consent ) ;
if ( typeof consent == 'number' ) { op . consent = consent ; }
}
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2020-04-16 11:46:53 -04:00
case 'movetodevicegroup' : {
2022-11-14 19:31:44 -05:00
var op = { action : 'changeDeviceMesh' , responseid : 'meshctrl' , nodeids : [ args . devid ] } ;
2020-04-16 11:46:53 -04:00
if ( args . id ) { op . meshid = args . id ; } else if ( args . group ) { op . meshname = args . group ; }
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2019-07-01 17:44:26 -04:00
case 'addusertodevicegroup' : {
var meshrights = 0 ;
if ( args . fullrights ) { meshrights = 0xFFFFFFFF ; }
if ( args . editgroup ) { meshrights |= 1 ; }
if ( args . manageusers ) { meshrights |= 2 ; }
if ( args . managedevices ) { meshrights |= 4 ; }
if ( args . remotecontrol ) { meshrights |= 8 ; }
if ( args . agentconsole ) { meshrights |= 16 ; }
if ( args . serverfiles ) { meshrights |= 32 ; }
if ( args . wakedevices ) { meshrights |= 64 ; }
if ( args . notes ) { meshrights |= 128 ; }
if ( args . desktopviewonly ) { meshrights |= 256 ; }
if ( args . noterminal ) { meshrights |= 512 ; }
if ( args . nofiles ) { meshrights |= 1024 ; }
if ( args . noamt ) { meshrights |= 2048 ; }
if ( args . limiteddesktop ) { meshrights |= 4096 ; }
2020-04-01 16:15:14 -04:00
if ( args . limitedevents ) { meshrights |= 8192 ; }
if ( args . chatnotify ) { meshrights |= 16384 ; }
if ( args . uninstall ) { meshrights |= 32768 ; }
2020-04-08 14:26:35 -04:00
var op = { action : 'addmeshuser' , usernames : [ args . userid ] , meshadmin : meshrights , responseid : 'meshctrl' } ;
if ( args . id ) { op . meshid = args . id ; } else if ( args . group ) { op . meshname = args . group ; }
2019-07-01 17:44:26 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
case 'removeuserfromdevicegroup' : {
2020-04-08 14:26:35 -04:00
var op = { action : 'removemeshuser' , userid : args . userid , responseid : 'meshctrl' } ;
if ( args . id ) { op . meshid = args . id ; } else if ( args . group ) { op . meshname = args . group ; }
2019-07-01 17:44:26 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2020-04-01 16:15:14 -04:00
case 'addusertodevice' : {
var meshrights = 0 ;
if ( args . fullrights ) { meshrights = ( 8 + 16 + 32 + 64 + 128 + 16384 + 32768 ) ; }
if ( args . remotecontrol ) { meshrights |= 8 ; }
if ( args . agentconsole ) { meshrights |= 16 ; }
if ( args . serverfiles ) { meshrights |= 32 ; }
if ( args . wakedevices ) { meshrights |= 64 ; }
if ( args . notes ) { meshrights |= 128 ; }
if ( args . desktopviewonly ) { meshrights |= 256 ; }
if ( args . noterminal ) { meshrights |= 512 ; }
if ( args . nofiles ) { meshrights |= 1024 ; }
if ( args . noamt ) { meshrights |= 2048 ; }
if ( args . limiteddesktop ) { meshrights |= 4096 ; }
if ( args . limitedevents ) { meshrights |= 8192 ; }
if ( args . chatnotify ) { meshrights |= 16384 ; }
if ( args . uninstall ) { meshrights |= 32768 ; }
var op = { action : 'adddeviceuser' , nodeid : args . id , usernames : [ args . userid ] , rights : meshrights , responseid : 'meshctrl' } ;
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
case 'removeuserfromdevice' : {
2020-05-14 15:10:25 -04:00
var op = { action : 'adddeviceuser' , nodeid : args . id , usernames : [ args . userid ] , rights : 0 , remove : true , responseid : 'meshctrl' } ;
2020-04-01 16:15:14 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2019-07-05 16:28:41 -04:00
case 'sendinviteemail' : {
2020-04-07 19:13:02 -04:00
var op = { action : 'inviteAgent' , email : args . email , name : '' , os : '0' , responseid : 'meshctrl' }
if ( args . id ) { op . meshid = args . id ; } else if ( args . group ) { op . meshname = args . group ; }
if ( args . name ) { op . name = args . name ; }
if ( args . message ) { op . msg = args . message ; }
2019-07-05 16:28:41 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2019-09-23 14:45:10 -04:00
case 'generateinvitelink' : {
2020-04-07 19:13:02 -04:00
var op = { action : 'createInviteLink' , expire : args . hours , flags : 0 , responseid : 'meshctrl' }
if ( args . id ) { op . meshid = args . id ; } else if ( args . group ) { op . meshname = args . group ; }
2021-05-10 12:37:41 -04:00
if ( args . flags ) { op . flags = args . flags ; }
2019-09-23 14:45:10 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2019-06-30 14:34:27 -04:00
case 'broadcast' : {
var op = { action : 'userbroadcast' , msg : args . msg , responseid : 'meshctrl' } ;
2020-11-05 05:27:39 -05:00
if ( args . user ) { op . userid = args . user ; }
2019-06-29 15:18:20 -04:00
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2020-03-20 18:47:22 -04:00
case 'showevents' : {
console . log ( 'Connected. Press ctrl-c to end.' ) ;
break ;
}
2020-05-02 16:49:56 -04:00
case 'deviceinfo' : {
2021-03-11 14:51:07 -05:00
settings . deviceinfocount = 4 ;
ws . send ( JSON . stringify ( { action : 'nodes' } ) ) ;
ws . send ( JSON . stringify ( { action : 'getnetworkinfo' , nodeid : args . id , responseid : 'meshctrl' } ) ) ;
ws . send ( JSON . stringify ( { action : 'lastconnect' , nodeid : args . id , responseid : 'meshctrl' } ) ) ;
2020-05-02 16:49:56 -04:00
ws . send ( JSON . stringify ( { action : 'getsysinfo' , nodeid : args . id , nodeinfo : true , responseid : 'meshctrl' } ) ) ;
break ;
}
2022-11-14 19:31:44 -05:00
case 'removedevice' : {
var op = { action : 'removedevices' , nodeids : [ args . id ] , responseid : 'meshctrl' } ;
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2021-06-11 15:48:43 -04:00
case 'editdevice' : {
var op = { action : 'changedevice' , nodeid : args . id , responseid : 'meshctrl' } ;
if ( typeof args . name == 'string' ) { op . name = args . name ; }
if ( typeof args . name == 'number' ) { op . name = '' + args . name ; }
if ( args . desc ) { if ( args . desc === true ) { op . desc = '' ; } else if ( typeof args . desc == 'string' ) { op . desc = args . desc ; } else if ( typeof args . desc == 'number' ) { op . desc = '' + args . desc ; } }
if ( args . tags ) { if ( args . tags === true ) { op . tags = '' ; } else if ( typeof args . tags == 'string' ) { op . tags = args . tags . split ( ',' ) ; } else if ( typeof args . tags == 'number' ) { op . tags = '' + args . tags ; } }
if ( args . icon ) { op . icon = parseInt ( args . icon ) ; if ( ( typeof op . icon != 'number' ) || isNaN ( op . icon ) || ( op . icon < 1 ) || ( op . icon > 8 ) ) { console . log ( "Icon must be between 1 and 8." ) ; process . exit ( 1 ) ; return ; } }
if ( args . consent ) { op . consent = parseInt ( args . consent ) ; if ( ( typeof op . consent != 'number' ) || isNaN ( op . consent ) || ( op . consent < 1 ) ) { console . log ( "Invalid consent flags." ) ; process . exit ( 1 ) ; return ; } }
ws . send ( JSON . stringify ( op ) ) ;
break ;
}
2020-07-13 15:25:14 -04:00
case 'runcommand' : {
2020-09-29 16:20:08 -04:00
var runAsUser = 0 ;
if ( args . runasuser ) { runAsUser = 1 ; } else if ( args . runasuseronly ) { runAsUser = 2 ; }
2024-03-14 10:33:02 -04:00
var reply = false ;
if ( args . reply ) { reply = true ; }
ws . send ( JSON . stringify ( { action : 'runcommands' , nodeids : [ args . id ] , type : ( ( args . powershell ) ? 2 : 0 ) , cmds : args . run , responseid : 'meshctrl' , runAsUser : runAsUser , reply : reply } ) ) ;
2020-07-13 15:25:14 -04:00
break ;
}
2020-07-16 17:08:06 -04:00
case 'shell' :
case 'upload' :
case 'download' : {
2020-07-13 18:06:45 -04:00
ws . send ( "{\"action\":\"authcookie\"}" ) ;
break ;
}
2021-01-05 21:29:23 -05:00
case 'devicepower' : {
var nodes = args . id . split ( ',' ) ;
if ( args . wake ) {
// Wake operation
ws . send ( JSON . stringify ( { action : 'wakedevices' , nodeids : nodes , responseid : 'meshctrl' } ) ) ;
} else if ( args . off ) {
// Power off operation
ws . send ( JSON . stringify ( { action : 'poweraction' , nodeids : nodes , actiontype : 2 , responseid : 'meshctrl' } ) ) ;
} else if ( args . reset ) {
// Reset operation
ws . send ( JSON . stringify ( { action : 'poweraction' , nodeids : nodes , actiontype : 3 , responseid : 'meshctrl' } ) ) ;
} else if ( args . sleep ) {
// Sleep operation
ws . send ( JSON . stringify ( { action : 'poweraction' , nodeids : nodes , actiontype : 4 , responseid : 'meshctrl' } ) ) ;
2022-05-24 17:37:48 -04:00
} else if ( args . amton ) {
// Intel AMT Power on operation
ws . send ( JSON . stringify ( { action : 'poweraction' , nodeids : nodes , actiontype : 302 , responseid : 'meshctrl' } ) ) ;
} else if ( args . amtoff ) {
// Intel AMT Power off operation
ws . send ( JSON . stringify ( { action : 'poweraction' , nodeids : nodes , actiontype : 308 , responseid : 'meshctrl' } ) ) ;
} else if ( args . amtreset ) {
// Intel AMT Power reset operation
ws . send ( JSON . stringify ( { action : 'poweraction' , nodeids : nodes , actiontype : 310 , responseid : 'meshctrl' } ) ) ;
2021-01-05 21:29:23 -05:00
} else {
console . log ( 'No power operation specified.' ) ;
process . exit ( 1 ) ;
}
break ;
}
2021-08-05 04:13:44 -04:00
case 'agentdownload' : {
// Download an agent
var u = settings . xxurl . replace ( 'wss://' , 'https://' ) . replace ( '/control.ashx' , '/meshagents' ) ;
if ( u . indexOf ( '?' ) > 0 ) { u += '&' ; } else { u += '?' ; }
u += 'id=' + args . type + '&meshid=' + args . id ;
2024-05-28 13:24:39 -04:00
if ( args . installflags ) {
if ( ( typeof parseInt ( args . installflags ) != 'number' ) || isNaN ( parseInt ( args . installflags ) ) || ( parseInt ( args . installflags ) < 0 ) || ( parseInt ( args . installflags ) > 2 ) ) { console . log ( "Invalid Installflags." ) ; process . exit ( 1 ) ; return ; }
u += '&installflags=' + args . installflags ;
}
2021-08-05 04:13:44 -04:00
const options = { rejectUnauthorized : false , checkServerIdentity : onVerifyServer }
const fs = require ( 'fs' ) ;
const https = require ( 'https' ) ;
var downloadSize = 0 ;
const req = https . request ( u , options , function ( res ) {
if ( res . statusCode != 200 ) {
console . log ( 'Download error, statusCode: ' + res . statusCode ) ;
process . exit ( 1 ) ;
} else {
// Agent the agent filename
var agentFileName = 'meshagent' ;
if ( ( res . headers ) && ( res . headers [ 'content-disposition' ] != null ) ) {
var i = res . headers [ 'content-disposition' ] . indexOf ( 'filename=\"' ) ;
if ( i >= 0 ) {
agentFileName = res . headers [ 'content-disposition' ] . substring ( i + 10 ) ;
i = agentFileName . indexOf ( '\"' ) ;
if ( i >= 0 ) { agentFileName = agentFileName . substring ( 0 , i ) ; }
}
}
// Check if this file already exists
if ( fs . existsSync ( agentFileName ) ) { console . log ( 'File \"' + agentFileName + '\" already exists.' ) ; process . exit ( 1 ) ; }
var fd = fs . openSync ( agentFileName , 'w' ) ; // Open the file for writing
res . on ( 'data' , function ( d ) {
downloadSize += d . length ;
fs . writeSync ( fd , d ) ; // Save to file
} ) ;
res . on ( 'end' , function ( d ) {
fs . closeSync ( fd ) ; // Close file
console . log ( 'Downloaded ' + downloadSize + ' byte(s) to \"' + agentFileName + '\"' ) ;
process . exit ( 1 ) ;
} ) ;
}
} )
req . on ( 'error' , function ( error ) { console . error ( error ) ; process . exit ( 1 ) ; } )
req . end ( )
break ;
}
2024-11-26 11:46:14 -05:00
case 'webrelay' : {
var protocol = null ;
if ( args . type != null ) {
if ( args . type == 'http' ) {
protocol = 1 ;
} else if ( args . type == 'https' ) {
protocol = 2 ;
} else {
console . log ( "Unknown protocol type: " + args . type ) ; process . exit ( 1 ) ;
}
}
var port = null ;
if ( typeof args . port == 'number' ) {
if ( ( args . port < 1 ) || ( args . port > 65535 ) ) { console . log ( "Port number must be between 1 and 65535." ) ; process . exit ( 1 ) ; }
port = args . port ;
} else if ( protocol == 1 ) {
port = 80 ;
} else if ( protocol == 2 ) {
port = 443 ;
}
ws . send ( JSON . stringify ( { action : 'webrelay' , nodeid : args . id , port : port , appid : protocol , responseid : 'meshctrl' } ) ) ;
break ;
}
2021-01-05 20:02:24 -05:00
case 'devicesharing' : {
if ( args . add ) {
if ( args . add . length == 0 ) { console . log ( "Invalid guest name." ) ; process . exit ( 1 ) ; }
// Sharing type, desktop or terminal
2021-10-08 21:35:30 -04:00
var p = 0 ;
2021-01-05 20:02:24 -05:00
if ( args . type != null ) {
2021-10-08 21:35:30 -04:00
var shareTypes = args . type . toLowerCase ( ) . split ( ',' ) ;
2024-03-02 16:56:14 -05:00
for ( var i in shareTypes ) { if ( ( shareTypes [ i ] != 'terminal' ) && ( shareTypes [ i ] != 'desktop' ) && ( shareTypes [ i ] != 'files' ) && ( shareTypes [ i ] != 'http' ) && ( shareTypes [ i ] != 'https' ) ) { console . log ( "Unknown sharing type: " + shareTypes [ i ] ) ; process . exit ( 1 ) ; } }
2021-10-08 21:35:30 -04:00
if ( shareTypes . indexOf ( 'terminal' ) >= 0 ) { p |= 1 ; }
if ( shareTypes . indexOf ( 'desktop' ) >= 0 ) { p |= 2 ; }
if ( shareTypes . indexOf ( 'files' ) >= 0 ) { p |= 4 ; }
2024-03-02 16:56:14 -05:00
if ( shareTypes . indexOf ( 'http' ) >= 0 ) { p |= 8 ; }
if ( shareTypes . indexOf ( 'https' ) >= 0 ) { p |= 16 ; }
2021-01-05 20:02:24 -05:00
}
2021-10-08 21:35:30 -04:00
if ( p == 0 ) { p = 2 ; } // Desktop
// Sharing view only
var viewOnly = false ;
if ( args . viewonly ) { viewOnly = true ; }
2021-01-05 20:02:24 -05:00
// User consent
var consent = 0 ;
if ( args . consent == null ) {
2021-10-08 21:35:30 -04:00
if ( ( p & 1 ) != 0 ) { consent = 0x0002 ; } // Terminal notify
if ( ( p & 2 ) != 0 ) { consent = 0x0001 ; } // Desktop notify
if ( ( p & 4 ) != 0 ) { consent = 0x0004 ; } // Files notify
2021-01-05 20:02:24 -05:00
} else {
2021-10-08 21:35:30 -04:00
if ( typeof args . consent == 'string' ) {
var flagStrs = args . consent . split ( ',' ) ;
for ( var i in flagStrs ) {
var flagStr = flagStrs [ i ] . toLowerCase ( ) ;
if ( flagStr == 'none' ) { consent = 0 ; }
else if ( flagStr == 'notify' ) {
if ( ( p & 1 ) != 0 ) { consent |= 0x0002 ; } // Terminal notify
if ( ( p & 2 ) != 0 ) { consent |= 0x0001 ; } // Desktop notify
if ( ( p & 4 ) != 0 ) { consent |= 0x0004 ; } // Files notify
} else if ( flagStr == 'prompt' ) {
if ( ( p & 1 ) != 0 ) { consent |= 0x0010 ; } // Terminal prompt
if ( ( p & 2 ) != 0 ) { consent |= 0x0008 ; } // Desktop prompt
if ( ( p & 4 ) != 0 ) { consent |= 0x0020 ; } // Files prompt
} else if ( flagStr == 'bar' ) {
if ( ( p & 2 ) != 0 ) { consent |= 0x0040 ; } // Desktop toolbar
} else { console . log ( "Unknown consent type." ) ; process . exit ( 1 ) ; return ; }
}
2021-01-05 20:02:24 -05:00
}
}
2024-03-02 16:56:14 -05:00
var port = null ;
// Set Port Number if http or https
if ( ( p & 8 ) || ( p & 16 ) ) {
if ( typeof args . port == 'number' ) {
if ( ( args . port < 1 ) || ( args . port > 65535 ) ) { console . log ( "Port number must be between 1 and 65535." ) ; process . exit ( 1 ) ; }
port = args . port ;
} else if ( ( p & 8 ) ) {
port = 80 ;
} else if ( ( p & 16 ) ) {
port = 443 ;
}
}
2021-01-05 20:02:24 -05:00
// Start and end time
2021-10-08 21:35:30 -04:00
var start = null , end = null ;
2021-01-05 20:02:24 -05:00
if ( args . start ) { start = Math . floor ( Date . parse ( args . start ) / 1000 ) ; end = start + ( 60 * 60 ) ; }
2021-10-08 21:35:30 -04:00
if ( args . end ) { if ( start == null ) { start = Math . floor ( Date . now ( ) / 1000 ) } end = Math . floor ( Date . parse ( args . end ) / 1000 ) ; if ( end <= start ) { console . log ( "End time must be ahead of start time." ) ; process . exit ( 1 ) ; return ; } }
if ( args . duration ) { if ( start == null ) { start = Math . floor ( Date . now ( ) / 1000 ) } end = start + parseInt ( args . duration * 60 ) ; }
2021-01-05 20:02:24 -05:00
2022-01-17 14:38:49 -05:00
// Recurring
var recurring = 0 ;
if ( args . daily ) { recurring = 1 ; } else if ( args . weekly ) { recurring = 2 ; }
if ( recurring > 0 ) {
if ( args . end != null ) { console . log ( "End time can't be specified for recurring shares, use --duration only." ) ; process . exit ( 1 ) ; return ; }
if ( args . duration == null ) { args . duration = 60 ; } else { args . duration = parseInt ( args . duration ) ; }
if ( start == null ) { start = Math . floor ( Date . now ( ) / 1000 ) }
if ( ( typeof args . duration != 'number' ) || ( args . duration < 1 ) ) { console . log ( "Invalid duration value." ) ; process . exit ( 1 ) ; return ; }
// Recurring sharing
2024-03-02 16:56:14 -05:00
ws . send ( JSON . stringify ( { action : 'createDeviceShareLink' , nodeid : args . id , guestname : args . add , p : p , consent : consent , start : start , expire : args . duration , recurring : recurring , viewOnly : viewOnly , port : port , responseid : 'meshctrl' } ) ) ;
2021-10-08 21:35:30 -04:00
} else {
2022-01-17 14:38:49 -05:00
if ( ( start == null ) && ( end == null ) ) {
// Unlimited sharing
2024-03-02 16:56:14 -05:00
ws . send ( JSON . stringify ( { action : 'createDeviceShareLink' , nodeid : args . id , guestname : args . add , p : p , consent : consent , expire : 0 , viewOnly : viewOnly , port : port , responseid : 'meshctrl' } ) ) ;
2022-01-17 14:38:49 -05:00
} else {
// Time limited sharing
2024-03-02 16:56:14 -05:00
ws . send ( JSON . stringify ( { action : 'createDeviceShareLink' , nodeid : args . id , guestname : args . add , p : p , consent : consent , start : start , end : end , viewOnly : viewOnly , port : port , responseid : 'meshctrl' } ) ) ;
2022-01-17 14:38:49 -05:00
}
2021-10-08 21:35:30 -04:00
}
2021-01-05 20:02:24 -05:00
} else if ( args . remove ) {
ws . send ( JSON . stringify ( { action : 'removeDeviceShare' , nodeid : args . id , publicid : args . remove , responseid : 'meshctrl' } ) ) ;
} else {
ws . send ( JSON . stringify ( { action : 'deviceShares' , nodeid : args . id , responseid : 'meshctrl' } ) ) ;
}
break ;
}
2020-08-17 18:01:25 -04:00
case 'deviceopenurl' : {
ws . send ( JSON . stringify ( { action : 'msg' , type : 'openUrl' , nodeid : args . id , url : args . openurl , responseid : 'meshctrl' } ) ) ;
break ;
}
case 'devicemessage' : {
2024-01-12 17:46:12 -05:00
ws . send ( JSON . stringify ( { action : 'msg' , type : 'messagebox' , nodeid : args . id , title : args . title ? args . title : "MeshCentral" , msg : args . msg , timeout : args . timeout ? args . timeout : 120000 , responseid : 'meshctrl' } ) ) ;
2020-08-17 18:01:25 -04:00
break ;
}
case 'devicetoast' : {
ws . send ( JSON . stringify ( { action : 'toast' , nodeids : [ args . id ] , title : args . title ? args . title : "MeshCentral" , msg : args . msg , responseid : 'meshctrl' } ) ) ;
break ;
}
2024-01-25 04:44:27 -05:00
case 'groupmessage' : {
ws . send ( JSON . stringify ( { action : 'nodes' , meshid : args . id , responseid : 'meshctrl' } ) ) ;
break ;
}
case 'grouptoast' : {
ws . send ( JSON . stringify ( { action : 'nodes' , meshid : args . id , responseid : 'meshctrl' } ) ) ;
break ;
}
2023-03-30 08:07:30 -04:00
case 'report' : {
2023-03-30 08:10:04 -04:00
var reporttype = 1 ;
switch ( args . type ) {
case 'traffic' :
reporttype = 2 ;
break ;
case 'logins' :
reporttype = 3 ;
break ;
case 'db' :
reporttype = 4 ;
break ;
}
var reportgroupby = 1 ;
if ( args . groupby ) {
reportgroupby = args . groupby === 'device' ? 2 : args . groupby === 'day' ? 3 : 1 ;
}
var start = null , end = null ;
if ( args . start ) {
start = Math . floor ( Date . parse ( args . start ) / 1000 ) ;
} else {
start = reportgroupby === 3 ? Math . round ( new Date ( ) . getTime ( ) / 1000 ) - ( 168 * 3600 ) : Math . round ( new Date ( ) . getTime ( ) / 1000 ) - ( 24 * 3600 ) ;
}
if ( args . end ) {
end = Math . floor ( Date . parse ( args . end ) / 1000 ) ;
} else {
end = Math . round ( new Date ( ) . getTime ( ) / 1000 ) ;
}
if ( end <= start ) { console . log ( "End time must be ahead of start time." ) ; process . exit ( 1 ) ; return ; }
2023-03-30 08:07:30 -04:00
ws . send ( JSON . stringify ( { action : 'report' , type : reporttype , groupBy : reportgroupby , devGroup : args . devicegroup || null , start , end , tz : Intl . DateTimeFormat ( ) . resolvedOptions ( ) . timeZone , tf : new Date ( ) . getTimezoneOffset ( ) , showTraffic : args . hasOwnProperty ( 'showtraffic' ) , l : 'en' , responseid : 'meshctrl' } ) ) ;
break ;
}
2019-06-28 21:31:18 -04:00
}
} ) ;
2020-12-09 19:34:40 -05:00
function getSiteAdminRights ( args ) {
var siteadmin = - 1 ;
if ( typeof args . rights == 'number' ) {
siteadmin = args . rights ;
} else if ( typeof args . rights == 'string' ) {
siteadmin = 0 ;
var srights = args . rights . toLowerCase ( ) . split ( ',' ) ;
if ( srights . indexOf ( 'full' ) != - 1 ) { siteadmin = 0xFFFFFFFF ; }
if ( srights . indexOf ( 'none' ) != - 1 ) { siteadmin = 0x00000000 ; }
2024-04-09 08:31:00 -04:00
if ( srights . indexOf ( 'backup' ) != - 1 || srights . indexOf ( 'serverbackup' ) != - 1 ) { siteadmin |= 0x00000001 ; }
2020-12-09 19:34:40 -05:00
if ( srights . indexOf ( 'manageusers' ) != - 1 ) { siteadmin |= 0x00000002 ; }
2024-04-09 08:31:00 -04:00
if ( srights . indexOf ( 'restore' ) != - 1 || srights . indexOf ( 'serverrestore' ) != - 1 ) { siteadmin |= 0x00000004 ; }
2020-12-09 19:34:40 -05:00
if ( srights . indexOf ( 'fileaccess' ) != - 1 ) { siteadmin |= 0x00000008 ; }
2024-04-09 08:31:00 -04:00
if ( srights . indexOf ( 'update' ) != - 1 || srights . indexOf ( 'serverupdate' ) != - 1 ) { siteadmin |= 0x00000010 ; }
2020-12-09 19:34:40 -05:00
if ( srights . indexOf ( 'locked' ) != - 1 ) { siteadmin |= 0x00000020 ; }
if ( srights . indexOf ( 'nonewgroups' ) != - 1 ) { siteadmin |= 0x00000040 ; }
if ( srights . indexOf ( 'notools' ) != - 1 ) { siteadmin |= 0x00000080 ; }
if ( srights . indexOf ( 'usergroups' ) != - 1 ) { siteadmin |= 0x00000100 ; }
if ( srights . indexOf ( 'recordings' ) != - 1 ) { siteadmin |= 0x00000200 ; }
if ( srights . indexOf ( 'locksettings' ) != - 1 ) { siteadmin |= 0x00000400 ; }
if ( srights . indexOf ( 'allevents' ) != - 1 ) { siteadmin |= 0x00000800 ; }
2024-04-09 08:31:00 -04:00
if ( srights . indexOf ( 'nonewdevices' ) != - 1 ) { siteadmin |= 0x00001000 ; }
2020-12-09 19:34:40 -05:00
}
if ( args . siteadmin ) { siteadmin = 0xFFFFFFFF ; }
if ( args . manageusers ) { if ( siteadmin == - 1 ) { siteadmin = 0 ; } siteadmin |= 2 ; }
if ( args . fileaccess ) { if ( siteadmin == - 1 ) { siteadmin = 0 ; } siteadmin |= 8 ; }
if ( args . serverupdate ) { if ( siteadmin == - 1 ) { siteadmin = 0 ; } siteadmin |= 16 ; }
if ( args . locked ) { if ( siteadmin == - 1 ) { siteadmin = 0 ; } siteadmin |= 32 ; }
if ( args . nonewgroups ) { if ( siteadmin == - 1 ) { siteadmin = 0 ; } siteadmin |= 64 ; }
if ( args . notools ) { if ( siteadmin == - 1 ) { siteadmin = 0 ; } siteadmin |= 128 ; }
return siteadmin ;
}
2022-11-14 19:31:44 -05:00
ws . on ( 'close' , function ( ) { process . exit ( ) ; } ) ;
2020-04-16 01:27:03 -04:00
ws . on ( 'error' , function ( err ) {
if ( err . code == 'ENOTFOUND' ) { console . log ( 'Unable to resolve ' + url ) ; }
else if ( err . code == 'ECONNREFUSED' ) { console . log ( 'Unable to connect to ' + url ) ; }
2022-03-28 14:53:11 -04:00
else { console . log ( 'Unable to connect to ' + url ) ; }
2020-04-16 01:27:03 -04:00
process . exit ( ) ;
} ) ;
2019-06-28 21:31:18 -04:00
ws . on ( 'message' , function incoming ( rawdata ) {
var data = null ;
try { data = JSON . parse ( rawdata ) ; } catch ( ex ) { }
if ( data == null ) { console . log ( 'Unable to parse data: ' + rawdata ) ; }
2020-11-05 05:27:39 -05:00
if ( settings . cmd == 'showevents' ) {
if ( args . filter == null ) {
// Display all events
console . log ( JSON . stringify ( data , null , 2 ) ) ;
} else {
// Display select events
var filters = args . filter . split ( ',' ) ;
if ( typeof data . event == 'object' ) {
if ( filters . indexOf ( data . event . action ) >= 0 ) { console . log ( JSON . stringify ( data , null , 2 ) + '\r\n' ) ; }
} else {
if ( filters . indexOf ( data . action ) >= 0 ) { console . log ( JSON . stringify ( data , null , 2 ) + '\r\n' ) ; }
}
}
return ;
}
2019-06-28 21:31:18 -04:00
switch ( data . action ) {
case 'serverinfo' : { // SERVERINFO
2020-07-13 18:06:45 -04:00
settings . currentDomain = data . serverinfo . domain ;
2019-06-28 21:31:18 -04:00
if ( settings . cmd == 'serverinfo' ) {
if ( args . json ) {
console . log ( JSON . stringify ( data . serverinfo , ' ' , 2 ) ) ;
} else {
for ( var i in data . serverinfo ) { console . log ( i + ':' , data . serverinfo [ i ] ) ; }
}
process . exit ( ) ;
}
break ;
}
2021-02-02 21:01:09 -05:00
case 'events' : {
if ( settings . cmd == 'listevents' ) {
if ( args . raw ) {
// RAW JSON
console . log ( JSON . stringify ( data . events ) ) ;
} else if ( args . json ) {
// Formatted JSON
console . log ( JSON . stringify ( data . events , null , 2 ) ) ;
} else {
if ( ( args . id == null ) && ( args . userid == null ) ) {
// CSV format
console . log ( "time,type,action,nodeid,userid,msg" ) ;
for ( var i in data . events ) {
var x = [ ] ;
x . push ( data . events [ i ] . time ) ;
x . push ( data . events [ i ] . etype ) ;
x . push ( data . events [ i ] . action ) ;
x . push ( data . events [ i ] . nodeid ) ;
x . push ( data . events [ i ] . userid ) ;
x . push ( data . events [ i ] . msg ) ;
console . log ( csvFormatArray ( x ) ) ;
}
} else if ( args . id != null ) {
// CSV format
console . log ( "time,type,action,userid,msg" ) ;
for ( var i in data . events ) {
var x = [ ] ;
x . push ( data . events [ i ] . time ) ;
x . push ( data . events [ i ] . etype ) ;
x . push ( data . events [ i ] . action ) ;
x . push ( data . events [ i ] . userid ) ;
x . push ( data . events [ i ] . msg ) ;
console . log ( csvFormatArray ( x ) ) ;
}
} else if ( args . userid != null ) {
// CSV format
console . log ( "time,type,action,nodeid,msg" ) ;
for ( var i in data . events ) {
var x = [ ] ;
x . push ( data . events [ i ] . time ) ;
x . push ( data . events [ i ] . etype ) ;
x . push ( data . events [ i ] . action ) ;
x . push ( data . events [ i ] . nodeid ) ;
x . push ( data . events [ i ] . msg ) ;
console . log ( csvFormatArray ( x ) ) ;
}
}
}
process . exit ( ) ;
}
break ;
}
2020-07-16 17:08:06 -04:00
case 'authcookie' : { // SHELL, UPLOAD, DOWNLOAD
if ( ( settings . cmd == 'shell' ) || ( settings . cmd == 'upload' ) || ( settings . cmd == 'download' ) ) {
var protocol = 1 ; // Terminal
if ( ( settings . cmd == 'upload' ) || ( settings . cmd == 'download' ) ) { protocol = 5 ; } // Files
2020-07-13 18:06:45 -04:00
if ( ( args . id . split ( '/' ) != 3 ) && ( settings . currentDomain != null ) ) { args . id = 'node/' + settings . currentDomain + '/' + args . id ; }
var id = getRandomHex ( 6 ) ;
2020-07-16 17:08:06 -04:00
ws . send ( JSON . stringify ( { action : 'msg' , nodeid : args . id , type : 'tunnel' , usage : 1 , value : '*/meshrelay.ashx?p=' + protocol + '&nodeid=' + args . id + '&id=' + id + '&rauth=' + data . rcookie , responseid : 'meshctrl' } ) ) ;
connectTunnel ( url . replace ( '/control.ashx' , '/meshrelay.ashx?browser=1&p=' + protocol + '&nodeid=' + args . id + '&id=' + id + '&auth=' + data . cookie ) ) ;
2020-07-13 18:06:45 -04:00
}
break ;
}
2021-01-05 20:02:24 -05:00
case 'deviceShares' : { // DEVICESHARING
if ( data . result != null ) {
console . log ( data . result ) ;
} else {
if ( ( data . deviceShares == null ) || ( data . deviceShares . length == 0 ) ) {
console . log ( 'No device sharing links for this device.' ) ;
} else {
2021-10-08 21:35:30 -04:00
if ( args . json ) {
console . log ( data . deviceShares ) ;
} else {
for ( var i in data . deviceShares ) {
var share = data . deviceShares [ i ] ;
var shareType = [ ] ;
if ( ( share . p & 1 ) != 0 ) { shareType . push ( "Terminal" ) ; }
if ( ( share . p & 2 ) != 0 ) { if ( share . viewOnly ) { shareType . push ( "View Only Desktop" ) ; } else { shareType . push ( "Desktop" ) ; } }
if ( ( share . p & 4 ) != 0 ) { shareType . push ( "Files" ) ; }
shareType = shareType . join ( ' + ' ) ;
if ( shareType == '' ) { shareType = "Unknown" ; }
var consent = [ ] ;
if ( ( share . consent & 0x0001 ) != 0 ) { consent . push ( "Desktop Notify" ) ; }
if ( ( share . consent & 0x0008 ) != 0 ) { consent . push ( "Desktop Prompt" ) ; }
if ( ( share . consent & 0x0040 ) != 0 ) { consent . push ( "Desktop Connection Toolbar" ) ; }
if ( ( share . consent & 0x0002 ) != 0 ) { consent . push ( "Terminal Notify" ) ; }
if ( ( share . consent & 0x0010 ) != 0 ) { consent . push ( "Terminal Prompt" ) ; }
if ( ( share . consent & 0x0004 ) != 0 ) { consent . push ( "Files Notify" ) ; }
if ( ( share . consent & 0x0020 ) != 0 ) { consent . push ( "Files Prompt" ) ; }
console . log ( '----------' ) ;
console . log ( 'Identifier: ' + share . publicid ) ;
console . log ( 'Type: ' + shareType ) ;
console . log ( 'UserId: ' + share . userid ) ;
console . log ( 'Guest Name: ' + share . guestName ) ;
console . log ( 'User Consent: ' + consent . join ( ', ' ) ) ;
if ( share . startTime ) { console . log ( 'Start Time: ' + new Date ( share . startTime ) . toLocaleString ( ) ) ; }
if ( share . expireTime ) { console . log ( 'Expire Time: ' + new Date ( share . expireTime ) . toLocaleString ( ) ) ; }
2022-01-17 14:38:49 -05:00
if ( share . duration ) { console . log ( 'Duration: ' + share . duration + ' minute' + ( ( share . duration > 1 ) ? 's' : '' ) ) ; }
if ( share . recurring == 1 ) { console . log ( 'Recurring: ' + 'Daily' ) ; }
if ( share . recurring == 2 ) { console . log ( 'Recurring: ' + 'Weekly' ) ; }
2021-10-08 21:35:30 -04:00
console . log ( 'URL: ' + share . url ) ;
}
2021-01-05 20:02:24 -05:00
}
}
}
process . exit ( ) ;
break ;
}
2019-06-28 21:31:18 -04:00
case 'userinfo' : { // USERINFO
if ( settings . cmd == 'userinfo' ) {
if ( args . json ) {
console . log ( JSON . stringify ( data . userinfo , ' ' , 2 ) ) ;
} else {
for ( var i in data . userinfo ) { console . log ( i + ':' , data . userinfo [ i ] ) ; }
}
process . exit ( ) ;
}
break ;
}
2020-05-02 16:49:56 -04:00
case 'getsysinfo' : { // DEVICEINFO
if ( settings . cmd == 'deviceinfo' ) {
2021-03-11 14:51:07 -05:00
settings . sysinfo = ( data . result ) ? null : data ;
if ( -- settings . deviceinfocount == 0 ) { displayDeviceInfo ( settings . sysinfo , settings . lastconnect , settings . networking , settings . nodes ) ; process . exit ( ) ; }
2020-05-02 16:49:56 -04:00
}
break ;
}
case 'lastconnect' : {
if ( settings . cmd == 'deviceinfo' ) {
2021-03-11 14:51:07 -05:00
settings . lastconnect = ( data . result ) ? null : data ;
if ( -- settings . deviceinfocount == 0 ) { displayDeviceInfo ( settings . sysinfo , settings . lastconnect , settings . networking , settings . nodes ) ; process . exit ( ) ; }
2020-05-02 16:49:56 -04:00
}
break ;
}
case 'getnetworkinfo' : {
if ( settings . cmd == 'deviceinfo' ) {
settings . networking = ( data . result ) ? null : data ;
2021-03-11 14:51:07 -05:00
if ( -- settings . deviceinfocount == 0 ) { displayDeviceInfo ( settings . sysinfo , settings . lastconnect , settings . networking , settings . nodes ) ; process . exit ( ) ; }
2020-05-02 16:49:56 -04:00
}
break ;
}
2020-07-13 18:06:45 -04:00
case 'msg' : // SHELL
2020-08-17 18:01:25 -04:00
case 'toast' : // TOAST
2019-06-30 14:34:27 -04:00
case 'adduser' : // ADDUSER
2020-12-09 19:34:40 -05:00
case 'edituser' : // EDITUSER
2024-10-25 05:34:16 -04:00
case 'addamtdevice' : // ADDAMTDEVICE
case 'addlocaldevice' : // ADDLOCALDEVICE
2022-11-14 19:31:44 -05:00
case 'removedevices' : // REMOVEDEVICE
2021-06-11 15:48:43 -04:00
case 'changedevice' : // EDITDEVICE
2019-06-30 14:34:27 -04:00
case 'deleteuser' : // REMOVEUSER
case 'createmesh' : // ADDDEVICEGROUP
case 'deletemesh' : // REMOVEDEVICEGROUP
2020-07-24 15:32:43 -04:00
case 'editmesh' : // EDITDEVICEGROUP
2021-01-05 21:29:23 -05:00
case 'wakedevices' :
2020-04-16 11:46:53 -04:00
case 'changeDeviceMesh' :
2019-07-01 17:44:26 -04:00
case 'addmeshuser' : //
case 'removemeshuser' : //
2021-01-05 21:29:23 -05:00
case 'wakedevices' : //
2019-09-23 14:45:10 -04:00
case 'inviteAgent' : //
2020-04-01 16:15:14 -04:00
case 'adddeviceuser' : //
2020-05-27 20:23:38 -04:00
case 'createusergroup' : //
case 'deleteusergroup' : //
2020-07-13 15:25:14 -04:00
case 'runcommands' :
2021-01-05 21:29:23 -05:00
case 'poweraction' :
2020-10-02 19:17:28 -04:00
case 'addusertousergroup' :
case 'removeuserfromusergroup' :
2021-01-05 20:02:24 -05:00
case 'removeDeviceShare' :
2019-06-30 14:34:27 -04:00
case 'userbroadcast' : { // BROADCAST
2021-01-05 15:12:38 -05:00
if ( ( settings . cmd == 'shell' ) || ( settings . cmd == 'upload' ) || ( settings . cmd == 'download' ) ) return ;
2020-10-02 19:17:28 -04:00
if ( ( settings . multiresponse != null ) && ( settings . multiresponse > 1 ) ) { settings . multiresponse -- ; break ; }
2019-06-30 14:34:27 -04:00
if ( data . responseid == 'meshctrl' ) {
if ( data . meshid ) { console . log ( data . result , data . meshid ) ; }
else if ( data . userid ) { console . log ( data . result , data . userid ) ; }
else console . log ( data . result ) ;
process . exit ( ) ;
}
break ;
}
2021-10-08 22:03:51 -04:00
case 'createDeviceShareLink' :
2024-11-26 11:46:14 -05:00
case 'webrelay' :
2021-10-08 22:03:51 -04:00
if ( data . result == 'OK' ) {
if ( data . publicid ) { console . log ( 'ID: ' + data . publicid ) ; }
console . log ( 'URL: ' + data . url ) ;
} else {
console . log ( data . result ) ;
}
process . exit ( ) ;
break ;
2019-09-23 14:45:10 -04:00
case 'createInviteLink' :
if ( data . responseid == 'meshctrl' ) {
if ( data . url ) { console . log ( data . url ) ; }
else console . log ( data . result ) ;
process . exit ( ) ;
}
break ;
2020-05-14 16:20:45 -04:00
case 'wssessioncount' : { // LIST USER SESSIONS
if ( args . json ) {
console . log ( JSON . stringify ( data . wssessions , ' ' , 2 ) ) ;
} else {
for ( var i in data . wssessions ) { console . log ( i + ', ' + ( ( data . wssessions [ i ] > 1 ) ? ( data . wssessions [ i ] + ' sessions.' ) : ( "1 session." ) ) ) ; }
}
process . exit ( ) ;
break ;
}
2020-05-27 20:23:38 -04:00
case 'usergroups' : { // LIST USER GROUPS
2020-10-02 18:27:46 -04:00
if ( settings . cmd == 'listusergroups' ) {
if ( args . json ) {
console . log ( JSON . stringify ( data . ugroups , ' ' , 2 ) ) ;
} else {
for ( var i in data . ugroups ) {
var x = i + ', ' + data . ugroups [ i ] . name ;
if ( data . ugroups [ i ] . desc && ( data . ugroups [ i ] . desc != '' ) ) { x += ', ' + data . ugroups [ i ] . desc ; }
console . log ( x ) ;
2020-10-05 06:53:30 -04:00
var mesh = [ ] , user = [ ] , node = [ ] ;
if ( data . ugroups [ i ] . links != null ) { for ( var j in data . ugroups [ i ] . links ) { if ( j . startsWith ( 'mesh/' ) ) { mesh . push ( j ) ; } if ( j . startsWith ( 'user/' ) ) { user . push ( j ) ; } if ( j . startsWith ( 'node/' ) ) { node . push ( j ) ; } } }
2022-11-14 19:31:44 -05:00
console . log ( ' Users:' ) ;
2020-10-05 06:53:30 -04:00
if ( user . length > 0 ) { for ( var j in user ) { console . log ( ' ' + user [ j ] ) ; } } else { console . log ( ' (None)' ) ; }
2022-11-14 19:31:44 -05:00
console . log ( ' Device Groups:' ) ;
2020-10-05 06:53:30 -04:00
if ( mesh . length > 0 ) { for ( var j in mesh ) { console . log ( ' ' + mesh [ j ] + ', ' + data . ugroups [ i ] . links [ mesh [ j ] ] . rights ) ; } } else { console . log ( ' (None)' ) ; }
2022-11-14 19:31:44 -05:00
console . log ( ' Devices:' ) ;
2020-10-05 06:53:30 -04:00
if ( node . length > 0 ) { for ( var j in node ) { console . log ( ' ' + node [ j ] + ', ' + data . ugroups [ i ] . links [ node [ j ] ] . rights ) ; } } else { console . log ( ' (None)' ) ; }
2020-10-02 18:27:46 -04:00
}
2020-05-27 20:23:38 -04:00
}
2020-10-02 18:27:46 -04:00
process . exit ( ) ;
2020-10-02 19:17:28 -04:00
} else if ( settings . cmd == 'removeallusersfromusergroup' ) {
var ugrpid = args . groupid , exit = false ;
if ( ( args . domain != null ) && ( userid . indexOf ( '/' ) < 0 ) ) { ugrpid = 'ugrp/' + args . domain + '/' + ugrpid ; }
var ugroup = data . ugroups [ ugrpid ] ;
if ( ugroup == null ) {
console . log ( 'User group not found.' ) ;
exit = true ;
} else {
var usercount = 0 ;
if ( ugroup . links ) {
for ( var i in ugroup . links ) {
if ( i . startsWith ( 'user/' ) ) {
usercount ++ ;
ws . send ( JSON . stringify ( { action : 'removeuserfromusergroup' , ugrpid : ugrpid , userid : i , responseid : 'meshctrl' } ) ) ;
console . log ( 'Removing ' + i ) ;
}
}
}
if ( usercount == 0 ) { console . log ( 'No users in this user group.' ) ; exit = true ; } else { settings . multiresponse = usercount ; }
}
if ( exit ) { process . exit ( ) ; }
2020-05-27 20:23:38 -04:00
}
break ;
}
2019-06-28 21:31:18 -04:00
case 'users' : { // LISTUSERS
2020-06-12 16:04:23 -04:00
if ( data . result ) { console . log ( data . result ) ; process . exit ( ) ; return ; }
2019-12-12 14:44:03 -05:00
if ( args . filter ) {
// Filter the list of users
var filters = args . filter . toLowerCase ( ) . split ( ',' ) ;
var filteredusers = [ ] ;
for ( var i in data . users ) {
var ok = false ;
if ( ( filters . indexOf ( '2fa' ) >= 0 ) && ( ( data . users [ i ] . otphkeys != null ) || ( data . users [ i ] . otpkeys != null ) || ( data . users [ i ] . otpsecret != null ) ) ) { ok = true ; }
if ( ( filters . indexOf ( 'no2fa' ) >= 0 ) && ( ( data . users [ i ] . otphkeys == null ) && ( data . users [ i ] . otpkeys == null ) && ( data . users [ i ] . otpsecret == null ) ) ) { ok = true ; }
if ( ok == true ) { filteredusers . push ( data . users [ i ] ) ; }
}
data . users = filteredusers ;
}
2019-06-28 21:31:18 -04:00
if ( args . json ) {
console . log ( JSON . stringify ( data . users , ' ' , 2 ) ) ;
} else {
2019-06-29 15:18:20 -04:00
if ( args . idexists ) { for ( var i in data . users ) { const u = data . users [ i ] ; if ( ( u . _id == args . idexists ) || ( u . _id . split ( '/' ) [ 2 ] == args . idexists ) ) { console . log ( '1' ) ; process . exit ( ) ; return ; } } console . log ( '0' ) ; process . exit ( ) ; return ; }
if ( args . nameexists ) { for ( var i in data . users ) { const u = data . users [ i ] ; if ( u . name == args . nameexists ) { console . log ( u . _id ) ; process . exit ( ) ; return ; } } process . exit ( ) ; return ; }
console . log ( 'id, name, email\r\n---------------' ) ;
2019-06-28 21:31:18 -04:00
for ( var i in data . users ) {
const u = data . users [ i ] ;
var t = "\"" + u . _id . split ( '/' ) [ 2 ] + "\", \"" + u . name + "\"" ;
if ( u . email != null ) { t += ", \"" + u . email + "\"" ; }
console . log ( t ) ;
}
}
process . exit ( ) ;
break ;
}
2019-07-05 16:28:41 -04:00
case 'nodes' : {
2021-03-11 14:51:07 -05:00
if ( settings . cmd == 'deviceinfo' ) {
settings . nodes = ( data . result ) ? null : data ;
if ( -- settings . deviceinfocount == 0 ) { displayDeviceInfo ( settings . sysinfo , settings . lastconnect , settings . networking , settings . nodes ) ; process . exit ( ) ; }
}
2019-07-05 16:28:41 -04:00
if ( ( settings . cmd == 'listdevices' ) && ( data . responseid == 'meshctrl' ) ) {
if ( ( data . result != null ) && ( data . result != 'ok' ) ) {
console . log ( data . result ) ;
} else {
2021-07-27 13:47:41 -04:00
// Filter devices based on device id.
2021-03-14 17:18:50 -04:00
if ( args . filterid ) {
var filteridSplit = args . filterid . split ( ',' ) , filters = [ ] ;
for ( var i in filteridSplit ) {
var f = filteridSplit [ i ] . trim ( ) ;
var g = f . split ( '/' ) ; // If there is any / in the id, just grab the last part.
if ( g . length > 0 ) { f = g [ g . length - 1 ] ; }
if ( f != '' ) { filters . push ( f ) ; }
}
if ( filters . length > 0 ) {
for ( var mid in data . nodes ) {
var filteredNodes = [ ] ;
for ( var nid in data . nodes [ mid ] ) {
var n = data . nodes [ mid ] [ nid ] , match = false ;
for ( var f in filters ) { if ( n . _id . indexOf ( filters [ f ] ) >= 0 ) { match = true ; } }
if ( match ) { filteredNodes . push ( n ) ; }
}
data . nodes [ mid ] = filteredNodes ;
}
}
}
2021-09-07 16:32:31 -04:00
// Filter devices based on filter string
if ( args . filter != null ) {
for ( var meshid in data . nodes ) {
for ( var d in data . nodes [ meshid ] ) { data . nodes [ meshid ] [ d ] . meshid = meshid ; }
2024-05-14 15:49:08 -04:00
data . nodes [ meshid ] = parseSearchOrInput ( data . nodes [ meshid ] , args . filter . toString ( ) . toLowerCase ( ) ) ;
2021-09-07 16:32:31 -04:00
}
}
2020-10-05 19:47:30 -04:00
if ( args . csv ) {
// Return a flat list
var nodecount = 0 ;
for ( var i in data . nodes ) {
var devicesInMesh = data . nodes [ i ] ;
for ( var j in devicesInMesh ) {
var n = devicesInMesh [ j ] ;
nodecount ++ ;
2022-01-20 16:52:08 -05:00
if ( settings . xmeshes ) {
console . log ( '\"' + settings . xmeshes [ i ] . _id . split ( '/' ) [ 2 ] + '\",\"' + settings . xmeshes [ i ] . name . split ( '\"' ) . join ( '' ) + '\",\"' + n . _id . split ( '/' ) [ 2 ] + '\",\"' + n . name . split ( '\"' ) . join ( '' ) + '\",' + ( n . icon ? n . icon : 0 ) + ',' + ( n . conn ? n . conn : 0 ) + ',' + ( n . pwr ? n . pwr : 0 ) ) ;
} else {
console . log ( '\"' + n . _id . split ( '/' ) [ 2 ] + '\",\"' + n . name . split ( '\"' ) . join ( '' ) + '\",' + ( n . icon ? n . icon : 0 ) + ',' + ( n . conn ? n . conn : 0 ) + ',' + ( n . pwr ? n . pwr : 0 ) ) ;
}
2020-10-05 19:47:30 -04:00
}
}
if ( nodecount == 0 ) { console . log ( 'None' ) ; }
} else if ( args . count ) {
2019-07-05 16:28:41 -04:00
// Return how many devices are in this group
var nodes = [ ] ;
for ( var i in data . nodes ) { var devicesInMesh = data . nodes [ i ] ; for ( var j in devicesInMesh ) { nodes . push ( devicesInMesh [ j ] ) ; } }
console . log ( nodes . length ) ;
} else if ( args . json ) {
// Return all devices in JSON format
var nodes = [ ] ;
2022-11-14 19:31:44 -05:00
2021-07-27 13:47:41 -04:00
for ( var i in data . nodes ) {
const devicesInMesh = data . nodes [ i ] ;
for ( var j in devicesInMesh ) {
devicesInMesh [ j ] . meshid = i ; // Add device group id
if ( settings . xmeshes && settings . xmeshes [ i ] && settings . xmeshes [ i ] . name ) { devicesInMesh [ j ] . groupname = settings . xmeshes [ i ] . name ; } // Add device group name
nodes . push ( devicesInMesh [ j ] ) ;
}
}
2019-07-05 16:28:41 -04:00
console . log ( JSON . stringify ( nodes , ' ' , 2 ) ) ;
} else {
// Display the list of nodes in text format
2020-04-20 16:31:01 -04:00
var nodecount = 0 ;
2019-07-05 16:28:41 -04:00
for ( var i in data . nodes ) {
var devicesInMesh = data . nodes [ i ] ;
2021-09-07 16:32:31 -04:00
if ( devicesInMesh . length > 0 ) {
if ( settings . xmeshes ) { console . log ( '\r\nDevice group: \"' + settings . xmeshes [ i ] . name . split ( '\"' ) . join ( '' ) + '\"' ) ; }
console . log ( 'id, name, icon, conn, pwr\r\n-------------------------' ) ;
for ( var j in devicesInMesh ) {
var n = devicesInMesh [ j ] ;
nodecount ++ ;
console . log ( '\"' + n . _id . split ( '/' ) [ 2 ] + '\", \"' + n . name . split ( '\"' ) . join ( '' ) + '\", ' + ( n . icon ? n . icon : 0 ) + ', ' + ( n . conn ? n . conn : 0 ) + ', ' + ( n . pwr ? n . pwr : 0 ) ) ;
}
2019-07-05 16:28:41 -04:00
}
}
2020-04-20 16:31:01 -04:00
if ( nodecount == 0 ) { console . log ( 'None' ) ; }
2019-07-05 16:28:41 -04:00
}
}
process . exit ( ) ;
}
2024-01-25 04:44:27 -05:00
if ( ( settings . cmd == 'groupmessage' ) && ( data . responseid == 'meshctrl' ) ) {
if ( ( data . nodes != null ) ) {
for ( var i in data . nodes ) {
for ( let index = 0 ; index < data . nodes [ i ] . length ; index ++ ) {
const element = data . nodes [ i ] [ index ] ;
ws . send ( JSON . stringify ( { action : 'msg' , type : 'messagebox' , nodeid : element . _id , title : args . title ? args . title : "MeshCentral" , msg : args . msg , timeout : args . timeout ? args . timeout : 120000 } ) ) ;
}
}
}
setTimeout ( function ( ) { console . log ( 'ok' ) ; process . exit ( ) ; } , 1000 ) ;
}
if ( ( settings . cmd == 'grouptoast' ) && ( data . responseid == 'meshctrl' ) ) {
if ( data . nodes != null ) {
for ( var i in data . nodes ) {
var nodes = [ ] ;
for ( let index = 0 ; index < data . nodes [ i ] . length ; index ++ ) {
const element = data . nodes [ i ] [ index ] ;
nodes . push ( element . _id ) ;
}
ws . send ( JSON . stringify ( { action : 'toast' , nodeids : nodes , title : args . title ? args . title : "MeshCentral" , msg : args . msg , responseid : 'meshctrl' } ) ) ;
}
}
}
2019-07-05 16:28:41 -04:00
break ;
}
2019-06-30 14:34:27 -04:00
case 'meshes' : { // LISTDEVICEGROUPS
2019-07-05 16:28:41 -04:00
if ( settings . cmd == 'listdevices' ) {
// Store the list of device groups for later use
settings . xmeshes = { }
for ( var i in data . meshes ) { settings . xmeshes [ data . meshes [ i ] . _id ] = data . meshes [ i ] ; }
} else if ( settings . cmd == 'listdevicegroups' ) {
if ( args . json ) {
2020-07-24 13:56:28 -04:00
// If asked, add the MeshID hex encoding to the JSON.
if ( args . hex ) { for ( var i in data . meshes ) { data . meshes [ i ] . _idhex = '0x' + Buffer . from ( data . meshes [ i ] . _id . split ( '/' ) [ 2 ] . replace ( /\@/g , '+' ) . replace ( /\$/g , '/' ) , 'base64' ) . toString ( 'hex' ) . toUpperCase ( ) ; } }
2019-07-05 16:28:41 -04:00
console . log ( JSON . stringify ( data . meshes , ' ' , 2 ) ) ;
} else {
if ( args . idexists ) { for ( var i in data . meshes ) { const u = data . meshes [ i ] ; if ( ( u . _id == args . idexists ) || ( u . _id . split ( '/' ) [ 2 ] == args . idexists ) ) { console . log ( '1' ) ; process . exit ( ) ; return ; } } console . log ( '0' ) ; process . exit ( ) ; return ; }
if ( args . nameexists ) { for ( var i in data . meshes ) { const u = data . meshes [ i ] ; if ( u . name == args . nameexists ) { console . log ( u . _id ) ; process . exit ( ) ; return ; } } process . exit ( ) ; return ; }
2019-06-29 15:18:20 -04:00
2019-07-05 16:28:41 -04:00
console . log ( 'id, name\r\n---------------' ) ;
for ( var i in data . meshes ) {
const m = data . meshes [ i ] ;
2020-07-15 18:12:01 -04:00
var mid = m . _id . split ( '/' ) [ 2 ] ;
2020-07-16 17:08:06 -04:00
if ( args . hex ) { mid = '0x' + Buffer . from ( mid . replace ( /\@/g , '+' ) . replace ( /\$/g , '/' ) , 'base64' ) . toString ( 'hex' ) . toUpperCase ( ) ; }
2020-07-15 18:12:01 -04:00
var t = "\"" + mid + "\", \"" + m . name + "\"" ;
2019-07-05 16:28:41 -04:00
console . log ( t ) ;
}
}
process . exit ( ) ;
} else if ( settings . cmd == 'listusersofdevicegroup' ) {
2019-06-28 21:31:18 -04:00
for ( var i in data . meshes ) {
const m = data . meshes [ i ] ;
2019-07-05 16:28:41 -04:00
var mid = m . _id . split ( '/' ) [ 2 ] ;
if ( mid == args . id ) {
if ( args . json ) {
console . log ( JSON . stringify ( m . links , ' ' , 2 ) ) ;
} else {
console . log ( 'userid, rights\r\n---------------' ) ;
for ( var l in m . links ) {
var rights = m . links [ l ] . rights ;
var rightsstr = [ ] ;
if ( rights == 4294967295 ) { rightsstr = [ 'FullAdministrator' ] ; } else {
if ( rights & 1 ) { rightsstr . push ( 'EditMesh' ) ; }
if ( rights & 2 ) { rightsstr . push ( 'ManageUsers' ) ; }
if ( rights & 4 ) { rightsstr . push ( 'ManageComputers' ) ; }
if ( rights & 8 ) { rightsstr . push ( 'RemoteControl' ) ; }
if ( rights & 16 ) { rightsstr . push ( 'AgentConsole' ) ; }
if ( rights & 32 ) { rightsstr . push ( 'ServerFiles' ) ; }
if ( rights & 64 ) { rightsstr . push ( 'WakeDevice' ) ; }
if ( rights & 128 ) { rightsstr . push ( 'SetNotes' ) ; }
if ( rights & 256 ) { rightsstr . push ( 'RemoteViewOnly' ) ; }
if ( rights & 512 ) { rightsstr . push ( 'NoTerminal' ) ; }
if ( rights & 1024 ) { rightsstr . push ( 'NoFiles' ) ; }
if ( rights & 2048 ) { rightsstr . push ( 'NoAMT' ) ; }
if ( rights & 4096 ) { rightsstr . push ( 'DesktopLimitedInput' ) ; }
}
console . log ( l . split ( '/' ) [ 2 ] + ', ' + rightsstr . join ( ', ' ) ) ;
}
}
process . exit ( ) ;
return ;
}
2019-06-28 21:31:18 -04:00
}
2019-07-05 16:28:41 -04:00
console . log ( 'Group id not found' ) ;
process . exit ( ) ;
2019-06-28 21:31:18 -04:00
}
break ;
}
2019-06-29 15:18:20 -04:00
case 'close' : {
if ( data . cause == 'noauth' ) {
if ( data . msg == 'tokenrequired' ) {
console . log ( 'Authentication token required, use --token [number].' ) ;
2024-08-16 11:02:21 -04:00
} else if ( data . msg == 'nokey' ) {
console . log ( 'URL key is invalid or missing, please specify ?key=xxx in url' ) ;
2019-06-29 15:18:20 -04:00
} else {
2020-05-27 04:17:03 -04:00
if ( ( args . loginkeyfile != null ) || ( args . loginkey != null ) ) {
console . log ( 'Invalid login, check the login key and that this computer has the correct time.' ) ;
} else {
console . log ( 'Invalid login.' ) ;
}
2019-06-29 15:18:20 -04:00
}
}
process . exit ( ) ;
break ;
}
2021-05-07 15:15:44 -04:00
case 'createLoginToken' : {
if ( data . result != null ) {
console . log ( data . result ) ;
process . exit ( ) ;
} else {
2022-05-18 16:13:09 -04:00
if ( args . json ) {
console . log ( data ) ;
} else {
console . log ( "New login token created." ) ;
if ( data . name ) { console . log ( "Token name: " + data . name ) ; }
if ( data . created ) { console . log ( "Created: " + new Date ( data . created ) . toLocaleString ( ) ) ; }
if ( data . expire ) { console . log ( "Expire: " + new Date ( data . expire ) . toLocaleString ( ) ) ; }
if ( data . tokenUser ) { console . log ( "Username: " + data . tokenUser ) ; }
if ( data . tokenPass ) { console . log ( "Password: " + data . tokenPass ) ; }
}
2021-05-07 15:15:44 -04:00
}
2022-05-18 16:13:09 -04:00
process . exit ( ) ;
2021-05-07 15:15:44 -04:00
break ;
}
case 'loginTokens' : {
if ( args . json ) {
console . log ( data . loginTokens ) ;
} else {
console . log ( "Name Username Expire" ) ;
console . log ( "-------------------------------------------------------------------------------------" ) ;
if ( data . loginTokens . length == 0 ) {
console . log ( "No login tokens" ) ;
} else {
for ( var i in data . loginTokens ) {
var t = data . loginTokens [ i ] ;
var e = ( t . expire == 0 ) ? "Unlimited" : new Date ( t . expire ) . toLocaleString ( ) ;
console . log ( padString ( t . name , 28 ) + padString ( t . tokenUser , 28 ) + e ) ;
}
}
}
process . exit ( ) ;
break ;
}
2021-07-24 14:28:55 -04:00
case 'getDeviceDetails' : {
console . log ( data . data ) ;
process . exit ( ) ;
}
2023-03-30 08:10:04 -04:00
case 'report' : {
console . log ( 'group,' + data . data . columns . flatMap ( c => c . id ) . join ( ',' ) ) ;
Object . keys ( data . data . groups ) . forEach ( gk => {
data . data . groups [ gk ] . entries . forEach ( e => {
console . log ( gk + ',' + Object . values ( e ) . join ( ',' ) ) ;
} ) ;
} ) ;
2023-03-30 08:07:30 -04:00
process . exit ( ) ;
2023-03-30 08:10:04 -04:00
}
2019-06-30 14:34:27 -04:00
default : { break ; }
2019-06-28 21:31:18 -04:00
}
//console.log('Data', data);
//setTimeout(function timeout() { ws.send(Date.now()); }, 500);
} ) ;
2019-06-29 15:18:20 -04:00
}
2021-05-07 15:15:44 -04:00
// String padding function
function padString ( str , pad ) {
var xpad = ' ' ;
if ( str . length >= pad ) return str ; return str + xpad . substring ( 0 , pad - str . length )
}
2021-09-07 16:32:31 -04:00
function parseSearchAndInput ( nodes , x ) {
var s = x . split ( ' ' + "and" + ' ' ) , r = null ;
for ( var i in s ) {
var r2 = getDevicesThatMatchFilter ( nodes , s [ i ] ) ;
if ( r == null ) { r = r2 ; } else { var r3 = [ ] ; for ( var j in r2 ) { if ( r . indexOf ( r2 [ j ] ) >= 0 ) { r3 . push ( r2 [ j ] ) ; } } r = r3 ; }
}
return r ;
}
function parseSearchOrInput ( nodes , x ) {
var s = x . split ( ' ' + "or" + ' ' ) , r = null ;
for ( var i in s ) { var r2 = parseSearchAndInput ( nodes , s [ i ] ) ; if ( r == null ) { r = r2 ; } else { for ( var j in r2 ) { if ( r . indexOf ( r2 [ j ] >= 0 ) ) { r . push ( r2 [ j ] ) ; } } } }
return r ;
}
function getDevicesThatMatchFilter ( nodes , x ) {
var r = [ ] ;
var userSearch = null , ipSearch = null , groupSearch = null , tagSearch = null , agentTagSearch = null , wscSearch = null , osSearch = null , amtSearch = null , descSearch = null ;
if ( x . startsWith ( "user:" . toLowerCase ( ) ) ) { userSearch = x . substring ( "user:" . length ) ; }
else if ( x . startsWith ( "u:" . toLowerCase ( ) ) ) { userSearch = x . substring ( "u:" . length ) ; }
else if ( x . startsWith ( "ip:" . toLowerCase ( ) ) ) { ipSearch = x . substring ( "ip:" . length ) ; }
else if ( x . startsWith ( "group:" . toLowerCase ( ) ) ) { groupSearch = x . substring ( "group:" . length ) ; }
else if ( x . startsWith ( "g:" . toLowerCase ( ) ) ) { groupSearch = x . substring ( "g:" . length ) ; }
else if ( x . startsWith ( "tag:" . toLowerCase ( ) ) ) { tagSearch = x . substring ( "tag:" . length ) ; }
else if ( x . startsWith ( "t:" . toLowerCase ( ) ) ) { tagSearch = x . substring ( "t:" . length ) ; }
else if ( x . startsWith ( "atag:" . toLowerCase ( ) ) ) { agentTagSearch = x . substring ( "atag:" . length ) ; }
else if ( x . startsWith ( "a:" . toLowerCase ( ) ) ) { agentTagSearch = x . substring ( "a:" . length ) ; }
else if ( x . startsWith ( "os:" . toLowerCase ( ) ) ) { osSearch = x . substring ( "os:" . length ) ; }
else if ( x . startsWith ( "amt:" . toLowerCase ( ) ) ) { amtSearch = x . substring ( "amt:" . length ) ; }
else if ( x . startsWith ( "desc:" . toLowerCase ( ) ) ) { descSearch = x . substring ( "desc:" . length ) ; }
else if ( x == 'wsc:ok' ) { wscSearch = 1 ; }
else if ( x == 'wsc:noav' ) { wscSearch = 2 ; }
else if ( x == 'wsc:noupdate' ) { wscSearch = 3 ; }
else if ( x == 'wsc:nofirewall' ) { wscSearch = 4 ; }
else if ( x == 'wsc:any' ) { wscSearch = 5 ; }
if ( x == '' ) {
// No search
for ( var d in nodes ) { r . push ( nodes [ d ] ) ; }
} else if ( ipSearch != null ) {
// IP address search
for ( var d in nodes ) { if ( ( nodes [ d ] . ip != null ) && ( nodes [ d ] . ip . indexOf ( ipSearch ) >= 0 ) ) { r . push ( nodes [ d ] ) ; } }
} else if ( groupSearch != null ) {
// Group filter
if ( settings . xmeshes ) { for ( var d in nodes ) { if ( settings . xmeshes [ nodes [ d ] . meshid ] . name . toLowerCase ( ) . indexOf ( groupSearch ) >= 0 ) { r . push ( nodes [ d ] ) ; } } }
} else if ( tagSearch != null ) {
// Tag filter
for ( var d in nodes ) {
2021-09-15 22:12:10 -04:00
if ( ( nodes [ d ] . tags == null ) && ( tagSearch == '' ) ) { r . push ( d ) ; }
else if ( nodes [ d ] . tags != null ) { for ( var j in nodes [ d ] . tags ) { if ( nodes [ d ] . tags [ j ] . toLowerCase ( ) == tagSearch ) { r . push ( d ) ; break ; } } }
2021-09-07 16:32:31 -04:00
}
} else if ( agentTagSearch != null ) {
// Agent Tag filter
for ( var d in nodes ) {
if ( ( ( ( nodes [ d ] . agent != null ) && ( nodes [ d ] . agent . tag == null ) ) && ( agentTagSearch == '' ) ) || ( ( nodes [ d ] . agent != null ) && ( nodes [ d ] . agent . tag != null ) && ( nodes [ d ] . agent . tag . toLowerCase ( ) . indexOf ( agentTagSearch ) >= 0 ) ) ) { r . push ( nodes [ d ] ) ; } ;
}
} else if ( userSearch != null ) {
// User search
for ( var d in nodes ) {
if ( nodes [ d ] . users && nodes [ d ] . users . length > 0 ) { for ( var i in nodes [ d ] . users ) { if ( nodes [ d ] . users [ i ] . toLowerCase ( ) . indexOf ( userSearch ) >= 0 ) { r . push ( nodes [ d ] ) ; } } }
}
} else if ( osSearch != null ) {
// OS search
for ( var d in nodes ) { if ( ( nodes [ d ] . osdesc != null ) && ( nodes [ d ] . osdesc . toLowerCase ( ) . indexOf ( osSearch ) >= 0 ) ) { r . push ( nodes [ d ] ) ; } ; }
} else if ( amtSearch != null ) {
// Intel AMT search
for ( var d in nodes ) { if ( ( nodes [ d ] . intelamt != null ) && ( ( amtSearch == '' ) || ( nodes [ d ] . intelamt . state == amtSearch ) ) ) { r . push ( nodes [ d ] ) ; } }
} else if ( descSearch != null ) {
// Device description search
for ( var d in nodes ) { if ( ( nodes [ d ] . desc != null ) && ( nodes [ d ] . desc != '' ) && ( ( descSearch == '' ) || ( nodes [ d ] . desc . toLowerCase ( ) . indexOf ( descSearch ) >= 0 ) ) ) { r . push ( nodes [ d ] ) ; } }
} else if ( wscSearch != null ) {
// Windows Security Center
for ( var d in nodes ) {
if ( nodes [ d ] . wsc ) {
if ( ( wscSearch == 1 ) && ( nodes [ d ] . wsc . antiVirus == 'OK' ) && ( nodes [ d ] . wsc . autoUpdate == 'OK' ) && ( nodes [ d ] . wsc . firewall == 'OK' ) ) { r . push ( nodes [ d ] ) ; }
else if ( ( ( wscSearch == 2 ) || ( wscSearch == 5 ) ) && ( nodes [ d ] . wsc . antiVirus != 'OK' ) ) { r . push ( nodes [ d ] ) ; }
else if ( ( ( wscSearch == 3 ) || ( wscSearch == 5 ) ) && ( nodes [ d ] . wsc . autoUpdate != 'OK' ) ) { r . push ( nodes [ d ] ) ; }
else if ( ( ( wscSearch == 4 ) || ( wscSearch == 5 ) ) && ( nodes [ d ] . wsc . firewall != 'OK' ) ) { r . push ( nodes [ d ] ) ; }
}
}
} else if ( x == '*' ) {
// Star filter
for ( var d in nodes ) { if ( stars [ nodes [ d ] . _id ] == 1 ) { r . push ( nodes [ d ] ) ; } }
} else {
// Device name search
try {
var rs = x . split ( /\s+/ ) . join ( '|' ) , rx = new RegExp ( rs ) ; // In some cases (like +), this can throw an exception.
for ( var d in nodes ) {
//if (showRealNames) {
2022-11-14 19:31:44 -05:00
//if (nodes[d].rnamel != null && rx.test(nodes[d].rnamel.toLowerCase())) { r.push(nodes[d]); }
2021-09-07 16:32:31 -04:00
//} else {
2022-11-14 19:31:44 -05:00
if ( rx . test ( nodes [ d ] . name . toLowerCase ( ) ) ) { r . push ( nodes [ d ] ) ; }
2021-09-07 16:32:31 -04:00
//}
}
} catch ( ex ) { for ( var d in nodes ) { r . push ( nodes [ d ] ) ; } }
}
return r ;
}
2020-07-16 17:08:06 -04:00
// Connect tunnel to a remote agent
function connectTunnel ( url ) {
2020-07-13 18:06:45 -04:00
// Setup WebSocket options
var options = { rejectUnauthorized : false , checkServerIdentity : onVerifyServer }
// Setup the HTTP proxy if needed
if ( args . proxy != null ) { const HttpsProxyAgent = require ( 'https-proxy-agent' ) ; options . agent = new HttpsProxyAgent ( require ( 'url' ) . parse ( args . proxy ) ) ; }
// Connect the WebSocket
console . log ( 'Connecting...' ) ;
const WebSocket = require ( 'ws' ) ;
settings . tunnelwsstate = 0 ;
settings . tunnelws = new WebSocket ( url , options ) ;
settings . tunnelws . on ( 'open' , function ( ) { console . log ( 'Waiting for Agent...' ) ; } ) ; // Wait for agent connection
settings . tunnelws . on ( 'close' , function ( ) { console . log ( 'Connection Closed.' ) ; process . exit ( ) ; } ) ;
settings . tunnelws . on ( 'error' , function ( err ) { console . log ( err ) ; process . exit ( ) ; } ) ;
2020-07-16 17:08:06 -04:00
if ( settings . cmd == 'shell' ) {
// This code does all of the work for a shell command
settings . tunnelws . on ( 'message' , function ( rawdata ) {
var data = rawdata . toString ( ) ;
if ( settings . tunnelwsstate == 1 ) {
2021-04-26 22:01:40 -04:00
// If the incoming text looks exactly like a control command, ignore it.
if ( ( typeof data == 'string' ) && ( data . startsWith ( '{"ctrlChannel":"102938","type":"' ) ) ) {
var ctrlCmd = null ;
try { ctrlCmd = JSON . parse ( data ) ; } catch ( ex ) { }
if ( ( ctrlCmd != null ) && ( ctrlCmd . ctrlChannel == '102938' ) && ( ctrlCmd . type != null ) ) return ; // This is a control command, like ping/pong. Ignore it.
}
2020-07-16 17:08:06 -04:00
process . stdout . write ( data ) ;
} else if ( settings . tunnelwsstate == 0 ) {
if ( data == 'c' ) { console . log ( 'Connected.' ) ; } else if ( data == 'cr' ) { console . log ( 'Connected, session is being recorded.' ) ; } else return ;
2020-07-13 18:06:45 -04:00
// Send terminal size
var termSize = null ;
if ( typeof process . stdout . getWindowSize == 'function' ) { termSize = process . stdout . getWindowSize ( ) ; }
if ( termSize != null ) { settings . tunnelws . send ( JSON . stringify ( { ctrlChannel : '102938' , type : 'options' , cols : termSize [ 0 ] , rows : termSize [ 1 ] } ) ) ; }
settings . tunnelwsstate = 1 ;
2020-07-16 17:08:06 -04:00
settings . tunnelws . send ( '1' ) ; // Terminal
process . stdin . setEncoding ( 'utf8' ) ;
process . stdin . setRawMode ( true ) ;
process . stdout . setEncoding ( 'utf8' ) ;
process . stdin . unpipe ( process . stdout ) ;
process . stdout . unpipe ( process . stdin ) ;
process . stdin . on ( 'data' , function ( data ) { settings . tunnelws . send ( Buffer . from ( data ) ) ; } ) ;
//process.stdin.on('readable', function () { var chunk; while ((chunk = process.stdin.read()) !== null) { settings.tunnelws.send(Buffer.from(chunk)); } });
process . stdin . on ( 'end' , function ( ) { process . exit ( ) ; } ) ;
process . stdout . on ( 'resize' , function ( ) {
var termSize = null ;
if ( typeof process . stdout . getWindowSize == 'function' ) { termSize = process . stdout . getWindowSize ( ) ; }
if ( termSize != null ) { settings . tunnelws . send ( JSON . stringify ( { ctrlChannel : '102938' , type : 'termsize' , cols : termSize [ 0 ] , rows : termSize [ 1 ] } ) ) ; }
} ) ;
2020-07-13 18:06:45 -04:00
}
2020-07-16 17:08:06 -04:00
} ) ;
} else if ( settings . cmd == 'upload' ) {
// This code does all of the work for a file upload
// node meshctrl upload --id oL4Y6Eg0qjnpHFrp1AxfxnBPenbDGnDSkC@HSOnAheIyd51pKhqSCUgJZakzwfKl --file readme.md --target c:\
settings . tunnelws . on ( 'message' , function ( rawdata ) {
if ( settings . tunnelwsstate == 1 ) {
var cmd = null ;
try { cmd = JSON . parse ( rawdata . toString ( ) ) ; } catch ( ex ) { return ; }
if ( cmd . reqid == 'up' ) {
if ( ( cmd . action == 'uploadack' ) || ( cmd . action == 'uploadstart' ) ) {
2021-04-26 22:21:38 -04:00
settings . inFlight -- ;
if ( settings . uploadFile == null ) { if ( settings . inFlight == 0 ) { process . exit ( ) ; } return ; } // If the file is closed and there is no more in-flight data, exit.
2022-11-14 19:31:44 -05:00
var loops = ( cmd . action == 'uploadstart' ) ? 16 : 1 ; // If this is the first data to be sent, hot start now. We are going to have 16 blocks of data in-flight.
2021-04-26 22:21:38 -04:00
for ( var i = 0 ; i < loops ; i ++ ) {
if ( settings . uploadFile == null ) continue ;
var buf = Buffer . alloc ( 65565 ) ;
var len = require ( 'fs' ) . readSync ( settings . uploadFile , buf , 1 , 65564 , settings . uploadPtr ) ;
var start = 1 ;
settings . uploadPtr += len ;
if ( len > 0 ) {
if ( ( buf [ 1 ] == 0 ) || ( buf [ 1 ] == 123 ) ) { start = 0 ; buf [ 0 ] = 0 ; len ++ ; } // If the buffer starts with 0 or 123, we must add an extra 0 at the start of the buffer
settings . inFlight ++ ;
settings . tunnelws . send ( buf . slice ( start , start + len ) ) ;
} else {
console . log ( 'Upload done, ' + settings . uploadPtr + ' bytes sent.' ) ;
if ( settings . uploadFile != null ) { require ( 'fs' ) . closeSync ( settings . uploadFile ) ; delete settings . uploadFile ; }
if ( settings . inFlight == 0 ) { process . exit ( ) ; return ; } // File is closed, if there is no more in-flight data, exit.
}
2020-07-16 17:08:06 -04:00
}
2021-04-26 22:21:38 -04:00
2020-07-16 17:08:06 -04:00
} else if ( cmd . action == 'uploaderror' ) {
if ( settings . uploadFile != null ) { require ( 'fs' ) . closeSync ( settings . uploadFile ) ; }
console . log ( 'Upload error.' ) ;
process . exit ( ) ;
}
}
} else if ( settings . tunnelwsstate == 0 ) {
var data = rawdata . toString ( ) ;
if ( data == 'c' ) { console . log ( 'Connected.' ) ; } else if ( data == 'cr' ) { console . log ( 'Connected, session is being recorded.' ) ; } else return ;
settings . tunnelwsstate = 1 ;
settings . tunnelws . send ( '5' ) ; // Files
settings . uploadSize = require ( 'fs' ) . statSync ( args . file ) . size ;
settings . uploadFile = require ( 'fs' ) . openSync ( args . file , 'r' ) ;
settings . uploadPtr = 0 ;
2021-04-26 22:21:38 -04:00
settings . inFlight = 1 ;
console . log ( 'Uploading...' ) ;
2020-10-20 15:10:05 -04:00
settings . tunnelws . send ( JSON . stringify ( { action : 'upload' , reqid : 'up' , path : args . target , name : require ( 'path' ) . basename ( args . file ) , size : settings . uploadSize } ) ) ;
2020-07-16 17:08:06 -04:00
}
} ) ;
} else if ( settings . cmd == 'download' ) {
// This code does all of the work for a file download
// node meshctrl download --id oL4Y6Eg0qjnpHFrp1AxfxnBPenbDGnDSkC@HSOnAheIyd51pKhqSCUgJZakzwfKl --file c:\temp\MC-8Languages.png --target c:\temp\bob.png
settings . tunnelws . on ( 'message' , function ( rawdata ) {
if ( settings . tunnelwsstate == 1 ) {
2023-12-14 11:15:36 -05:00
if ( ( rawdata . length > 0 ) && ( rawdata . toString ( ) [ 0 ] != '{' ) ) {
2020-07-16 17:08:06 -04:00
// This is binary data, this test is ok because 4 first bytes is a control value.
if ( ( rawdata . length > 4 ) && ( settings . downloadFile != null ) ) { settings . downloadSize += ( rawdata . length - 4 ) ; require ( 'fs' ) . writeSync ( settings . downloadFile , rawdata , 4 , rawdata . length - 4 ) ; }
if ( ( rawdata [ 3 ] & 1 ) != 0 ) { // Check end flag
// File is done, close everything.
if ( settings . downloadFile != null ) { require ( 'fs' ) . closeSync ( settings . downloadFile ) ; }
console . log ( 'Download completed, ' + settings . downloadSize + ' bytes written.' ) ;
process . exit ( ) ;
} else {
settings . tunnelws . send ( JSON . stringify ( { action : 'download' , sub : 'ack' , id : args . file } ) ) ; // Send the ACK
}
} else {
// This is text data
var cmd = null ;
try { cmd = JSON . parse ( rawdata . toString ( ) ) ; } catch ( ex ) { return ; }
if ( cmd . action == 'download' ) {
if ( cmd . id != args . file ) return ;
if ( cmd . sub == 'start' ) {
2021-09-03 01:11:59 -04:00
if ( ( args . target . endsWith ( '\\' ) ) || ( args . target . endsWith ( '/' ) ) ) { args . target += path . parse ( args . file ) . name ; }
try { settings . downloadFile = require ( 'fs' ) . openSync ( args . target , 'w' ) ; } catch ( ex ) { console . log ( "Unable to create file: " + args . target ) ; process . exit ( ) ; return ; }
2020-07-16 17:08:06 -04:00
settings . downloadSize = 0 ;
settings . tunnelws . send ( JSON . stringify ( { action : 'download' , sub : 'startack' , id : args . file } ) ) ;
2021-09-03 01:11:59 -04:00
console . log ( 'Download started: ' + args . target ) ;
2020-07-16 17:08:06 -04:00
} else if ( cmd . sub == 'cancel' ) {
if ( settings . downloadFile != null ) { require ( 'fs' ) . closeSync ( settings . downloadFile ) ; }
console . log ( 'Download canceled.' ) ;
process . exit ( ) ;
}
}
}
} else if ( settings . tunnelwsstate == 0 ) {
var data = rawdata . toString ( ) ;
if ( data == 'c' ) { console . log ( 'Connected.' ) ; } else if ( data == 'cr' ) { console . log ( 'Connected, session is being recorded.' ) ; } else return ;
settings . tunnelwsstate = 1 ;
settings . tunnelws . send ( '5' ) ; // Files
settings . tunnelws . send ( JSON . stringify ( { action : 'download' , sub : 'start' , id : args . file , path : args . file } ) ) ;
}
} ) ;
}
2020-07-13 18:06:45 -04:00
}
2019-06-29 15:18:20 -04:00
// Encode an object as a cookie using a key using AES-GCM. (key must be 32 bytes or more)
function encodeCookie ( o , key ) {
try {
if ( key == null ) { return null ; }
o . time = Math . floor ( Date . now ( ) / 1000 ) ; // Add the cookie creation time
const iv = Buffer . from ( crypto . randomBytes ( 12 ) , 'binary' ) , cipher = crypto . createCipheriv ( 'aes-256-gcm' , key . slice ( 0 , 32 ) , iv ) ;
const crypted = Buffer . concat ( [ cipher . update ( JSON . stringify ( o ) , 'utf8' ) , cipher . final ( ) ] ) ;
return Buffer . concat ( [ iv , cipher . getAuthTag ( ) , crypted ] ) . toString ( 'base64' ) . replace ( /\+/g , '@' ) . replace ( /\//g , '$' ) ;
} catch ( e ) { return null ; }
}
2019-06-30 14:34:27 -04:00
// Generate a random Intel AMT password
function checkAmtPassword ( p ) { return ( p . length > 7 ) && ( /\d/ . test ( p ) ) && ( /[a-z]/ . test ( p ) ) && ( /[A-Z]/ . test ( p ) ) && ( /\W/ . test ( p ) ) ; }
function getRandomAmtPassword ( ) { var p ; do { p = Buffer . from ( crypto . randomBytes ( 9 ) , 'binary' ) . toString ( 'base64' ) . split ( '/' ) . join ( '@' ) ; } while ( checkAmtPassword ( p ) == false ) ; return p ; }
2020-07-13 18:06:45 -04:00
function getRandomHex ( count ) { return Buffer . from ( crypto . randomBytes ( count ) , 'binary' ) . toString ( 'hex' ) ; }
2020-05-02 16:49:56 -04:00
function format ( format ) { var args = Array . prototype . slice . call ( arguments , 1 ) ; return format . replace ( /{(\d+)}/g , function ( match , number ) { return typeof args [ number ] != 'undefined' ? args [ number ] : match ; } ) ; } ;
2020-07-17 17:29:02 -04:00
function winRemoveSingleQuotes ( str ) { if ( process . platform != 'win32' ) return str ; else return str . split ( '\'' ) . join ( '' ) ; }
2020-05-02 16:49:56 -04:00
2021-02-02 21:01:09 -05:00
function csvFormatArray ( x ) {
var y = [ ] ;
for ( var i in x ) { if ( ( x [ i ] == null ) || ( x [ i ] == '' ) ) { y . push ( '' ) ; } else { y . push ( '"' + x [ i ] . split ( '"' ) . join ( '' ) + '"' ) ; } }
return y . join ( ',' ) ;
}
2021-03-11 14:51:07 -05:00
function displayDeviceInfo ( sysinfo , lastconnect , network , nodes ) {
//console.log('displayDeviceInfo', sysinfo, lastconnect, network, nodes);
// Fetch the node information
var node = null ; ;
if ( sysinfo != null && ( sysinfo . node != null ) ) {
// Node information came with system information
node = sysinfo . node ;
} else {
// This device does not have system information, get node information from the nodes list.
for ( var m in nodes . nodes ) {
for ( var n in nodes . nodes [ m ] ) {
if ( nodes . nodes [ m ] [ n ] . _id . indexOf ( args . id ) >= 0 ) { node = nodes . nodes [ m ] [ n ] ; }
}
}
}
2024-05-23 15:59:33 -04:00
if ( ( sysinfo == null && lastconnect == null && network == null ) || ( node == null ) ) {
2021-03-11 14:51:07 -05:00
console . log ( "Invalid device id" ) ;
process . exit ( ) ; return ;
}
2020-05-02 16:49:56 -04:00
var info = { } ;
2021-03-11 14:51:07 -05:00
//if (network != null) { sysinfo.netif = network.netif; }
2020-05-02 16:49:56 -04:00
if ( lastconnect != null ) { node . lastconnect = lastconnect . time ; node . lastaddr = lastconnect . addr ; }
if ( args . raw ) { console . log ( JSON . stringify ( sysinfo , ' ' , 2 ) ) ; return ; }
2020-08-28 19:45:48 -04:00
// General
var output = { } , outputCount = 0 ;
2021-03-11 14:51:07 -05:00
if ( node . name ) { output [ "Server Name" ] = node . name ; outputCount ++ ; }
if ( node . rname ) { output [ "Computer Name" ] = node . rname ; outputCount ++ ; }
2020-08-28 19:45:48 -04:00
if ( node . host != null ) { output [ "Hostname" ] = node . host ; outputCount ++ ; }
if ( node . ip != null ) { output [ "IP Address" ] = node . ip ; outputCount ++ ; }
if ( node . desc != null ) { output [ "Description" ] = node . desc ; outputCount ++ ; }
if ( node . icon != null ) { output [ "Icon" ] = node . icon ; outputCount ++ ; }
if ( node . tags ) { output [ "Tags" ] = node . tags ; outputCount ++ ; }
if ( node . av ) {
var av = [ ] ;
for ( var i in node . av ) {
if ( typeof node . av [ i ] [ 'product' ] == 'string' ) {
var n = node . av [ i ] [ 'product' ] ;
if ( node . av [ i ] [ 'updated' ] === true ) { n += ', updated' ; }
if ( node . av [ i ] [ 'updated' ] === false ) { n += ', not updated' ; }
if ( node . av [ i ] [ 'enabled' ] === true ) { n += ', enabled' ; }
if ( node . av [ i ] [ 'enabled' ] === false ) { n += ', disabled' ; }
av . push ( n ) ;
}
}
output [ "AntiVirus" ] = av ; outputCount ++ ;
}
2021-03-11 14:51:07 -05:00
if ( typeof node . wsc == 'object' ) {
output [ "WindowsSecurityCenter" ] = node . wsc ; outputCount ++ ;
}
2020-08-28 19:45:48 -04:00
if ( outputCount > 0 ) { info [ "General" ] = output ; }
2020-05-02 16:49:56 -04:00
// Operating System
2021-03-11 14:51:07 -05:00
var hardware = null ;
if ( ( sysinfo != null ) && ( sysinfo . hardware != null ) ) { hardware = sysinfo . hardware ; }
if ( ( hardware && hardware . windows && hardware . windows . osinfo ) || node . osdesc ) {
2020-05-02 16:49:56 -04:00
var output = { } , outputCount = 0 ;
if ( node . rname ) { output [ "Name" ] = node . rname ; outputCount ++ ; }
if ( node . osdesc ) { output [ "Version" ] = node . osdesc ; outputCount ++ ; }
2021-03-11 14:51:07 -05:00
if ( hardware && hardware . windows && hardware . windows . osinfo ) { var m = hardware . windows . osinfo ; if ( m . OSArchitecture ) { output [ "Architecture" ] = m . OSArchitecture ; outputCount ++ ; } }
2020-05-02 16:49:56 -04:00
if ( outputCount > 0 ) { info [ "Operating System" ] = output ; }
}
// MeshAgent
if ( node . agent ) {
var output = { } , outputCount = 0 ;
2023-04-14 16:36:34 -04:00
var agentsStr = [ "Unknown" , "Windows 32bit console" , "Windows 64bit console" , "Windows 32bit service" , "Windows 64bit service" , "Linux 32bit" , "Linux 64bit" , "MIPS" , "XENx86" , "Android" , "Linux ARM" , "macOS x86-32bit" , "Android x86" , "PogoPlug ARM" , "Android" , "Linux Poky x86-32bit" , "macOS x86-64bit" , "ChromeOS" , "Linux Poky x86-64bit" , "Linux NoKVM x86-32bit" , "Linux NoKVM x86-64bit" , "Windows MinCore console" , "Windows MinCore service" , "NodeJS" , "ARM-Linaro" , "ARMv6l / ARMv7l" , "ARMv8 64bit" , "ARMv6l / ARMv7l / NoKVM" , "MIPS24KC (OpenWRT)" , "Apple Silicon" , "FreeBSD x86-64" , "Unknown" , "Linux ARM 64 bit (glibc/2.24 NOKVM)" , "Alpine Linux x86 64 Bit (MUSL)" , "Assistant (Windows)" , "Armada370 - ARM32/HF (libc/2.26)" , "OpenWRT x86-64" , "OpenBSD x86-64" , "Unknown" , "Unknown" , "MIPSEL24KC (OpenWRT)" , "ARMADA/CORTEX-A53/MUSL (OpenWRT)" , "Windows ARM 64bit console" , "Windows ARM 64bit service" ] ;
2020-05-02 16:49:56 -04:00
if ( ( node . agent != null ) && ( node . agent . id != null ) && ( node . agent . ver != null ) ) {
var str = '' ;
if ( node . agent . id <= agentsStr . length ) { str = agentsStr [ node . agent . id ] ; } else { str = agentsStr [ 0 ] ; }
if ( node . agent . ver != 0 ) { str += ' v' + node . agent . ver ; }
output [ "Mesh Agent" ] = str ; outputCount ++ ;
}
if ( ( node . conn & 1 ) != 0 ) {
output [ "Last agent connection" ] = "Connected now" ; outputCount ++ ;
} else {
if ( node . lastconnect ) { output [ "Last agent connection" ] = new Date ( node . lastconnect ) . toLocaleString ( ) ; outputCount ++ ; }
}
if ( node . lastaddr ) {
var splitip = node . lastaddr . split ( ':' ) ;
if ( splitip . length > 2 ) {
output [ "Last agent address" ] = node . lastaddr ; outputCount ++ ; // IPv6
} else {
output [ "Last agent address" ] = splitip [ 0 ] ; outputCount ++ ; // IPv4
}
}
2022-05-05 19:49:00 -04:00
if ( ( node . agent != null ) && ( node . agent . tag != null ) ) {
output [ "Tag" ] = node . agent . tag ; outputCount ++ ;
}
2020-05-02 16:49:56 -04:00
if ( outputCount > 0 ) { info [ "Mesh Agent" ] = output ; }
}
// Networking
if ( network . netif != null ) {
var output = { } , outputCount = 0 , minfo = { } ;
for ( var i in network . netif ) {
var m = network . netif [ i ] , moutput = { } , moutputCount = 0 ;
if ( m . desc ) { moutput [ "Description" ] = m . desc ; moutputCount ++ ; }
if ( m . mac ) {
if ( m . gatewaymac ) {
moutput [ "MAC Layer" ] = format ( "MAC: {0}, Gateway: {1}" , m . mac , m . gatewaymac ) ; moutputCount ++ ;
} else {
moutput [ "MAC Layer" ] = format ( "MAC: {0}" , m . mac ) ; moutputCount ++ ;
}
}
if ( m . v4addr && ( m . v4addr != '0.0.0.0' ) ) {
if ( m . v4gateway && m . v4mask ) {
moutput [ "IPv4 Layer" ] = format ( "IP: {0}, Mask: {1}, Gateway: {2}" , m . v4addr , m . v4mask , m . v4gateway ) ; moutputCount ++ ;
} else {
moutput [ "IPv4 Layer" ] = format ( "IP: {0}" , m . v4addr ) ; moutputCount ++ ;
}
}
if ( moutputCount > 0 ) { minfo [ m . name + ( m . dnssuffix ? ( ', ' + m . dnssuffix ) : '' ) ] = moutput ; info [ "Networking" ] = minfo ; }
}
}
2021-07-12 17:23:53 -04:00
if ( network . netif2 != null ) {
var minfo = { } ;
for ( var i in network . netif2 ) {
var m = network . netif2 [ i ] , moutput = { } , moutputCount = 0 ;
if ( Array . isArray ( m ) == false ||
m . length < 1 ||
m [ 0 ] == null ||
( ( typeof m [ 0 ] . mac == 'string' ) && ( m [ 0 ] . mac . startsWith ( '00:00:00:00' ) ) )
)
continue ;
2021-07-12 18:08:30 -04:00
var ifTitle = '' + i ;
2021-07-12 17:23:53 -04:00
if ( m [ 0 ] . fqdn != null && m [ 0 ] . fqdn != '' ) ifTitle += ', ' + m [ 0 ] . fqdn ;
if ( typeof m [ 0 ] . mac == 'string' ) {
if ( m [ 0 ] . gatewaymac ) {
moutput [ 'MAC Layer' ] = format ( "MAC: {0}, Gateway: {1}" , m [ 0 ] . mac , m [ 0 ] . gatewaymac ) ;
} else {
moutput [ 'MAC Layer' ] = format ( "MAC: {0}" , m [ 0 ] . mac ) ;
}
moutputCount ++ ;
}
moutput [ 'IPv4 Layer' ] = '' ;
moutput [ 'IPv6 Layer' ] = '' ;
for ( var j = 0 ; j < m . length ; j ++ ) {
var iplayer = m [ j ] ;
2021-07-12 18:08:30 -04:00
if ( iplayer . family == 'IPv4' || iplayer . family == 'IPv6' ) {
2021-07-12 17:23:53 -04:00
if ( iplayer . gateway && iplayer . netmask ) {
2021-07-12 18:08:30 -04:00
moutput [ iplayer . family + ' Layer' ] += format ( "IP: {0}, Mask: {1}, Gateway: {2} " , iplayer . address , iplayer . netmask , iplayer . gateway ) ;
2021-07-12 17:23:53 -04:00
moutputCount ++ ;
} else {
if ( iplayer . address ) {
2021-07-12 18:08:30 -04:00
moutput [ iplayer . family + ' Layer' ] += format ( "IP: {0} " , iplayer . address ) ;
2021-07-12 17:23:53 -04:00
moutputCount ++ ;
}
}
}
}
if ( moutput [ 'IPv4 Layer' ] == '' ) delete moutput [ 'IPv4 Layer' ] ;
if ( moutput [ 'IPv6 Layer' ] == '' ) delete moutput [ 'IPv6 Layer' ] ;
if ( moutputCount > 0 ) {
minfo [ ifTitle ] = moutput ;
info [ "Networking" ] = minfo ;
}
}
}
2020-05-02 16:49:56 -04:00
// Intel AMT
if ( node . intelamt != null ) {
var output = { } , outputCount = 0 ;
output [ "Version" ] = ( node . intelamt . ver ) ? ( 'v' + node . intelamt . ver ) : ( '<i>' + "Unknown" + '</i>' ) ; outputCount ++ ;
var provisioningStates = { 0 : "Not Activated (Pre)" , 1 : "Not Activated (In)" , 2 : "Activated" } ;
var provisioningMode = '' ;
if ( ( node . intelamt . state == 2 ) && node . intelamt . flags ) { if ( node . intelamt . flags & 2 ) { provisioningMode = ( ', ' + "Client Control Mode (CCM)" ) ; } else if ( node . intelamt . flags & 4 ) { provisioningMode = ( ', ' + "Admin Control Mode (ACM)" ) ; } }
output [ "Provisioning State" ] = ( ( node . intelamt . state ) ? ( provisioningStates [ node . intelamt . state ] ) : ( '<i>' + "Unknown" + '</i>' ) ) + provisioningMode ; outputCount ++ ;
output [ "Security" ] = ( node . intelamt . tls == 1 ) ? "Secured using TLS" : "TLS is not setup" ; outputCount ++ ;
output [ "Admin Credentials" ] = ( node . intelamt . user == null || node . intelamt . user == '' ) ? "Not Known" : "Known" ; outputCount ++ ;
if ( outputCount > 0 ) { info [ "Intel Active Management Technology (Intel AMT)" ] = output ; }
}
2021-03-11 14:51:07 -05:00
if ( hardware != null ) {
if ( hardware . identifiers ) {
var output = { } , outputCount = 0 , ident = hardware . identifiers ;
// BIOS
if ( ident . bios _vendor ) { output [ "Vendor" ] = ident . bios _vendor ; outputCount ++ ; }
if ( ident . bios _version ) { output [ "Version" ] = ident . bios _version ; outputCount ++ ; }
if ( outputCount > 0 ) { info [ "BIOS" ] = output ; }
output = { } , outputCount = 0 ;
2020-05-02 16:49:56 -04:00
2021-03-11 14:51:07 -05:00
// Motherboard
if ( ident . board _vendor ) { output [ "Vendor" ] = ident . board _vendor ; outputCount ++ ; }
if ( ident . board _name ) { output [ "Name" ] = ident . board _name ; outputCount ++ ; }
if ( ident . board _serial && ( ident . board _serial != '' ) ) { output [ "Serial" ] = ident . board _serial ; outputCount ++ ; }
if ( ident . board _version ) { output [ "Version" ] = ident . board _version ; }
if ( ident . product _uuid ) { output [ "Identifier" ] = ident . product _uuid ; }
if ( ident . cpu _name ) { output [ "CPU" ] = ident . cpu _name ; }
if ( ident . gpu _name ) { for ( var i in ident . gpu _name ) { output [ "GPU" + ( parseInt ( i ) + 1 ) ] = ident . gpu _name [ i ] ; } }
if ( outputCount > 0 ) { info [ "Motherboard" ] = output ; }
}
// Memory
if ( hardware . windows ) {
if ( hardware . windows . memory ) {
var output = { } , outputCount = 0 , minfo = { } ;
hardware . windows . memory . sort ( function ( a , b ) { if ( a . BankLabel > b . BankLabel ) return 1 ; if ( a . BankLabel < b . BankLabel ) return - 1 ; return 0 ; } ) ;
for ( var i in hardware . windows . memory ) {
var m = hardware . windows . memory [ i ] , moutput = { } , moutputCount = 0 ;
if ( m . Capacity ) { moutput [ "Capacity/Speed" ] = ( m . Capacity / 1024 / 1024 ) + " Mb, " + m . Speed + " Mhz" ; moutputCount ++ ; }
if ( m . PartNumber ) { moutput [ "Part Number" ] = ( ( m . Manufacturer && m . Manufacturer != 'Undefined' ) ? ( m . Manufacturer + ', ' ) : '' ) + m . PartNumber ; moutputCount ++ ; }
if ( moutputCount > 0 ) { minfo [ m . BankLabel ] = moutput ; info [ "Memory" ] = minfo ; }
}
2020-05-02 16:49:56 -04:00
}
}
2021-03-11 14:51:07 -05:00
// Storage
if ( hardware . identifiers && ident . storage _devices ) {
var output = { } , outputCount = 0 , minfo = { } ;
// Sort Storage
ident . storage _devices . sort ( function ( a , b ) { if ( a . Caption > b . Caption ) return 1 ; if ( a . Caption < b . Caption ) return - 1 ; return 0 ; } ) ;
for ( var i in ident . storage _devices ) {
var m = ident . storage _devices [ i ] , moutput = { } ;
if ( m . Size ) {
if ( m . Model && ( m . Model != m . Caption ) ) { moutput [ "Model" ] = m . Model ; outputCount ++ ; }
if ( ( typeof m . Size == 'string' ) && ( parseInt ( m . Size ) == m . Size ) ) { m . Size = parseInt ( m . Size ) ; }
if ( typeof m . Size == 'number' ) { moutput [ "Capacity" ] = Math . floor ( m . Size / 1024 / 1024 ) + 'Mb' ; outputCount ++ ; }
if ( typeof m . Size == 'string' ) { moutput [ "Capacity" ] = m . Size ; outputCount ++ ; }
if ( moutputCount > 0 ) { minfo [ m . Caption ] = moutput ; info [ "Storage" ] = minfo ; }
}
2020-05-02 16:49:56 -04:00
}
}
}
// Display everything
if ( args . json ) {
console . log ( JSON . stringify ( info , ' ' , 2 ) ) ;
} else {
for ( var i in info ) {
console . log ( '--- ' + i + ' ---' ) ;
for ( var j in info [ i ] ) {
2020-08-28 19:45:48 -04:00
if ( ( typeof info [ i ] [ j ] == 'string' ) || ( typeof info [ i ] [ j ] == 'number' ) ) {
2020-05-02 16:49:56 -04:00
console . log ( ' ' + j + ': ' + info [ i ] [ j ] ) ;
} else {
console . log ( ' ' + j + ':' ) ;
for ( var k in info [ i ] [ j ] ) {
console . log ( ' ' + k + ': ' + info [ i ] [ j ] [ k ] ) ;
}
}
}
}
}
2020-05-15 03:39:07 -04:00
}
2021-04-17 19:04:48 -04:00
// Read the Mesh Agent error log and index it.
function indexAgentErrorLog ( ) {
// Index the messages
const lines = require ( 'fs' ) . readFileSync ( '../meshcentral-data/agenterrorlogs.txt' , { encoding : 'utf8' , flag : 'r' } ) . split ( '\r\n' ) ;
var errorIndex = { } ; // "msg" --> [ { lineNumber, elemenetNumber } ]
for ( var i = 0 ; i < lines . length ; i ++ ) {
const line = lines [ i ] ;
if ( line . length > 88 ) {
var nodeid = line . substring ( 0 , 70 ) ;
var fetchTime = parseInt ( line . substring ( 72 , 85 ) ) ;
var data = JSON . parse ( line . substring ( 87 ) ) ;
if ( ( data != null ) && ( data . action == 'errorlog' ) && ( Array . isArray ( data . log ) ) ) {
for ( var j = 0 ; j < data . log . length ; j ++ ) {
var entry = data . log [ j ] ;
if ( ( entry != null ) && ( typeof entry . t == 'number' ) && ( typeof entry . m == 'string' ) ) {
const msg = entry . m ;
if ( errorIndex [ msg ] == null ) { errorIndex [ msg ] = [ ] ; }
errorIndex [ msg ] . push ( { l : i , e : j } ) ;
}
}
}
}
}
// Sort the messages by frequency
var errorIndexCount = [ ] ; // [ { m: "msg", c: count } ]
for ( var i in errorIndex ) { errorIndexCount . push ( { m : i , c : errorIndex [ i ] . length } ) ; }
errorIndexCount = errorIndexCount . sort ( function ( a , b ) { return b . c - a . c } )
// Display the results
2021-04-23 02:39:09 -04:00
for ( var i = 0 ; i < errorIndexCount . length ; i ++ ) {
const m = errorIndexCount [ i ] . m ;
if ( ( m . indexOf ( 'STUCK' ) >= 0 ) || ( m . indexOf ( 'FATAL' ) >= 0 ) ) { console . log ( errorIndexCount [ i ] . c , m ) ; }
}
2021-04-17 19:04:48 -04:00
}