Added View Only Desktop, Optimized Images
Ylian Saint-Hilaire committed
Nov 2, 2018 at 18:13 UTC
dfeab93cc90dc8e113ac39b2706401ec892cb9d9
36 files changed
+198
-109
meshcentral.js
+12
-4
@@ -407,6 +407,9 @@ function CreateMeshCentralServer(config, args) {
407
// Load any domain web certificates
408
for (i in obj.config.domains) {
409
if (obj.config.domains[i].certurl != null) {
410
+ // Fix the URL and add 'https://' if needed
411
+ if (obj.config.domains[i].certurl.indexOf('://') < 0) { obj.config.domains[i].certurl = 'https://' + obj.config.domains[i].certurl; }
412
+
413
// Load web certs
414
webCertLoadCount++;
415
obj.certificateOperations.loadCertificate(obj.config.domains[i].certurl, obj.config.domains[i], function (url, cert, xdomain) {
@@ -415,12 +418,17 @@ function CreateMeshCentralServer(config, args) {
418
// Decode a RSA certificate and hash the public key
419
var forgeCert = obj.certificateOperations.forge.pki.certificateFromAsn1(obj.certificateOperations.forge.asn1.fromDer(cert.raw.toString('binary')));
420
var hash = obj.certificateOperations.forge.pki.getPublicKeyFingerprint(forgeCert.publicKey, { md: obj.certificateOperations.forge.md.sha384.create(), encoding: 'hex' });
418
- xdomain.certhash = hash;
419
- console.log('Loaded RSA web certificate at ' + url + ', SHA384: ' + xdomain.certhash + '.');
421
+ if (xdomain.certhash != hash) {
422
+ xdomain.certhash = hash;
423
+ console.log('Loaded RSA web certificate at ' + url + ', SHA384: ' + xdomain.certhash + '.');
424
+ }
425
} catch (ex) {
426
// This may be a ECDSA certificate, hash the entire cert
422
- xdomain.certhash = obj.crypto.createHash('sha384').update(cert.raw).digest('hex');
423
- console.log('Loaded non-RSA web certificate at ' + url + ', SHA384: ' + xdomain.certhash + '.');
427
+ var hash = obj.crypto.createHash('sha384').update(cert.raw).digest('hex');
428
+ if (xdomain.certhash != hash) {
429
+ xdomain.certhash = hash;
430
+ console.log('Loaded non-RSA web certificate at ' + url + ', SHA384: ' + xdomain.certhash + '.');
431
+ }
432
}
433
} else {
434
console.log('Failed to load web certificate at: ' + url);
meshuser.js
+4
-4
@@ -315,7 +315,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
315
if (agent != null) {
316
// Check if we have permission to send a message to that node
317
var rights = user.links[agent.dbMeshKey];
318
- if ((rights != null) && ((rights.rights & 8) != 0)) { // 8 is remote control permission
318
+ if ((rights != null) && ((rights.rights & 8) || (rights.rights & 256))) { // 8 is remote control permission, 256 is desktop read only
319
command.sessionid = ws.sessionId; // Set the session id, required for responses.
320
command.rights = rights.rights; // Add user rights flags to the message
321
delete command.nodeid; // Remove the nodeid since it's implyed.
@@ -327,7 +327,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
327
if (routing != null) {
328
// Check if we have permission to send a message to that node
329
var rights = user.links[routing.meshid];
330
- if ((rights != null) && ((rights.rights & 8) != 0)) { // 8 is remote control permission
330
+ if ((rights != null) && ((rights.rights & 8) || (rights.rights & 256))) { // 8 is remote control permission
331
command.fromSessionid = ws.sessionId; // Set the session id, required for responses.
332
command.rights = rights.rights; // Add user rights flags to the message
333
obj.parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
@@ -1210,7 +1210,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1210
mesh = obj.parent.meshes[command.id];
1211
if (mesh) {
1212
// Check if this user has rights to do this
1213
- if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; }
1213
+ if ((mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { return; } // Must have rights to edit the mesh
1214
1215
// Set the id's notes
1216
if (obj.common.validateString(command.notes, 1) == false) {
@@ -1265,7 +1265,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1265
mesh = obj.parent.meshes[command.id];
1266
if (mesh) {
1267
// Check if this user has rights to do this
1268
- if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; }
1268
+ if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 1) == 0)) { return; } // Must have rights to edit the mesh
1269
1270
// Get the notes about this node
1271
obj.db.Get('nt' + command.id, function (err, notes) {
public/images/User-200.png
Binary files a/public/images/User-200.png and /dev/null differ
public/images/icons200-1-1.jpg
Binary files /dev/null and b/public/images/icons200-1-1.jpg differ
public/images/icons200-1-1.png
Binary files a/public/images/icons200-1-1.png and /dev/null differ
public/images/icons200-2-1.jpg
Binary files /dev/null and b/public/images/icons200-2-1.jpg differ
public/images/icons200-2-1.png
Binary files a/public/images/icons200-2-1.png and /dev/null differ
public/images/icons200-3-1.jpg
Binary files /dev/null and b/public/images/icons200-3-1.jpg differ
public/images/icons200-3-1.png
Binary files a/public/images/icons200-3-1.png and /dev/null differ
public/images/icons200-4-1.jpg
Binary files /dev/null and b/public/images/icons200-4-1.jpg differ
public/images/icons200-4-1.png
Binary files a/public/images/icons200-4-1.png and /dev/null differ
public/images/icons200-5-1.jpg
Binary files /dev/null and b/public/images/icons200-5-1.jpg differ
public/images/icons200-5-1.png
Binary files a/public/images/icons200-5-1.png and /dev/null differ
public/images/icons200-6-1.jpg
Binary files /dev/null and b/public/images/icons200-6-1.jpg differ
public/images/icons200-6-1.png
Binary files a/public/images/icons200-6-1.png and /dev/null differ
public/images/leftbar-62.jpg
Binary files /dev/null and b/public/images/leftbar-62.jpg differ
public/images/leftbar-62.png
Binary files a/public/images/leftbar-62.png and /dev/null differ
public/images/leftbar-90.png
Binary files a/public/images/leftbar-90.png and /dev/null differ
public/images/mainaccount.jpg
Binary files /dev/null and b/public/images/mainaccount.jpg differ
public/images/mainaccount.png
Binary files a/public/images/mainaccount.png and /dev/null differ
public/images/mainwelcome-90.png
Binary files a/public/images/mainwelcome-90.png and /dev/null differ
public/images/mainwelcome.jpg
Binary files /dev/null and b/public/images/mainwelcome.jpg differ
public/images/mainwelcome.png
Binary files a/public/images/mainwelcome.png and /dev/null differ
public/images/mesh-200.jpg
Binary files /dev/null and b/public/images/mesh-200.jpg differ
public/images/mesh-200.png
Binary files a/public/images/mesh-200.png and /dev/null differ
public/images/server-200.jpg
Binary files /dev/null and b/public/images/server-200.jpg differ
public/images/server-200.png
Binary files a/public/images/server-200.png and /dev/null differ
public/images/user-200.jpg
Binary files /dev/null and b/public/images/user-200.jpg differ
public/images/webp/mainwelcome.webp
Binary files /dev/null and b/public/images/webp/mainwelcome.webp differ
public/images/webp/mesh-200.webp
Binary files /dev/null and b/public/images/webp/mesh-200.webp differ
public/images/webp/user-200.webp
Binary files /dev/null and b/public/images/webp/user-200.webp differ
public/styles/style.css
+6
-6
@@ -197,7 +197,7 @@ a {
197
}
198
199
.lb1 {
200
- background: url(../images/leftbar-62.png) -0px 0px;
200
+ background: url(../images/leftbar-62.jpg) -0px 0px;
201
height: 62px;
202
width: 62px;
203
cursor: pointer;
@@ -205,7 +205,7 @@ a {
205
}
206
207
.lb2 {
208
- background: url(../images/leftbar-62.png) -75px 0px;
208
+ background: url(../images/leftbar-62.jpg) -75px 0px;
209
height: 62px;
210
width: 62px;
211
cursor: pointer;
@@ -213,7 +213,7 @@ a {
213
}
214
215
.lb3 {
216
- background: url(../images/leftbar-62.png) -150px 0px;
216
+ background: url(../images/leftbar-62.jpg) -150px 0px;
217
height: 62px;
218
width: 62px;
219
cursor: pointer;
@@ -221,7 +221,7 @@ a {
221
}
222
223
.lb4 {
224
- background: url(../images/leftbar-62.png) -225px 0px;
224
+ background: url(../images/leftbar-62.jpg) -225px 0px;
225
height: 62px;
226
width: 62px;
227
cursor: pointer;
@@ -229,7 +229,7 @@ a {
229
}
230
231
.lb5 {
232
- background: url(../images/leftbar-62.png) -294px 0px;
232
+ background: url(../images/leftbar-62.jpg) -294px 0px;
233
height: 62px;
234
width: 62px;
235
cursor: pointer;
@@ -237,7 +237,7 @@ a {
237
}
238
239
.lb6 {
240
- background: url(../images/leftbar-62.png) -360px 0px;
240
+ background: url(../images/leftbar-62.jpg) -360px 0px;
241
height: 62px;
242
width: 62px;
243
cursor: pointer;
views/default-mobile.handlebars
+139
-77
@@ -389,9 +389,10 @@
389
</div>
390
<div>
391
<input id="deskActionsBtn" type=button style="margin-left:3px" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value=Actions onclick=deviceActionFunction() />
392
- <input type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()">
393
- <input type="button" title="Change the power state of the remote machine" onkeypress="return false" onkeydown="return false" value="Power Actions..." onclick="showPowerActionDlg()" style="display:none">
394
- <input id="DeskCAD" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()">
392
+ <input type="button" value="Settings..." style="margin-left:3px" title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()">
393
+ <input type="button" title="Change the power state of the remote machine" onkeypress="return false" onkeydown="return false" value="Power Actions..." onclick="showPowerActionDlg()" style="display:none;margin-left:3px">
394
+ <!--<input id="DeskCAD" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()">-->
395
+ <span id="DeskControlSpan" style="margin-left:3px;display:none" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false">Input</span>
396
</div>
397
</div>
398
</div>
@@ -500,6 +501,56 @@
501
<div id=dialog2 style="margin:auto;margin:3px">
502
<div id=id_dialogOptions></div>
503
</div>
504
+ <div id=dialog7 style="margin:auto;margin:3px">
505
+ <div id="d7meshkvm">
506
+ <h4 style="width:100%;border-bottom:1px solid gray">Agent Remote Desktop</h4>
507
+ <div style="margin:3px 0 3px 0">
508
+ <select id="d7bitmapquality" style="float:right;width:200px;height:20px" dir="rtl"></select>
509
+ <div style="height:20px">Quality</div>
510
+ </div>
511
+ <div style="margin:3px 0 3px 0">
512
+ <select id="d7bitmapscaling" style="float:right;width:200px;height:20px" dir="rtl">
513
+ <option selected=selected value=1024>100%</option>
514
+ <option value=896>87.5%</option>
515
+ <option value=768>75%</option>
516
+ <option value=640>62.5%</option>
517
+ <option value=512>50%</option>
518
+ <option value=384>37.5%</option>
519
+ <option value=256>25%</option>
520
+ <option value=128>12.5%</option>
521
+ </select>
522
+ <div style="height:20px">Scaling</div>
523
+ </div>
524
+ <div style="margin:3px 0 3px 0">
525
+ <select id="d7framelimiter" style="float:right;width:200px;height:20px" dir="rtl">
526
+ <option selected=selected value=50>Fast</option>
527
+ <option value=100>Medium</option>
528
+ <option value=400>Slow</option>
529
+ <option value=1000>Very slow</option>
530
+ </select>
531
+ <div style="height:20px">Rate</div>
532
+ </div>
533
+ </div>
534
+ <div id="d7amtkvm">
535
+ <h4 style="width:100%;border-bottom:1px solid gray">Intel® AMT Hardware KVM</h4>
536
+ <div style='height:26px'>
537
+ <select id="d7desktopmode" style="float:right;width:200px">
538
+ <option value="1">RLE8, Fastest</option>
539
+ <option value="2">RLE16, Recommended</option>
540
+ <option value="3">RAW8, Slow</option>
541
+ <option value="4">RAW16, Very Slow</option>
542
+ </select>
543
+ <div>Encoding</div>
544
+ </div>
545
+ <div style="height:60px">
546
+ <div style="float:right;border:1px solid #666;width:200px;height:60px;overflow-y:scroll;background-color:white">
547
+ <input type="checkbox" id='d7showfocus'>Show Focus Tool<br>
548
+ <input type="checkbox" id='d7showcursor'>Show Local Mouse Cursor<br>
549
+ </div>
550
+ <div>Other</div>
551
+ </div>
552
+ </div>
553
+ </div>
554
</div>
555
<div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px">
556
<input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)">
@@ -637,7 +688,7 @@
688
if (message.nodes[m][n].rname) { message.nodes[m][n].rnamel = message.nodes[m][n].rname.toLowerCase(); } else { message.nodes[m][n].rnamel = message.nodes[m][n].namel; }
689
message.nodes[m][n].meshnamel = meshes[m].name.toLowerCase();
690
message.nodes[m][n].meshid = m;
640
- message.nodes[m][n].state = (message.nodes[m][n].state)?(message.nodes[m][n].state):0;
691
+ message.nodes[m][n].state = (message.nodes[m][n].state) ? (message.nodes[m][n].state) : 0;
692
message.nodes[m][n].desc = message.nodes[m][n].desc;
693
if (!message.nodes[m][n].icon) message.nodes[m][n].icon = 1;
694
message.nodes[m][n].ident = ++nodeShortIdent;
@@ -883,9 +934,9 @@
934
}
935
936
function updateFooterMenu(options) {
886
- while (options != null && options.length < 3) { options.push( { n:'' } ); }
937
+ while (options != null && options.length < 3) { options.push({ n: '' }); }
938
var x = '', prev = '';
888
- if (options != null) { for (var i in options) { x += '<td style="cursor:pointer' + ((prev == '')?'':';border-left:solid 1px white') + '" onclick="' + options[i].f + '">' + options[i].n; prev = options[i].n; } }
939
+ if (options != null) { for (var i in options) { x += '<td style="cursor:pointer' + ((prev == '') ? '' : ';border-left:solid 1px white') + '" onclick="' + options[i].f + '">' + options[i].n; prev = options[i].n; } }
940
QH('footerMenu', '<tr>' + x);
941
}
942
@@ -986,7 +1037,7 @@
1037
function checkPasswordStrength(password) {
1038
var r = 0, letters = {}, varCount = 0, variations = { digits: /\d/.test(password), lower: /[a-z]/.test(password), upper: /[A-Z]/.test(password), nonWords: /\W/.test(password) }
1039
if (!password) return 0;
989
- for (var i = 0; i< password.length; i++) { letters[password[i]] = (letters[password[i]] || 0) + 1; r += 5.0 / letters[password[i]]; }
1040
+ for (var i = 0; i < password.length; i++) { letters[password[i]] = (letters[password[i]] || 0) + 1; r += 5.0 / letters[password[i]]; }
1041
for (var c in variations) { varCount += (variations[c] == true) ? 1 : 0; }
1042
return parseInt(r + (varCount - 1) * 10);
1043
}
@@ -1078,7 +1129,7 @@
1129
if (filetreelinkpath != '') { filetreelinkpath += '/' + filetreelocation[i]; if (folderdepth > 2) { publicPath += '/' + filetreelocation[i]; } }
1130
}
1131
filetreex = filetreex.f[filetreelocation[i]];
1081
- displayPath += ' / <a style=cursor:pointer onclick=p5folderup(' + folderdepth + ')>' + (filetreex.n != null?filetreex.n:filetreelocation[i]) + '</a>';
1132
+ displayPath += ' / <a style=cursor:pointer onclick=p5folderup(' + folderdepth + ')>' + (filetreex.n != null ? filetreex.n : filetreelocation[i]) + '</a>';
1133
folderdepth++;
1134
} else {
1135
break;
@@ -1108,7 +1159,7 @@
1159
1160
var h = '';
1161
if (f.t < 3 || f.t == 4) {
1111
- var right = (f.t == 1 || f.t == 4)?p5getQuotabar(f):'', title = '';
1162
+ var right = (f.t == 1 || f.t == 4) ? p5getQuotabar(f) : '', title = '';
1163
h = "<div class=filelist file=999><input file=999 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value='" + name + "'> <span style=float:right;padding-right:4px title=\"" + title + "\">" + right + "</span><span><div class=fileIcon" + f.t + "></div><a style=cursor:pointer onclick=p5folderset(\"" + encodeURIComponent(f.nx) + "\")>" + shortname + "</a></span></div>";
1164
} else {
1165
var link = shortname;
@@ -1144,7 +1195,7 @@
1195
while (f.t > 1 && f.t != 4) { f = f.parent; }
1196
if ((f.t != 1 && f.t != 4) || (f.maxbytes == null)) return '';
1197
var tf = Math.floor(f.s / 1024), tq = Math.floor((f.maxbytes - f.s) / 1024);
1147
- return '<span title="' + tf + "k in " + f.c + " file" + (f.c > 1?'s':'') + ". " + (Math.floor(f.maxbytes / 1024)) + 'k maxinum">' + ((tq < 0)?('Storage limit exceed'):(tq + 'k remaining')) + ' <progress style=height:10px;width:100px value=' + f.s + ' max=' + f.maxbytes + ' /></span>';
1198
+ return '<span title="' + tf + "k in " + f.c + " file" + (f.c > 1 ? 's' : '') + ". " + (Math.floor(f.maxbytes / 1024)) + 'k maxinum">' + ((tq < 0) ? ('Storage limit exceed') : (tq + 'k remaining')) + ' <progress style=height:10px;width:100px value=' + f.s + ' max=' + f.maxbytes + ' /></span>';
1199
}
1200
1201
function p5showPublicLink(u) { setDialogMode(2, "Public Link", 1, null, '<input type=text style=width:100% value="' + u + '" readonly />'); }
@@ -1186,22 +1237,22 @@
1237
function p5folderup(x) { if (x == null) { filetreelocation.pop(); } else { while (filetreelocation.length > x) { filetreelocation.pop(); } } updateFiles(); }
1238
function p5folderset(x) { filetreelocation.push(decodeURIComponent(x)); updateFiles(); }
1239
function p5createfolder() { setDialogMode(2, "New Folder", 3, p5createfolderEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% />'); focusTextBox('p5renameinput'); p5fileNameCheck(); }
1189
- function p5createfolderEx() { meshserver.send({ action: 'fileoperation', fileop: 'createfolder', path: filetreelocation, newfolder: Q('p5renameinput').value}); }
1190
- function p5deletefile() { var cc = getFileSelCount(); setDialogMode(2, "Delete", 3, p5deletefileEx, (cc > 1)?('Delete ' + cc + ' selected items?'):('Delete selected item?')); }
1191
- function p5deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(checkboxes[i].value); } } meshserver.send({ action: 'fileoperation', fileop: 'delete', path: filetreelocation, delfiles: delfiles}); }
1192
- function p5renamefile() { var renamefile, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = checkboxes[i].value; } } setDialogMode(2, "Rename", 3, p5renamefileEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'fileoperation', fileop: 'rename', path: filetreelocation, oldname: renamefile}); focusTextBox('p5renameinput'); p5fileNameCheck(); }
1240
+ function p5createfolderEx() { meshserver.send({ action: 'fileoperation', fileop: 'createfolder', path: filetreelocation, newfolder: Q('p5renameinput').value }); }
1241
+ function p5deletefile() { var cc = getFileSelCount(); setDialogMode(2, "Delete", 3, p5deletefileEx, (cc > 1) ? ('Delete ' + cc + ' selected items?') : ('Delete selected item?')); }
1242
+ function p5deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(checkboxes[i].value); } } meshserver.send({ action: 'fileoperation', fileop: 'delete', path: filetreelocation, delfiles: delfiles }); }
1243
+ function p5renamefile() { var renamefile, checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = checkboxes[i].value; } } setDialogMode(2, "Rename", 3, p5renamefileEx, '<input type=text id=p5renameinput maxlength=64 onkeyup=p5fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'fileoperation', fileop: 'rename', path: filetreelocation, oldname: renamefile }); focusTextBox('p5renameinput'); p5fileNameCheck(); }
1244
function p5renamefileEx(b, t) { t.newname = Q('p5renameinput').value; meshserver.send(t); }
1245
function p5fileNameCheck(e) { var x = isFilenameValid(Q('p5renameinput').value); QE('idx_dlgOkButton', x); if ((x == true) && (e.keyCode == 13)) { dialogclose(1); } }
1195
- var isFilenameValid = (function(){ var x1=/^[^\\/:\*\?"<>\|]+$/, x2=/^\./, x3=/^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname){ return x1.test(fname)&&!x2.test(fname)&&!x3.test(fname)&&(fname[0] != '.'); } })();
1246
+ var isFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); } })();
1247
function p5uploadFile() { setDialogMode(2, "Upload File", 3, p5uploadFileEx, '<form method=post enctype=multipart/form-data action=uploadfile.ashx target=fileUploadFrame><input type=text name=link style=display:none id=p5uploadpath value=\"' + encodeURIComponent(filetreelinkpath) + '\" /><input type=file name=files id=p5uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p5uploadinput\')" /><input type=submit id=p5loginSubmit style=display:none /></form>'); updateUploadDialogOk('p5uploadinput'); }
1248
function p5uploadFileEx() { Q('p5loginSubmit').click(); }
1249
function updateUploadDialogOk(x) { QE('idx_dlgOkButton', Q(x).value != ''); }
1250
1251
var p5clipboard = null, p5clipboardFolder = null, p5clipboardCut = 0;
1252
function p5copyFile(cut) { var checkboxes = document.getElementsByName('fc'); p5clipboard = []; p5clipboardCut = cut, p5clipboardFolder = Clone(filetreelocation); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == "3")) { p5clipboard.push(checkboxes[i].value); } } p5updateClipview(); }
1202
- function p5pasteFile() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = 'Confim ' + (p5clipboardCut == 0?'copy':'move') + ' of ' + p5clipboard.length + ' entrie' + ((p5clipboard.length > 1)?'s':'') + ' to this location?' } setDialogMode(2, "Paste", 3, p5pasteFileEx, x); }
1203
- function p5pasteFileEx() { meshserver.send({ action: 'fileoperation', fileop: (p5clipboardCut == 0?'copy':'move'), scpath: p5clipboardFolder, path: filetreelocation, names: p5clipboard }); p5folderup(999); if (p5clipboardCut == 1) { p5clipboard = null, p5clipboardFolder = null, p5clipboardCut = 0; p5updateClipview(); } }
1204
- function p5updateClipview() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = 'Holding ' + p5clipboard.length + ' entrie' + ((p5clipboard.length > 1)?'s':'') + ' for ' + (p5clipboardCut == 0?'copy':'move') + ', <a onclick=p5clearClip() style=cursor:pointer>Clear</a>.' } QH('p5bottomstatus', x); p5setActions(); }
1253
+ function p5pasteFile() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = 'Confim ' + (p5clipboardCut == 0 ? 'copy' : 'move') + ' of ' + p5clipboard.length + ' entrie' + ((p5clipboard.length > 1) ? 's' : '') + ' to this location?' } setDialogMode(2, "Paste", 3, p5pasteFileEx, x); }
1254
+ function p5pasteFileEx() { meshserver.send({ action: 'fileoperation', fileop: (p5clipboardCut == 0 ? 'copy' : 'move'), scpath: p5clipboardFolder, path: filetreelocation, names: p5clipboard }); p5folderup(999); if (p5clipboardCut == 1) { p5clipboard = null, p5clipboardFolder = null, p5clipboardCut = 0; p5updateClipview(); } }
1255
+ function p5updateClipview() { var x = ''; if ((p5clipboard != null) && (p5clipboard.length > 0)) { x = 'Holding ' + p5clipboard.length + ' entrie' + ((p5clipboard.length > 1) ? 's' : '') + ' for ' + (p5clipboardCut == 0 ? 'copy' : 'move') + ', <a onclick=p5clearClip() style=cursor:pointer>Clear</a>.' } QH('p5bottomstatus', x); p5setActions(); }
1256
function p5clearClip() { p5clipboard = null; p5clipboardFolder = null; p5clipboardCut = 0; p5updateClipview(); }
1257
1258
function p5fileDragDrop(e) {
@@ -1216,7 +1267,7 @@
1267
names.push(file.name);
1268
sizes.push(file.size);
1269
types.push(file.type);
1219
- reader.onload = function(event) {
1270
+ reader.onload = function (event) {
1271
datas.push(event.target.result);
1272
if (--readercount == 0) {
1273
Q('p5fileDragName').value = names.join('*');
@@ -1428,7 +1479,7 @@
1479
}
1480
1481
function meshSort(a, b) { if (a.meshnamel > b.meshnamel) return 1; if (a.meshnamel < b.meshnamel) return -1; if (a.meshid == b.meshid) { if (showRealNames == true) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; } else { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; } } return 0; }
1431
- function powerSort(a, b) { var ap = a.pwr?a.pwr:0; var bp = b.pwr?b.pwr:0; if (ap == bp) { if (showRealNames == true) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; } else { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; } } if (ap > bp) return 1; if (ap < bp) return -1; return 0; }
1482
+ function powerSort(a, b) { var ap = a.pwr ? a.pwr : 0; var bp = b.pwr ? b.pwr : 0; if (ap == bp) { if (showRealNames == true) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; } else { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; } } if (ap > bp) return 1; if (ap < bp) return -1; return 0; }
1483
function deviceSort(a, b) { if (a.namel > b.namel) return 1; if (a.namel < b.namel) return -1; return 0; }
1484
function deviceHostSort(a, b) { if (a.rnamel > b.rnamel) return 1; if (a.rnamel < b.rnamel) return -1; return 0; }
1485
@@ -1491,7 +1542,7 @@
1542
}
1543
1544
// Attribute: Description
1494
- var description = node.desc?EscapeHtml(node.desc):"<i>None</i>";
1545
+ var description = node.desc ? EscapeHtml(node.desc) : "<i>None</i>";
1546
if ((meshrights & 4) != 0) {
1547
x += addDeviceAttribute('Description', '<span onclick=showEditNodeValueDialog(2) style=cursor:pointer>' + description + '</span>');
1548
} else {
@@ -1499,7 +1550,7 @@
1550
}
1551
1552
// Attribute: Mesh Agent
1502
- var agentsStr = ['Unknown', 'Windows 32bit console', 'Windows 64bit console', 'Windows 32bit service', 'Windows 64bit service', 'Linux 32bit', 'Linux 64bit', 'MIPS', 'XENx86', 'Android ARM', 'Linux ARM', 'OSX 32bit', 'Android x86', 'PogoPlug ARM', 'Android APK', 'Linux Poky x86-32bit', 'OSX 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' ];
1553
+ var agentsStr = ['Unknown', 'Windows 32bit console', 'Windows 64bit console', 'Windows 32bit service', 'Windows 64bit service', 'Linux 32bit', 'Linux 64bit', 'MIPS', 'XENx86', 'Android ARM', 'Linux ARM', 'OSX 32bit', 'Android x86', 'PogoPlug ARM', 'Android APK', 'Linux Poky x86-32bit', 'OSX 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'];
1554
if ((node.agent != null) && (node.agent.id != null) && (node.agent.ver != null)) {
1555
var str = '';
1556
if (node.agent.id <= agentsStr.length) { str = agentsStr[node.agent.id]; } else { str = agentsStr[0]; }
@@ -1590,7 +1641,7 @@
1641
//if (node.state == 0) { powerstate = 'Unknown State'; }
1642
if ((connectivity & 1) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += '<span style=font-size:10px title="Agent connected">Mesh Agent</span>'; }
1643
if ((connectivity & 2) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += '<span style=font-size:10px title="Intel® AMT connected">Intel® AMT connected</span>'; } else
1593
- if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += '<span style=font-size:10px title="Intel® AMT detected">Intel® AMT detected</span>'; }
1644
+ if ((connectivity & 4) != 0) { if (powerstate.length > 0) { powerstate += ', '; } powerstate += '<span style=font-size:10px title="Intel® AMT detected">Intel® AMT detected</span>'; }
1645
QH('MainComputerState', powerstate);
1646
1647
// Set the node icon
@@ -1613,18 +1664,20 @@
1664
}
1665
1666
function deviceToastFunctionEx() {
1616
- meshserver.send({ action: 'toast', nodeids: [ currentNode._id ], title: 'MeshCentral', msg: Q('d2devToast').value });
1667
+ meshserver.send({ action: 'toast', nodeids: [currentNode._id], title: 'MeshCentral', msg: Q('d2devToast').value });
1668
}
1669
1670
function setupDeviceMenu(op, obj) {
1671
+ var meshrights = 0;
1672
+ if (currentNode) { meshrights = meshes[currentNode.meshid].links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights; }
1673
if (op != null) { currentDevicePanel = op; }
1674
QV('p10general', currentDevicePanel == 0);
1622
- QV('p10desktop', currentDevicePanel == 1);
1675
+ QV('p10desktop', currentDevicePanel == 1); // Show if we have remote control rights or desktop view only rights
1676
QV('p10files', currentDevicePanel == 2);
1677
var menus = [];
1678
if (currentDevicePanel != 0) { menus.push({ n: 'General', f: 'setupDeviceMenu(0)' }); }
1626
- if ((currentDevicePanel != 1) && (currentNode != null) && ((currentNode.mtype == 1) || (currentNode.agent.caps & 1))) { menus.push({ n: 'Desktop', f: 'setupDeviceMenu(1)' }); }
1627
- if ((currentDevicePanel != 2) && (currentNode != null) && ((currentNode.mtype == 2) && (currentNode.agent.caps & 4))) { menus.push({ n: 'Files', f: 'setupDeviceMenu(2)' }); }
1679
+ if ((currentDevicePanel != 1) && (currentNode != null) && ((meshrights & 8) || (meshrights & 256)) && ((currentNode.mtype == 1) || (currentNode.agent.caps & 1))) { menus.push({ n: 'Desktop', f: 'setupDeviceMenu(1)' }); }
1680
+ if ((currentDevicePanel != 2) && (currentNode != null) && (meshrights & 8) && ((currentNode.mtype == 2) && (currentNode.agent.caps & 4))) { menus.push({ n: 'Files', f: 'setupDeviceMenu(2)' }); }
1681
updateFooterMenu(menus);
1682
}
1683
@@ -1644,10 +1697,10 @@
1697
var op = Q('d2deviceop').value;
1698
if (op == 100) {
1699
// Device wake
1647
- meshserver.send({ action: 'wakedevices', nodeids: [ currentNode._id ] });
1700
+ meshserver.send({ action: 'wakedevices', nodeids: [currentNode._id] });
1701
} else {
1702
// Power operation
1650
- meshserver.send({ action: 'poweraction', nodeids: [ currentNode._id ], actiontype: op });
1703
+ meshserver.send({ action: 'poweraction', nodeids: [currentNode._id], actiontype: op });
1704
}
1705
}
1706
@@ -1671,12 +1724,12 @@
1724
// De-compact the timeline
1725
var timeline2 = [];
1726
if (timeline != null && timeline.length > 1) {
1674
- timeline2.push([ 0, timeline[1], timeline[0] ]); // Start, End, Power
1727
+ timeline2.push([0, timeline[1], timeline[0]]); // Start, End, Power
1728
var ct = timeline[1];
1729
for (var i = 2; i < timeline.length; i += 2) {
1730
var power = timeline[i], dt = now;
1731
if (timeline.length > (i + 1)) { dt = timeline[i + 1]; }
1679
- timeline2.push([ ct, ct + dt, power ]); // Start, End, Power
1732
+ timeline2.push([ct, ct + dt, power]); // Start, End, Power
1733
ct = ct + dt;
1734
}
1735
}
@@ -1699,7 +1752,7 @@
1752
}
1753
}
1754
}
1702
- x += '<tr style=' + (((count % 2) == 0)?'background-color:#DDD':'') + '><td><div> ' + date.toLocaleDateString() + '<div></div></div></td><td><div>' + datavalue + '</div></td></tr>';
1755
+ x += '<tr style=' + (((count % 2) == 0) ? 'background-color:#DDD' : '') + '><td><div> ' + date.toLocaleDateString() + '<div></div></div></td><td><div>' + datavalue + '</div></td></tr>';
1756
++count;
1757
date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day
1758
}
@@ -1767,7 +1820,7 @@
1820
}
1821
1822
function p10showDeleteNodeDialogEx(buttons, nodeid) {
1770
- meshserver.send({ action: 'removedevices', nodeids: [ nodeid ] });
1823
+ meshserver.send({ action: 'removedevices', nodeids: [nodeid] });
1824
}
1825
1826
function p10showiconselector() {
@@ -1851,11 +1904,12 @@
1904
var mesh = meshes[currentNode.meshid];
1905
var deskState = 0;
1906
if (desktop != null) { deskState = desktop.State; }
1907
+ var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
1908
1909
// Show the right buttons
1910
QV('disconnectbutton1', (deskState != 0));
1857
- QV('connectbutton1', (deskState == 0) && (mesh.mtype == 2));
1858
- QV('connectbutton1h', (deskState == 0) && ((currentNode.intelamt != null) && (mesh.mtype == 1 || currentNode.intelamt.state == 2) && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))));
1911
+ QV('connectbutton1', (deskState == 0) && (mesh.mtype == 2) && ((meshrights & 8) || (meshrights & 256)));
1912
+ QV('connectbutton1h', (deskState == 0) && ((currentNode.intelamt != null) && (meshrights & 8) && (mesh.mtype == 1 || currentNode.intelamt.state == 2) && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))));
1913
1914
// Show the right settings
1915
QV('d7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))) && ((deskState == 0) || (desktop.contype == 2)));
@@ -1867,14 +1921,17 @@
1921
var hwonline = ((currentNode.conn & 6) != 0); // If CIRA (2) or AMT (4) connected, enable hardware terminal
1922
QE('connectbutton1h', hwonline);
1923
//QE('deskSaveBtn', deskState == 3);
1870
- QE('DeskCAD', deskState == 3);
1871
- QE('DeskWD', deskState == 3);
1872
- QE('deskkeys', deskState == 3);
1873
- QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5));
1874
- QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5));
1875
- QE('DeskToolsButton', online);
1876
- QV('DeskToastButton', (currentNode.agent) && (currentNode.agent.id < 5));
1924
+ //QV('DeskCAD', meshrights & 8);
1925
+ //QE('DeskCAD', deskState == 3);
1926
+ //QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5));
1927
+ //QE('DeskWD', deskState == 3);
1928
+ //QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5));
1929
+ //QE('deskkeys', deskState == 3);
1930
+ //QE('DeskToolsButton', online);
1931
+ QV('DeskToastButton', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
1932
QE('DeskToastButton', online);
1933
+ QV('deskActionsBtn', meshrights & 8);
1934
+ Q('DeskControl').checked = ((meshrights & 8) != 0);
1935
if (online == false) QV('DeskTools', false);
1936
}
1937
@@ -1965,8 +2022,7 @@
2022
}
2023
2024
function applyDesktopSettings() {
1968
- /*
1969
- var r = '', ops = (features & 512)?[90,70,50,40,30,20,10,5,1]:[50,40,30,20,10,5,1];
2025
+ var r = '', ops = (features & 512) ? [90, 70, 50, 40, 30, 20, 10, 5, 1] : [50, 40, 30, 20, 10, 5, 1];
2026
for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
2027
QH('d7bitmapquality', r);
2028
d7desktopmode.value = desktopsettings.encoding;
@@ -1976,7 +2032,6 @@
2032
if (ops.indexOf(parseInt(desktopsettings.quality)) >= 0) { d7bitmapquality.value = desktopsettings.quality; }
2033
d7bitmapscaling.value = desktopsettings.scaling;
2034
if (desktopsettings.framerate) { d7framelimiter.value = desktopsettings.framerate; }
1979
- */
2035
}
2036
2037
var fullscreen = false;
@@ -2025,6 +2080,7 @@
2080
QS('Desk')['margin-bottom'] = x + 'px';
2081
}
2082
2083
+ /*
2084
// Remote desktop special key combos for Windows
2085
function deskSendKeys() {
2086
if (xxdialogMode || desktop == null || desktop.State != 3) return;
@@ -2061,12 +2117,15 @@
2117
}
2118
}
2119
}
2120
+ */
2121
2122
+ /*
2123
// Send CTRL-ALT-DEL
2124
function sendCAD() {
2125
if (xxdialogMode || desktop == null || desktop.State != 3) return;
2126
desktop.m.sendcad();
2127
}
2128
+ */
2129
2130
// Show process dialogs
2131
function toggleDeskTools() {
@@ -2084,7 +2143,7 @@
2143
function refreshDeskTools() {
2144
QV('DeskToolsRefreshButton', false);
2145
setTimeout(refreshDeskToolsEx, 500);
2087
- meshserver.send({ action: 'msg', type:'ps', nodeid: currentNode._id });
2146
+ meshserver.send({ action: 'msg', type: 'ps', nodeid: currentNode._id });
2147
}
2148
function refreshDeskToolsEx() { QV('DeskToolsRefreshButton', true); }
2149
var deskTools = { sort: 1, msg: null };
@@ -2099,10 +2158,10 @@
2158
try { processes = JSON.parse(message.value); } catch (e) { }
2159
console.log(processes);
2160
if (processes != null) {
2102
- for (var pid in processes) { p.push( { p:parseInt(pid), c:processes[pid].cmd, d:processes[pid].cmd.toLowerCase(), u: processes[pid].user } ); }
2161
+ for (var pid in processes) { p.push({ p: parseInt(pid), c: processes[pid].cmd, d: processes[pid].cmd.toLowerCase(), u: processes[pid].user }); }
2162
if (deskTools.sort == 0) { p.sort(sortProcessPid); } else if (deskTools.sort == 1) { p.sort(sortProcessName); }
2163
var x = '';
2105
- for (var i in p) { if (p[i].p != 0) { x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + p[i].p + '</div><a style=float:right;padding-right:5px;cursor:pointer title="Stop process" onclick=stopProcess(' + p[i].p + ',"' + p[i].c + '")><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u?p[i].u:'') + '</div><div>' + p[i].c + '</div></div>'; } }
2164
+ for (var i in p) { if (p[i].p != 0) { x += '<div class=deskToolsBar><div style=width:50px;float:left;text-align:right;padding-right:5px>' + p[i].p + '</div><a style=float:right;padding-right:5px;cursor:pointer title="Stop process" onclick=stopProcess(' + p[i].p + ',"' + p[i].c + '")><img width=10 height=10 src="images/trash.png"></a><div style=float:right;padding-right:5px>' + (p[i].u ? p[i].u : '') + '</div><div>' + p[i].c + '</div></div>'; } }
2165
QH('DeskToolsProcesses', x);
2166
}
2167
}
@@ -2116,7 +2175,7 @@
2175
2176
function deskDisplayInfo(sender, info, selDisplay, selItem) {
2177
var txt = Q('termdisplays').value;
2119
- if (info.length > 0) { var options = ''; for (var x in info) { options += '<option' + ((txt == info[x])?' selected':'') + '>' + info[x] + '</option>'; } QH('termdisplays', options); }
2178
+ if (info.length > 0) { var options = ''; for (var x in info) { options += '<option' + ((txt == info[x]) ? ' selected' : '') + '>' + info[x] + '</option>'; } QH('termdisplays', options); }
2179
QV('termdisplays', info.length > 0);
2180
}
2181
@@ -2128,13 +2187,13 @@
2187
desktop.m.SetDisplay(display);
2188
}
2189
2131
- function dmousedown(e) { if (!xxdialogMode && desktop != null) desktop.m.mousedown(e) }
2132
- function dmouseup(e) { if (!xxdialogMode && desktop != null) desktop.m.mouseup(e) }
2133
- function dmousemove(e) { if (!xxdialogMode && desktop != null) desktop.m.mousemove(e) }
2134
- function dmousewheel(e) { if (!xxdialogMode && desktop != null && desktop.m.mousewheel) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
2190
+ function dmousedown(e) { if ((!xxdialogMode && desktop != null) && Q('DeskControl').checked) desktop.m.mousedown(e) }
2191
+ function dmouseup(e) { if ((!xxdialogMode && desktop != null) && Q('DeskControl').checked) desktop.m.mouseup(e) }
2192
+ function dmousemove(e) { if ((!xxdialogMode && desktop != null) && Q('DeskControl').checked) desktop.m.mousemove(e) }
2193
+ function dmousewheel(e) { if ((!xxdialogMode && desktop != null) && Q('DeskControl').checked && desktop.m.mousewheel) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
2194
function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
2195
function stopProcess(id, name) { setDialogMode(2, "Process Control", 3, stopProcessEx, 'Stop process #' + id + ' "' + name + '"?', id); }
2137
- function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type:'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }
2196
+ function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type: 'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }
2197
2198
//
2199
// FILES
@@ -2145,7 +2204,7 @@
2204
// Setup the files tab
2205
var samenode = (filesNode == currentNode);
2206
filesNode = currentNode;
2148
- var online = ((filesNode.conn & 1) != 0)?true:false; // If Agent (1) connected, enable Terminal
2207
+ var online = ((filesNode.conn & 1) != 0) ? true : false; // If Agent (1) connected, enable Terminal
2208
QE('p13Connect', online);
2209
if (((samenode == false) || (online == false)) && files) { files.Stop(); files = null; }
2210
}
@@ -2176,8 +2235,8 @@
2235
function CreateRemoteFiles(onFileUpdate) {
2236
var obj = { protocol: 5 };
2237
obj.onFileUpdate = onFileUpdate;
2179
- obj.xxStateChange = function(state) { }
2180
- obj.ProcessData = function(data) { obj.onFileUpdate(data); }
2238
+ obj.xxStateChange = function (state) { }
2239
+ obj.ProcessData = function (data) { obj.onFileUpdate(data); }
2240
return obj;
2241
}
2242
@@ -2348,9 +2407,9 @@
2407
function p13selectallfile() { var nv = (p13getFileSelCount() == 0), checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = nv; } p13setActions(); }
2408
function p13createfolder() { setDialogMode(2, "New Folder", 3, p13createfolderEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% />'); focusTextBox('p13renameinput'); p13fileNameCheck(); }
2409
function p13createfolderEx() { files.sendText({ action: 'mkdir', reqid: 1, path: p13filetreelocation.join('/') + '/' + Q('p13renameinput').value }); p13folderup(999); }
2351
- function p13deletefile() { var cc = getFileSelCount(); setDialogMode(2, "Delete", 3, p13deletefileEx, (cc > 1)?('Delete ' + cc + ' selected items?'):('Delete selected item?')); }
2410
+ function p13deletefile() { var cc = getFileSelCount(); setDialogMode(2, "Delete", 3, p13deletefileEx, (cc > 1) ? ('Delete ' + cc + ' selected items?') : ('Delete selected item?')); }
2411
function p13deletefileEx() { var delfiles = [], checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { delfiles.push(p13filetree.dir[checkboxes[i].value].n); } } files.sendText({ action: 'rm', reqid: 1, path: p13filetreelocation.join('/'), delfiles: delfiles }); p13folderup(999); }
2353
- function p13renamefile() { var renamefile, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = p13filetree.dir[checkboxes[i].value].n; } } setDialogMode(2, "Rename", 3, p13renamefileEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'rename', path: p13filetreelocation.join('/'), oldname: renamefile}); focusTextBox('p13renameinput'); p13fileNameCheck(); }
2412
+ function p13renamefile() { var renamefile, checkboxes = document.getElementsByName('fd'); for (var i = 0; i < checkboxes.length; i++) { if (checkboxes[i].checked) { renamefile = p13filetree.dir[checkboxes[i].value].n; } } setDialogMode(2, "Rename", 3, p13renamefileEx, '<input type=text id=p13renameinput maxlength=64 onkeyup=p13fileNameCheck(event) style=width:100% value="' + renamefile + '" />', { action: 'rename', path: p13filetreelocation.join('/'), oldname: renamefile }); focusTextBox('p13renameinput'); p13fileNameCheck(); }
2413
function p13renamefileEx(b, t) { t.newname = Q('p13renameinput').value; files.sendText(t); p13folderup(999); }
2414
function p13fileNameCheck(e) { var x = isFilenameValid(Q('p13renameinput').value); QE('idx_dlgOkButton', x); if ((x == true) && (e != null) && (e.keyCode == 13)) { dialogclose(1); } }
2415
function p13uploadFile() { setDialogMode(2, "Upload File", 3, p13uploadFileEx, '<input type=file name=files id=p13uploadinput style=width:100% multiple=multiple onchange="updateUploadDialogOk(\'p13uploadinput\')" />'); updateUploadDialogOk('p13uploadinput'); }
@@ -2358,9 +2417,9 @@
2417
2418
var p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0;
2419
function p13copyFile(cut) { var checkboxes = document.getElementsByName('fd'); p13clipboard = []; p13clipboardCut = cut, p13clipboardFolder = p13targetpath; for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && (checkboxes[i].attributes.file.value == "3")) { p13clipboard.push(p13filetree.dir[checkboxes[i].value].n); } } p13updateClipview(); }
2361
- function p13pasteFile() { var x = ''; if ((p13clipboard != null) && (p13clipboard.length > 0)) { x = 'Confim ' + (p13clipboardCut == 0?'copy':'move') + ' of ' + p13clipboard.length + ' entrie' + ((p13clipboard.length > 1)?'s':'') + ' to this location?' } setDialogMode(2, "Paste", 3, p13pasteFileEx, x); }
2362
- function p13pasteFileEx() { files.sendText({ action: (p13clipboardCut == 0?'copy':'move'), reqid: 1, scpath: p13clipboardFolder, dspath: p13targetpath, names: p13clipboard }); p13folderup(999); if (p13clipboardCut == 1) { p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0; p13updateClipview(); } }
2363
- function p13updateClipview() { var x = ''; if ((p13clipboard != null) && (p13clipboard.length > 0)) { x = 'Holding ' + p13clipboard.length + ' entrie' + ((p13clipboard.length > 1)?'s':'') + ' for ' + (p13clipboardCut == 0?'copy':'move') + ', <a onclick=p13clearClip() style=cursor:pointer>Clear</a>.' } QH('p13bottomstatus', x); p13setActions(); }
2420
+ function p13pasteFile() { var x = ''; if ((p13clipboard != null) && (p13clipboard.length > 0)) { x = 'Confim ' + (p13clipboardCut == 0 ? 'copy' : 'move') + ' of ' + p13clipboard.length + ' entrie' + ((p13clipboard.length > 1) ? 's' : '') + ' to this location?' } setDialogMode(2, "Paste", 3, p13pasteFileEx, x); }
2421
+ function p13pasteFileEx() { files.sendText({ action: (p13clipboardCut == 0 ? 'copy' : 'move'), reqid: 1, scpath: p13clipboardFolder, dspath: p13targetpath, names: p13clipboard }); p13folderup(999); if (p13clipboardCut == 1) { p13clipboard = null, p13clipboardFolder = null, p13clipboardCut = 0; p13updateClipview(); } }
2422
+ function p13updateClipview() { var x = ''; if ((p13clipboard != null) && (p13clipboard.length > 0)) { x = 'Holding ' + p13clipboard.length + ' entrie' + ((p13clipboard.length > 1) ? 's' : '') + ' for ' + (p13clipboardCut == 0 ? 'copy' : 'move') + ', <a onclick=p13clearClip() style=cursor:pointer>Clear</a>.' } QH('p13bottomstatus', x); p13setActions(); }
2423
function p13clearClip() { p13clipboard = null; p13clipboardFolder = null; p13clipboardCut = 0; p13updateClipview(); }
2424
function updateUploadDialogOk(x) { QE('idx_dlgOkButton', Q(x).value != ''); }
2425
function getFileSelCount(includeDirs) { var cc = 0; var checkboxes = document.getElementsByName('fc'); for (var i = 0; i < checkboxes.length; i++) { if ((checkboxes[i].checked) && ((includeDirs != false) || (checkboxes[i].attributes.file.value == "3"))) cc++; } return cc; }
@@ -2512,7 +2571,7 @@
2571
Q('d2progressBar').value = 0;
2572
2573
uploadFile.xreader = new FileReader();
2515
- uploadFile.xreader.onload = function() {
2574
+ uploadFile.xreader.onload = function () {
2575
uploadFile.xdata = uploadFile.xreader.result;
2576
uploadFile.ws.sendText({ action: 'upload', reqid: uploadFile.xfilePtr, path: uploadFile.xpath, name: file.name, size: uploadFile.xdata.byteLength });
2577
};
@@ -2581,7 +2640,7 @@
2640
2641
var x = '';
2642
x += addHtmlValue('Name', addLinkConditional(EscapeHtml(currentMesh.name), 'p20editmesh(1)', (meshrights & 1) != 0));
2584
- x += addHtmlValue('Description', addLinkConditional(((currentMesh.desc && currentMesh.desc != '')?EscapeHtml(currentMesh.desc):'<i>None</i>'), 'p20editmesh(2)', (meshrights & 1) != 0));
2643
+ x += addHtmlValue('Description', addLinkConditional(((currentMesh.desc && currentMesh.desc != '') ? EscapeHtml(currentMesh.desc) : '<i>None</i>'), 'p20editmesh(2)', (meshrights & 1) != 0));
2644
x += addHtmlValue('Type', meshtype);
2645
//x += addHtmlValue('Identifier', currentMesh._id.split('/')[2]);
2646
@@ -2623,14 +2682,14 @@
2682
// Sort the users for this mesh
2683
var count = 1, sortedusers = [];
2684
for (var i in currentMesh.links) { sortedusers.push({ id: i, name: i.split('/')[2], rights: currentMesh.links[i].rights }); }
2626
- sortedusers.sort(function(a, b) { if (a.name > b.name) return 1; if (a.name < b.name) return -1; return 0; });
2685
+ sortedusers.sort(function (a, b) { if (a.name > b.name) return 1; if (a.name < b.name) return -1; return 0; });
2686
2687
// Display all users for this mesh
2688
for (var i in sortedusers) {
2689
var trash = '', rights = 'Partial Rights', r = sortedusers[i].rights;
2690
if (r == 0xFFFFFFFF) rights = 'Full Administrator'; else if (r == 0) rights = 'No Rights';
2691
if ((i != userinfo._id) && (meshrights == 0xFFFFFFFF || (((meshrights & 2) != 0)))) { trash = '<a onclick=p20deleteUser(event,"' + encodeURIComponent(sortedusers[i].id) + '") title="Remote user rights to this mesh" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
2633
- x += '<tr onclick=p20viewuser("' + encodeURIComponent(sortedusers[i].id) + '") style=height:32px;cursor:pointer' + (((count % 2) == 0)?';background-color:#DDD':'') + '><td>';
2692
+ x += '<tr onclick=p20viewuser("' + encodeURIComponent(sortedusers[i].id) + '") style=height:32px;cursor:pointer' + (((count % 2) == 0) ? ';background-color:#DDD' : '') + '><td>';
2693
x += '<div style=float:right>' + trash + '</div><div style=float:right;padding-right:4px>' + rights + '</div><div class=m2></div><div> ' + sortedusers[i].name + '<div></div></div>';
2694
x += '</td></tr>';
2695
++count;
@@ -2693,6 +2752,7 @@
2752
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshserverfiles>Server Files<br>';
2753
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20wakedevices>Wake Devices<br>';
2754
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editnotes>Edit Device Notes<br>';
2755
+ x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview>Remote View Only<br>';
2756
x += '</div>';
2757
setDialogMode(2, "Add User to Mesh", 3, p20showAddMeshUserDialogEx, x);
2758
p20validateAddMeshUserDialog();
@@ -2711,6 +2771,7 @@
2771
QE('p20meshserverfiles', !Q('p20fulladmin').checked);
2772
QE('p20wakedevices', !Q('p20fulladmin').checked);
2773
QE('p20editnotes', !Q('p20fulladmin').checked);
2774
+ QE('p20remoteview', !Q('p20fulladmin').checked);
2775
}
2776
2777
function p20showAddMeshUserDialogEx() {
@@ -2724,8 +2785,9 @@
2785
if (Q('p20meshserverfiles').checked == true) meshadmin += 32;
2786
if (Q('p20wakedevices').checked == true) meshadmin += 64;
2787
if (Q('p20editnotes').checked == true) meshadmin += 128;
2788
+ if (Q('p20remoteview').checked == true) meshadmin += 256;
2789
}
2728
- meshserver.send({ action: 'addmeshuser', meshid: currentMesh._id, meshname: currentMesh.name, username: Q('dp20username').value , meshadmin: meshadmin});
2790
+ meshserver.send({ action: 'addmeshuser', meshid: currentMesh._id, meshname: currentMesh.name, username: Q('dp20username').value, meshadmin: meshadmin });
2791
}
2792
2793
function p20viewuser(userid) {
@@ -2733,13 +2795,13 @@
2795
userid = decodeURIComponent(userid);
2796
var r = '', cmeshrights = currentMesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights, meshrights = currentMesh.links[userid].rights;
2797
if (meshrights == 0xFFFFFFFF) r = ', Full Administrator'; else {
2736
- if ((meshrights & 1) != 0) r += ', Edit Device Group';
2737
- if ((meshrights & 2) != 0) r += ', Manage Device Group Users';
2738
- if ((meshrights & 4) != 0) r += ', Manage Device Group Computers';
2739
- if ((meshrights & 8) != 0) r += ', Remote Control';
2740
- if ((meshrights & 16) != 0) r += ', Agent Console';
2741
- if ((meshrights & 32) != 0) r += ', Server Files';
2742
- if ((meshrights & 64) != 0) r += ', Wake Devices';
2798
+ if ((meshrights & 1) != 0) r += ', Edit Device Group';
2799
+ if ((meshrights & 2) != 0) r += ', Manage Device Group Users';
2800
+ if ((meshrights & 4) != 0) r += ', Manage Device Group Computers';
2801
+ if ((meshrights & 8) != 0) r += ', Remote Control';
2802
+ if ((meshrights & 16) != 0) r += ', Agent Console';
2803
+ if ((meshrights & 32) != 0) r += ', Server Files';
2804
+ if ((meshrights & 64) != 0) r += ', Wake Devices';
2805
if ((meshrights & 128) != 0) r += ', Edit Notes';
2806
}
2807
r = r.substring(2);
@@ -2752,7 +2814,7 @@
2814
2815
function p20viewuserEx(button, userid) { if (button != 2) return; setDialogMode(2, "Remote Mesh User", 3, p20viewuserEx2, "Confirm removal of user " + userid.split('/')[2] + "?", userid); }
2816
function p20deleteUser(e, userid) { haltEvent(e); p20viewuserEx(2, decodeURIComponent(userid)); }
2755
- function p20viewuserEx2(button, userid) { meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid}); }
2817
+ function p20viewuserEx2(button, userid) { meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid }); }
2818
2819
//
2820
// PANELS
@@ -2820,8 +2882,8 @@
2882
function passwordcheck(p) { var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()]).{8,}/; return re.test(p); }
2883
function getFileSizeStr(size) { if (size == 1) return "1 byte"; return "" + size + " bytes"; }
2884
function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); }
2823
- function focusTextBox(x) { setTimeout(function(){ Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); }
2824
- var isFilenameValid = (function(){ var x1=/^[^\\/:\*\?"<>\|]+$/, x2=/^\./, x3=/^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname){ return x1.test(fname)&&!x2.test(fname)&&!x3.test(fname)&&(fname[0] != '.'); } })();
2885
+ function focusTextBox(x) { setTimeout(function () { Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); }
2886
+ var isFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); } })();
2887
2888
</script>
2889
</body>
views/default.handlebars
+31
-15
@@ -236,7 +236,7 @@
236
<div id=p2 style="display:none">
237
<h1>My Account</h1>
238
<div id="p2AccountActions">
239
- <p><strong><img alt="" width=150 height=103 src=images/mainaccount.png style=margin-bottom:10px;margin-right:20px;float:right />Account actions</strong></p>
239
+ <p><strong><img alt="" width=150 height=103 src=images/mainaccount.jpg style=margin-bottom:10px;margin-right:20px;float:right />Account actions</strong></p>
240
<p style="margin-left:40px">
241
<span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a><br /></span>
242
<a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a><br />
@@ -462,7 +462,7 @@
462
</select>
463
<input id="DeskWD" type=button value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()">
464
<input id="DeskCAD" style="margin-left:6px" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()">
465
- <span style="margin-left:6px" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()">Input</span>
465
+ <span id="DeskControlSpan" style="margin-left:6px" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()">Input</span>
466
</div>
467
</td>
468
</tr>
@@ -662,7 +662,10 @@
662
<div id=p16events style="max-height:calc(100vh - 267px);overflow-y:auto"></div>
663
</div>
664
<div id=p20 style="display:none">
665
- <img id=MainMeshImage src="images/mesh-200.png" style=border-width:0px;height:200px;width:200px;float:right>
665
+ <picture id=MainMeshImage style=border-width:0px;height:200px;width:200px;float:right>
666
+ <source type="image/webp" width=200 height=200 srcset="images/webp/mesh-200.webp">
667
+ <img alt="" width=200 height=200 src=images/mesh-200.jpg />
668
+ </picture>
669
<div style="float:left"><div class="backButton" onclick=goBack() title="Back"><div class="backButtonEx"></div></div></div>
670
<h1>General - <span id=p20meshName></span></h1>
671
<p id=p20info></p>
@@ -679,7 +682,10 @@
682
</td>
683
<td style=width:20px></td>
684
<td style=width:200px>
682
- <img id=MainUserImage src="images/user-200.png" style=border-width:0px;height:200px;width:200px>
685
+ <picture id=MainUserImage style=border-width:0px;height:200px;width:200px;float:right>
686
+ <source type="image/webp" width=200 height=200 srcset="images/webp/user-200.webp">
687
+ <img alt="" width=200 height=200 src=images/user-200.jpg />
688
+ </picture>
689
<div style="width:100%;text-align:center"><strong><span id=MainUserState></span></strong></div>
690
</td>
691
</tr>
@@ -890,6 +896,7 @@
896
var hide = parseInt(args.hide);
897
QV('masthead', !(hide & 1));
898
QV('topbarmaster', !(hide & 2));
899
+ QV('page_leftbar', !(hide & 2));
900
QV('footer', !(hide & 4));
901
QV('p10title', !(hide & 8));
902
QV('p11title', !(hide & 8));
@@ -1068,6 +1075,7 @@
1075
QV('p2ServerActionsRestore', siteRights & 4);
1076
QV('p2ServerActionsVersion', siteRights & 16);
1077
QV('MainMenuMyFiles', siteRights & 8);
1078
+ QV('LeftMenuMyFiles', siteRights & 8);
1079
if (((siteRights & 8) == 0) && (xxcurrentView == 5)) { setDialogMode(0); go(1); }
1080
if (currentNode != null) { gotoDevice(currentNode._id, xxcurrentView, true); }
1081
@@ -1753,7 +1761,7 @@
1761
r += '<div style=float:left;height:18px;width:18px;background-color:white onclick=gotoDevice(\'' + nodes[i]._id + '\')><div class=j' + icon + ' style=width:16px;margin-top:1px;margin-left:2px;height:16px></div></div>';
1762
r += '<div class=g1 style=height:18px;float:left></div><div class=g2 style=height:18px;float:right></div>';
1763
r += '<div style=cursor:pointer;font-size:14px title="' + title + '" onclick=gotoDevice(\'' + nodes[i]._id + '\')><span style=float:right>' + nodestate + '</span><span style=width:300px>' + name + '</span></div></div></td></tr>';
1756
- } else if ((view == 3) && (nodes[i].conn & 1) && ((meshrights & 8) != 0) && ((nodes[i].agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM.
1764
+ } else if ((view == 3) && (nodes[i].conn & 1) && (((meshrights & 8) || (meshrights & 256)) != 0) && ((nodes[i].agent.caps & 1) != 0)) { // Check if we have rights and agent is capable of KVM.
1765
if ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + nodes[i]._id) >= 0)) {
1766
r += '<div id=devs style=display:inline-block;margin:1px;background-color:lightgray;border-radius:5px;position:relative><div style=padding:3px;cursor:pointer onclick=gotoDevice(\'' + nodes[i]._id + '\',11)>';
1767
//r += '<input class="' + nodes[i].meshid + ' DeviceCheckbox" onclick=p1updateInfo() value=devid_' + nodes[i]._id + ' type=checkbox style=float:left>';
@@ -1914,7 +1922,7 @@
1922
1923
function toggleKvmDevice(nodeid) {
1924
var node = getNodeFromId(nodeid), mesh = meshes[node.meshid], meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
1917
- if ((meshrights & 8) != 0) { // Requires remote control rights
1925
+ if ((meshrights & 8) || (meshrights & 256)) { // Requires remote control rights or desktop view only rights
1926
//var conn = 0;
1927
//if ((node.conn & 1) != 0) { conn = 1; } else if ((node.conn & 6) != 0) { conn = 2; } // Check what type of connect we can do (Agent vs AMT)
1928
if (node.conn & 1) { connectMultiDesktop(node, 1); }
@@ -2375,7 +2383,7 @@
2383
var meshlinks = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()];
2384
var meshrights = meshlinks.rights;
2385
var consoleRights = ((meshrights & 16) != 0);
2378
- QV('cxdesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8));
2386
+ QV('cxdesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && ((meshrights & 8) || (meshrights & 256)));
2387
QV('cxterminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8));
2388
QV('cxfiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (meshrights & 8));
2389
QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (meshrights & 8));
@@ -3199,7 +3207,7 @@
3207
QH('MainComputerState', powerstate);
3208
3209
// Set the node icon
3202
- Q('MainComputerImage').setAttribute("src", "images/icons200-" + node.icon + "-1.png");
3210
+ Q('MainComputerImage').setAttribute("src", "images/icons200-" + node.icon + "-1.jpg");
3211
Q('MainComputerImage').className = ((!node.conn) || (node.conn == 0)?'gray':'');
3212
3213
// Setup/Refresh the desktop tab
@@ -3211,7 +3219,7 @@
3219
// Show or hide the tabs
3220
// mesh.mtype: 1 = Intel AMT only, 2 = Mesh Agent
3221
// node.agent.caps (bitmask): 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console
3214
- QV('MainDevDesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8));
3222
+ QV('MainDevDesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && ((meshrights & 8) || (meshrights & 256)));
3223
QV('MainDevTerminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8));
3224
QV('MainDevFiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (meshrights & 8));
3225
QV('MainDevAmt', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (meshrights & 8));
@@ -3623,11 +3631,12 @@
3631
var mesh = meshes[currentNode.meshid];
3632
var deskState = 0;
3633
if (desktop != null) { deskState = desktop.State; }
3634
+ var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
3635
3636
// Show the right buttons
3637
QV('disconnectbutton1span', (deskState != 0));
3629
- QV('connectbutton1span', (deskState == 0) && (mesh.mtype == 2) && (currentNode.agent.caps & 1));
3630
- QV('connectbutton1hspan', (deskState == 0) && ((currentNode.intelamt != null) && (mesh.mtype == 1 || currentNode.intelamt.state == 2) && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))));
3638
+ QV('connectbutton1span', (deskState == 0) && ((meshrights & 8) || (meshrights & 256)) && (mesh.mtype == 2) && (currentNode.agent.caps & 1));
3639
+ QV('connectbutton1hspan', (deskState == 0) && (meshrights & 8) && ((currentNode.intelamt != null) && (mesh.mtype == 1 || currentNode.intelamt.state == 2) && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))));
3640
3641
// Show the right settings
3642
QV('d7amtkvm', (currentNode.intelamt != null && ((currentNode.intelamt.ver != null) || (mesh.mtype == 1))) && ((deskState == 0) || (desktop.contype == 2)));
@@ -3640,14 +3649,18 @@
3649
QE('connectbutton1h', hwonline);
3650
QE('deskSaveBtn', deskState == 3);
3651
QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (deskState != 0) && (desktopsettings.showfocus));
3652
+ QV('DeskCAD', meshrights & 8);
3653
QE('DeskCAD', deskState == 3);
3654
+ QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
3655
QE('DeskWD', deskState == 3);
3656
+ QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
3657
QE('deskkeys', deskState == 3);
3646
- QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5));
3647
- QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5));
3658
+ QV('DeskToolsButton', meshrights & 8);
3659
QE('DeskToolsButton', online);
3649
- QV('DeskToastButton', (currentNode.agent) && (currentNode.agent.id < 5));
3660
+ QV('DeskToastButton', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
3661
QE('DeskToastButton', online);
3662
+ QV('DeskControlSpan', meshrights & 8)
3663
+ if (meshrights & 8) { Q('DeskControl').checked = (getstore('DeskControl', 1) == 1); } else { Q('DeskControl').checked = false; }
3664
if (online == false) QV('DeskTools', false);
3665
}
3666
@@ -5072,7 +5085,7 @@
5085
//x += addHtmlValue('Identifier', currentMesh._id.split('/')[2]);
5086
5087
// Display group note support
5075
- x += '<br><input type=button value=Notes title="View notes about this device group" onclick=showNotes(false,"' + encodeURIComponent(currentMesh._id) + '") />';
5088
+ if (meshrights & 1) { x += '<br><input type=button value=Notes title="View notes about this device group" onclick=showNotes(false,"' + encodeURIComponent(currentMesh._id) + '") />'; }
5089
5090
x += '<br style=clear:both><br>';
5091
var currentMeshLinks = currentMesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()];
@@ -5192,6 +5205,7 @@
5205
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshserverfiles>Server Files<br>';
5206
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20wakedevices>Wake Devices<br>';
5207
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editnotes>Edit Device Notes<br>';
5208
+ x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview>Remote View Only<br>';
5209
x += '</div>';
5210
setDialogMode(2, "Add User to Device Group", 3, p20showAddMeshUserDialogEx, x);
5211
p20validateAddMeshUserDialog();
@@ -5210,6 +5224,7 @@
5224
QE('p20meshserverfiles', !Q('p20fulladmin').checked);
5225
QE('p20wakedevices', !Q('p20fulladmin').checked);
5226
QE('p20editnotes', !Q('p20fulladmin').checked);
5227
+ QE('p20remoteview', !Q('p20fulladmin').checked);
5228
}
5229
5230
function p20showAddMeshUserDialogEx() {
@@ -5223,6 +5238,7 @@
5238
if (Q('p20meshserverfiles').checked == true) meshadmin += 32;
5239
if (Q('p20wakedevices').checked == true) meshadmin += 64;
5240
if (Q('p20editnotes').checked == true) meshadmin += 128;
5241
+ if (Q('p20remoteview').checked == true) meshadmin += 256;
5242
}
5243
meshserver.send({ action: 'addmeshuser', meshid: currentMesh._id, meshname: currentMesh.name, username: Q('dp20username').value , meshadmin: meshadmin});
5244
}
views/login.handlebars
+4
-1
@@ -110,7 +110,10 @@
110
<table id="centralTable" style=width:100%>
111
<tr>
112
<td id="welcomeimage" align="right">
113
- <img alt="" height=310 src=images/mainwelcome.png width=359 />
113
+ <picture>
114
+ <source type="image/webp" width=359 height=310 srcset="images/webp/mainwelcome.webp">
115
+ <img alt="" width=359 height=310 src=images/mainwelcome.jpg />
116
+ </picture>
117
</td>
118
<td id="logincell" align="left">
119
<div id=loginpanel style="background-color: #979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none">
webserver.js
+2
-2
@@ -1817,13 +1817,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1817
// Server picture
1818
obj.app.get(url + 'serverpic.ashx', function (req, res) {
1819
// Check if we have "server.png" in the data folder, if so, use that.
1820
- var p = obj.path.join(obj.parent.datapath, 'server.png');
1820
+ var p = obj.path.join(obj.parent.datapath, 'server.jpg');
1821
if (obj.fs.existsSync(p)) {
1822
// Use the data folder server picture
1823
try { res.sendFile(p); } catch (e) { res.sendStatus(404); }
1824
} else {
1825
// Use the default server picture
1826
- try { res.sendFile(obj.path.join(__dirname, 'public/images/server-200.png')); } catch (e) { res.sendStatus(404); }
1826
+ try { res.sendFile(obj.path.join(__dirname, 'public/images/server-200.jpg')); } catch (e) { res.sendStatus(404); }
1827
}
1828
});
1829