1
0
Fork 0
mirror of https://github.com/Ylianst/MeshCentral.git synced 2025-03-09 15:40:18 +00:00

Changed how stript-task will be integrated into MeshCentral, added run button to device general tab.

This commit is contained in:
Ylian Saint-Hilaire 2022-08-18 21:31:09 -07:00
parent 1b67b84369
commit 44af3a2408
10 changed files with 44 additions and 2550 deletions

View file

@ -5537,25 +5537,7 @@
p2downloadDeviceInfo();
} else if (op == 106) {
// Run commands
var wintype = false, linuxtype = false, agenttype = false, chkNodeIds = getCheckedDevices();
for (var i in chkNodeIds) {
var n = getNodeFromId(chkNodeIds[i]);
if (n.agent) { if ((GetNodeRights(n) & 24) == 24) { agenttype = true; } if ((n.agent.id > 0) && (n.agent.id < 5)) { wintype = true; } else { linuxtype = true; } }
}
if ((wintype == true) || (linuxtype == true) || (agenttype == true)) {
var x = "Run commands on selected devices." + '<br />';
x += '<select id=d2cmdtype onclick=d2runCommandValidate() style=width:100%;margin-bottom:4px;margin-top:4px>';
if (wintype == true) { x += '<option value=1>' + "Windows Command Prompt" + '</option><option value=2>' + "Windows PowerShell" + '</option>'; }
if (linuxtype == true) { x += '<option value=3>' + "Linux/BSD/macOS Command Shell" + '</option>'; }
if (agenttype == true) { x += '<option value=4>' + "Agent Console" + '</option>'; } // MESHRIGHT_REMOTECONTROL & MESHRIGHT_AGENTCONSOLE are needed
x += '</select>';
x += '<select id=d2cmduser style=width:100%;margin-bottom:4px><option value=0>' + "Run as agent" + '</option><option value=1>' + "Run as user, agent if no user" + '</option><option value=2>' + "Must run as user" + '</option></select>';
x += '<textarea id=d2runcmd style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea>';
setDialogMode(2, "Run Commands", 3, d2groupActionFunctionRunCommands, x);
Q('d2runcmd').focus();
//QE('idx_dlgOkButton', true);
d2runCommandValidate();
}
d2runCommandDialog({ nodeids: getCheckedDevices(), title: "Run commands on selected devices.", func: uncheckAllDevices });
} else if (op == 107) {
// Edit tags
var x = "Perform batch device tag operation" + '<br /><br />';
@ -5611,7 +5593,6 @@
}
}
function d2runCommandValidate() { QV('d2cmduser', Q('d2cmdtype').value < 4); }
function d2batchUploadValidate() { QE('idx_dlgOkButton', (Q('d2uploadinput').files.length != 0) && ((Q('d2winuploadpath') == null) || (Q('d2winuploadpath').value != '')) && ((Q('d2linuxuploadpath') == null) || (Q('d2linuxuploadpath').value != ''))); }
function d2batchUploadValidateOk() { Q('d2batchUploadSubmit').click(); }
function d2groupActionFunctionAgentUpdateExec() { meshserver.send({ action: 'updateAgents', nodeids: getCheckedDevices() }); }
@ -5728,10 +5709,34 @@
function d2groupActionFunctionDelCheck() { QE('idx_dlgOkButton', Q('d2check').checked); }
function d2groupActionFunctionDelExec() { meshserver.send({ action: 'removedevices', nodeids: getCheckedDevices() }); uncheckAllDevices(); }
function d2groupActionFunctionRunCommands() {
function d2runCommandDialog(options) {
var wintype = false, linuxtype = false, agenttype = false;
for (var i in options.nodeids) {
var n = getNodeFromId(options.nodeids[i]);
if (n.agent) { if ((GetNodeRights(n) & 24) == 24) { agenttype = true; } if ((n.agent.id > 0) && (n.agent.id < 5)) { wintype = true; } else { linuxtype = true; } }
}
if ((wintype == true) || (linuxtype == true) || (agenttype == true)) {
var x = options.title + '<br />';
x += '<select id=d2cmdtype onclick=d2runCommandValidate() style=width:100%;margin-bottom:4px;margin-top:4px>';
if (wintype == true) { x += '<option value=1>' + "Windows Command Prompt" + '</option><option value=2>' + "Windows PowerShell" + '</option>'; }
if (linuxtype == true) { x += '<option value=3>' + "Linux/BSD/macOS Command Shell" + '</option>'; }
if (agenttype == true) { x += '<option value=4>' + "Agent Console" + '</option>'; } // MESHRIGHT_REMOTECONTROL & MESHRIGHT_AGENTCONSOLE are needed
x += '</select>';
x += '<select id=d2cmduser style=width:100%;margin-bottom:4px><option value=0>' + "Run as agent" + '</option><option value=1>' + "Run as user, agent if no user" + '</option><option value=2>' + "Must run as user" + '</option></select>';
x += '<textarea id=d2runcmd style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea>';
setDialogMode(2, "Run Commands", 3, d2groupActionFunctionRunCommands, x, options);
Q('d2runcmd').focus();
//QE('idx_dlgOkButton', true);
d2runCommandValidate();
}
}
function d2runCommandValidate() { QV('d2cmduser', Q('d2cmdtype').value < 4); }
function d2groupActionFunctionRunCommands(b, options) {
var type = 3;
try { type = parseInt(Q('d2cmdtype').value); } catch (ex) { }
meshserver.send({ action: 'runcommands', nodeids: getCheckedDevices(), type: type, cmds: Q('d2runcmd').value, runAsUser: parseInt(Q('d2cmduser').value) }); uncheckAllDevices();
meshserver.send({ action: 'runcommands', nodeids: options.nodeids, type: type, cmds: Q('d2runcmd').value, runAsUser: parseInt(Q('d2cmduser').value) });
if (options.func) { options.func(); }
}
function onSortSelectChange(skipsave) {
@ -7174,6 +7179,7 @@
if (((meshrights & (4 + 8 + 64 + 262144)) != 0) && (node.mtype < 3) && ((node.agent == null) || (node.agent.id != 34))) { x += '<input type=button value="' + "Actions" + '" title="' + "Perform power actions on the device" + '" onclick=deviceActionFunction() />'; }
x += '<input type=button value="' + "Notes" + '" title="' + "View notes about this device" + '" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponentEx(node._id) + '") />';
x += '<input type=button value="' + "Log Event" + '" title="' + "Write an event for this device" + '" onclick=writeDeviceEvent("' + encodeURIComponentEx(node._id) + '") />';
if ((node.mtype == 2) && (connectivity & 1) && (meshrights == 0xFFFFFFFF)) { x += '<input type=button value="' + "Run" + '" title="' + "Run commands on this device" + '" onclick=runDeviceCmd("' + encodeURIComponentEx(node._id) + '") />'; }
if (node.mtype != 4) {
if ((meshrights & 8) && ((connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0)))) { x += '<input type=button value="' + "Message" + '" title="' + "Display a text message on the remote device" + '" onclick=deviceMessageFunction() />'; }
//if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="' + "Display a text message of the remote device" + '" onclick=deviceToastFunction() />'; }
@ -7632,6 +7638,12 @@
return str.join(', ');
}
// Run commands on current device
function runDeviceCmd(nodeid) {
if (xxdialogMode) return;
d2runCommandDialog({ nodeids: [ decodeURIComponent(nodeid) ], title: "Run commands on this device." });
}
function writeDeviceEvent(nodeid) {
if (xxdialogMode) return;
setDialogMode(2, "Add Device Event", 3, writeDeviceEventEx, '<textarea id=d2devEvent style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea><span style=font-size:10px>' + "This will add an entry to this device's event log." + '<span>', nodeid);

View file

@ -1,249 +0,0 @@
<html>
<head>
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<link rel="stylesheet" type="text/css" href="/public/tail.DateTime/tail.datetime-default-blue.min.css" />
<style>
body {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
color: white;
}
#scriptContent {
width: 80%;
height: 80%;
}
#schedContentC {
padding: 20px;
}
#controlBar button {
cursor: pointer;
}
#scriptNameC {
padding: 20px;
}
#scriptName {
width: 300px;
}
#controlBar {
padding: 5px;
padding-left: 20px;
}
#left {
height: 100%;
width: 25%;
float: left;
}
#right {
height: 100%;
width: 75%;
float: right;
}
body {
background-color: #036;
}
#intervalListC {
list-style-type: none;
}
#daysListC {
list-style-type: none;
}
.rOpt {
height: 40px;
}
#daysListC {
display: inline-grid;
}
li {
padding: 2px;
}
</style>
</head>
<body onload="doOnLoad();">
<script type="text/javascript" src="/public/tail.DateTime/tail.datetime.min.js"></script>
<div id="scriptTaskSchedule">
<div id="controlBar">
<button onclick="goSave();">Schedule</button>
<button onclick="goCancel();">Cancel</button>
</div>
<div id="schedContentC">
<div id="left">
<span class="oTitle">Recurrence</span>
<ul id="intervalListC">
<li><label><input onclick="intervalSelected(this);" type="radio" checked name="recur" value="once">Once</label></li>
<li><label><input onclick="intervalSelected(this);" type="radio" name="recur" value="minutes">Minutes</label></li>
<li><label><input onclick="intervalSelected(this);" type="radio" name="recur" value="hourly">Hourly</label></li>
<li><label><input onclick="intervalSelected(this);" type="radio" name="recur" value="daily">Daily</label></li>
<li><label><input onclick="intervalSelected(this);" type="radio" name="recur" value="weekly">Weekly</label></li>
<!-- li><label><input type="radio" name="recur" value="monthly">Monthly</label></li -->
</ul>
</div>
<div id="right">
<div class="rOpt">
<span class="oTitle">Start: </span>
<input type="text" class="datePick" id="startDate" value="" />
<input type="text" class="timePick" id="startTime" value="" />
</div>
<div class="rOpt" id="intervalC" style="display: none;">
<span class="oTitle">Every: </span>
<input type="text" id="interval" value="1" />&nbsp;<span id="hintText"></span>
</div>
<div class="rOpt" id="endC" style="display: none;">
<span class="oTitle">End: </span>
<input type="text" class="datePick" id="endDate" value="" />
<input type="text" class="timePick" id="endTime" value="" />
<label><input type="checkbox" id="endNever" checked onclick="checkEndNever(this);" /> Never</label>
</div>
<div class="rOpt" id="daysC" style="display: none;">
<span class="oTitle">Days: </span>
<ul id="daysListC">
<li><label><input type="checkbox" name="days[]" value="0"> Sunday</label></li>
<li><label><input type="checkbox" name="days[]" value="1"> Monday</label></li>
<li><label><input type="checkbox" name="days[]" value="2"> Tuesday</label></li>
<li><label><input type="checkbox" name="days[]" value="3"> Wednesday</label></li>
<li><label><input type="checkbox" name="days[]" value="4"> Thursday</label></li>
<li><label><input type="checkbox" name="days[]" value="5"> Friday</label></li>
<li><label><input type="checkbox" name="days[]" value="6"> Saturday</label></li>
</ul>
</div>
</div>
</div>
</div>
<script type="text/javascript">
function checkEndNever(el) {
if (el.checked) {
Q('endDate').value = '';
Q('endTime').value = '';
}
}
function setTimePick() {
var d = new Date();
document.getElementById("startDate").value = d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate();
document.getElementById("startTime").value = d.getHours() + ':' + d.getMinutes();
tail.DateTime(".datePick", { position: "bottom", dateStart: Date(), timeFormat: false });
tail.DateTime(".timePick", { position: "bottom", dateFormat: false, timeFormat: "HH:ii", timeStepMinutes: 15 });
tail.datetime.inst[document.getElementById('endDate').getAttribute('data-tail-datetime')].on('change', function () {
document.getElementById('endNever').checked = false;
});
tail.datetime.inst[document.getElementById('endTime').getAttribute('data-tail-datetime')].on('change', function () {
document.getElementById('endNever').checked = false;
});
}
function doOnLoad() {
try {
if (scriptId == null) {
alert('Page reloaded and data lost. Please re-run scheduler from the main window.');
goCancel();
return;
}
} catch (e) {
alert('Page reloaded and data lost. Please re-run scheduler from the main window.');
goCancel();
return;
}
setTimePick();
}
function intervalSelected(el) {
var v = el.value;
switch (v) {
case 'once':
QV('intervalC', false);
QV('endC', false);
QV('daysC', false);
break;
case 'minutes':
QV('intervalC', true);
QV('endC', true);
QV('daysC', false);
QH('hintText', 'minute(s)');
break;
case 'hourly':
QV('intervalC', true);
QV('endC', true);
QV('daysC', false);
QH('hintText', 'hour(s)');
break;
case 'daily':
QV('intervalC', true);
QV('endC', true);
QV('daysC', false);
QH('hintText', 'day(s)');
break;
case 'weekly':
QV('intervalC', true);
QV('endC', true);
QV('daysC', true);
QH('hintText', 'week(s)');
break;
}
}
function goSave() {
var o = {};
var recurEls = document.getElementsByName("recur");
recurEls.forEach(function (el) {
if (el.checked) o.recur = el.value;
});
switch (o.recur) {
case 'once':
o.startAt = Date.parse(Q('startDate').value + ' ' + Q('startTime').value);
o.startAt = Math.floor(o.startAt / 1000);
break;
case 'minutes':
case 'hourly':
case 'daily':
o.startAt = Date.parse(Q('startDate').value + ' ' + Q('startTime').value);
o.startAt = Math.floor(o.startAt / 1000);
o.interval = Number(Q('interval').value);
if (Q('endNever').checked) o.endAt = null;
else {
o.endAt = Date.parse(Q('endDate').value + ' ' + Q('endTime').value);
o.endAt = Math.floor(o.endAt / 1000);
}
break;
case 'weekly':
o.startAt = Date.parse(Q('startDate').value + ' ' + Q('startTime').value);
o.startAt = Math.floor(o.startAt / 1000);
o.interval = Number(Q('interval').value);
if (Q('endNever').checked) o.endAt = null;
else {
o.endAt = Date.parse(Q('endDate').value + ' ' + Q('endTime').value);
o.endAt = Math.floor(o.endAt / 1000);
}
var dayEls = document.getElementsByName("days[]");
o.dayVals = [];
if (dayEls.length) {
dayEls.forEach(function (de) {
if (de.checked) o.dayVals.push(de.value);
});
}
break;
}
o.scriptId = scriptId;
o.nodes = nodes;
window.opener.schedCallback(o);
window.close();
}
function goCancel() {
window.close();
}
</script>
</body>
</html>

View file

@ -1,73 +0,0 @@
<html>
<head>
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
<style>
body {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
color: white;
}
#scriptContent {
width: 80%;
height: 80%;
}
#scriptContentC {
padding: 20px;
}
#controlBar button {
cursor: pointer;
}
#scriptNameC {
padding: 20px;
}
#scriptName {
width: 300px;
}
#controlBar {
padding: 5px;
padding-left: 20px;
}
body {
background-color: #036;
}
</style>
</head>
<body onload="doOnLoad();">
<div id="scriptTaskScriptEdit">
<div id="scriptNameC">Script Name: <input type="text" value="" id="scriptName" /></div>
<div id="controlBar">
<button onclick="goSave();">Save</button>
<button onclick="goClose();">Close</button>
</div>
<div id="scriptContentC">
<textarea id="scriptContent"></textarea>
</div>
</div>
<script type="text/javascript">
var scriptData = {{{scriptData}}};
function doOnLoad() {
//QH('scriptContent', scriptData.content);
Q('scriptContent').value = scriptData.content;
Q('scriptName').value = scriptData.name;
}
function goSave() {
scriptData.content = Q('scriptContent').value;
scriptData.name = Q('scriptName').value;
window.opener.callback(scriptData);
//goClose();
}
function goClose() {
window.close();
}
</script>
</body>
</html>

File diff suppressed because it is too large Load diff