Added Webkit download bug workaround.

This commit is contained in:
Ylian Saint-Hilaire 2020-10-02 13:17:53 -07:00
parent 038c61c1f1
commit dfe4273baf
4 changed files with 79 additions and 64 deletions

View File

@ -204,9 +204,9 @@ module.exports.CreateMeshDeviceFile = function (parent, ws, res, req, domain, us
if ((cmd == null) || (typeof cmd.op == 'string')) {
if (cmd.op == 'ok') {
if (typeof cmd.size == 'number') {
this.res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + require('path').basename(this.file) + '"', 'Content-Length': cmd.size });
this.res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + require('path').basename(this.file) + '"', 'Content-Length': cmd.size });
} else {
this.res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + require('path').basename(this.file) + '"' });
this.res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + require('path').basename(this.file) + '"' });
}
} else {
try { this.res.sendStatus(401); } catch (ex) { }

View File

@ -53,7 +53,7 @@ module.exports.CreateRedirServer = function (parent, db, args, func) {
obj.app.get('/MeshServerRootCert.cer', function (req, res) {
// The redirection server starts before certificates are loaded, make sure to handle the case where no certificate is loaded now.
if (obj.certificates != null) {
res.set({ 'Cache-Control': "no-cache, no-store, must-revalidate", "Pragma": "no-cache", "Expires": "0", "Content-Type": "application/octet-stream", "Content-Disposition": "attachment; filename=\"" + obj.certificates.RootName + ".cer\"" });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + obj.certificates.RootName + '.cer"' });
var rootcert = obj.certificates.root.cert;
var i = rootcert.indexOf('-----BEGIN CERTIFICATE-----\r\n');
if (i >= 0) { rootcert = rootcert.substring(i + 29); }

View File

@ -1212,6 +1212,7 @@
<form style="display:none" method=post action=uploadfile.ashx enctype=multipart/form-data target=fileUploadFrame><input id=p5fileDragName name="name" /><input id=p5fileDragAuthCookie name="auth" /><input id=p5fileDragSize name="size" /><input id=p5fileDragType name="type" /><input id=p5fileDragData name="data" /><input id=p5fileDragLink name="link" /><input type=submit id=p5loginSubmit2 style="display:none" /></form>
<form style="display:none" method=post action=uploadnodefile.ashx enctype=multipart/form-data target=fileUploadFrame><input id=p13fileDragName name="name" /><input id=p13fileDragSize name="size" /><input id=p13fileDragType name="type" /><input id=p13fileDragData name="data" /><input id=p13fileDragLink name="link" /><input type=submit id=p13loginSubmit2 style="display:none" /></form>
<audio id="chimes"><source src="sounds/chimes.mp3" type="audio/mp3" /></audio>
<iframe style=display:none name="fileDownloadFrame"></iframe>
</div>
<script type="text/javascript" nonce="abc">
'use strict';
@ -4116,14 +4117,14 @@
// Setup CIRA using a MeshCommander script (Pretty Simple)
x += '<div id=dlgAddCira0>' + format("To add a new Intel&reg; AMT device to device group \"{0}\" with CIRA, download the following script files and use <a href='http://meshcommander.com' rel='noreferrer noopener' target='_blank'>MeshCommander</a> to run the script to configure computers.", EscapeHtml(mesh.name)) + '<br /><br />';
//x += addHtmlValue('Setup CIRA', '<a href="mescript.ashx?type=1' + (urlargs.key?('&key=' + urlargs.key):'') + '&meshid=' + meshidx.substring(0, 16) + '" download>cira_setup.mescript</a>');
x += addHtmlValue("Setup CIRA", '<a href="mescript.ashx?type=1' + (urlargs.key?('&key=' + urlargs.key):'') + '&meshid=' + meshid + '" download>cira_setup.mescript</a>');
x += addHtmlValue("Cleanup CIRA", '<a href="mescript.ashx?type=2' + (urlargs.key?('&key=' + urlargs.key):'') + '" download>cira_clean.mescript</a>');
x += addHtmlValue("Setup CIRA", '<a onclick=downloadFile("mescript.ashx?type=1' + (urlargs.key?('&key=' + urlargs.key):'') + '&meshid=' + meshid + '")>cira_setup.mescript</a>');
x += addHtmlValue("Cleanup CIRA", '<a onclick=downloadFile("mescript.ashx?type=2' + (urlargs.key?('&key=' + urlargs.key):'') + '")>cira_clean.mescript</a>');
x += '</div>';
// Setup CIRA with user/pass authentication (Somewhat difficult)
x += '<div id=dlgAddCira1 style=display:none>' + format("To add a new Intel&reg; AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel&reg; AMT", EscapeHtml(mesh.name));
if (serverinfo.mpspass) { x += (" and authenticate to the server using this username and password." + '<br /><br />'); } else { x += (" and authenticate to the server using this username and any password." + '<br /><br />'); }
x += addHtmlValue("Root Certificate", '<a href="' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '" download>' + "Root Certificate File" + '</a>');
x += addHtmlValue("Root Certificate", '<a onclick=downloadFile("' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '")>' + "Root Certificate File" + '</a>');
x += addHtmlValue("Username", '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
if (serverinfo.mpspass) { x += addHtmlValue("Password", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
if (serverinfo != null) { x += addHtmlValue("MPS Server", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
@ -4132,7 +4133,7 @@
// Setup CIRA with certificate authentication (Really difficult, only if TLS offload is not used)
if ((features & 16) == 0) {
x += '<div id=dlgAddCira2 style=display:none>' + format("To add a new Intel&reg; AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel&reg; AMT, authenticate using a client certificate with the following common name and connect to the following server.", EscapeHtml(mesh.name)) + '<br /><br />';
x += addHtmlValue("Root Certificate", '<a href="' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '" download>' + "Root Certificate File" + '</a>');
x += addHtmlValue("Root Certificate", '<a onclick=downloadFile("' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '")>' + "Root Certificate File" + '</a>');
x += addHtmlValue("Organization", '<input style=width:230px readonly value="' + meshidx + '" />');
if (serverinfo != null) { x += addHtmlValue("MPS Server", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
x += '</div>';
@ -4242,9 +4243,9 @@
// Windows agent install
x += '<div id=agins_windows>' + format("To add a new computer to device group \"{0}\", download the mesh agent and install it the computer to manage. This agent has server and device group information embedded within it.", EscapeHtml(mesh.name)) + '<br /><br />';
x += addHtmlValue("Mesh Agent", '<a id=aginsw32lnk href="meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '" download onclick="setDialogMode(0)" title="' + "32bit version of the MeshAgent" + '">' + "Windows (.exe)" + '</a> <img src=images/link4.png height=10 width=10 title="' + "Copy Windows 32bit agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
x += addHtmlValue("Mesh Agent", '<a id=aginsw64lnk href="meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '" download onclick="setDialogMode(0)" title="' + "64bit version of the MeshAgent" + '">' + "Windows x64 (.exe)" + '</a> <img src=images/link4.png height=10 width=10 title="' + "Copy Windows 64bit agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
if (debugmode > 0) { x += addHtmlValue("Settings File", '<a id=aginswmshlnk href="meshsettings?id=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '" download rel="noreferrer noopener" target="_blank">' + format("{0} settings (.msh)", EscapeHtml(mesh.name)) + '</a>'); }
x += addHtmlValue("Mesh Agent", '<a id=aginsw32lnk name="meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '" title="' + "32bit version of the MeshAgent" + '">' + "Windows (.exe)" + '</a> <img src=images/link4.png height=10 width=10 title="' + "Copy Windows 32bit agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=3&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
x += addHtmlValue("Mesh Agent", '<a id=aginsw64lnk name="meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '" title="' + "64bit version of the MeshAgent" + '">' + "Windows x64 (.exe)" + '</a> <img src=images/link4.png height=10 width=10 title="' + "Copy Windows 64bit agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=4&meshid=' + meshid.split('/')[2] + '&installflags=",1)>');
if (debugmode > 0) { x += addHtmlValue("Settings File", '<a id=aginswmshlnk name="meshsettings?id=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '">' + format("{0} settings (.msh)", EscapeHtml(mesh.name)) + '</a>'); }
x += '</div>';
// Linux agent install
@ -4254,13 +4255,13 @@
// macOS agent install
x += '<div id=agins_osx style=display:none>' + format("To add a new computer to device group \"{0}\", download the mesh agent and install it the computer to manage. This agent installer has server and device group information embedded within it.", EscapeHtml(mesh.name)) + '<br /><br />';
x += addHtmlValue("Mesh Agent", '<a href="meshosxagent?id=16&meshid=' + meshid.split('/')[2] + (urlargs.key?('&key=' + urlargs.key):'') + '" download rel="noreferrer noopener" target="_blank" title="' + "64bit version of macOS Mesh Agent" + '">macOS Agent (64bit)</a> <img src=images/link4.png height=10 width=10 title="' + "Copy macOS agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '",0)>');
x += addHtmlValue("Mesh Agent", '<a onclick=downloadFile("meshosxagent?id=16&meshid=' + meshid.split('/')[2] + (urlargs.key?('&key=' + urlargs.key):'') + '") title="' + "64bit version of macOS Mesh Agent" + '">macOS Agent (64bit)</a> <img src=images/link4.png height=10 width=10 title="' + "Copy macOS agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '",0)>');
x += '</div>';
// Windows agent uninstall
x += '<div id=agins_windows_un style=display:none>' + "To remove a mesh agent, download the file below, run it and click \"uninstall\"." + '<br /><br />';
x += addHtmlValue("Mesh Agent", '<a href="meshagents?id=3' + (urlargs.key?('&key=' + urlargs.key):'') + '" download onclick="setDialogMode(0)" title="' + "32bit version of the MeshAgent" + '">' + "Windows (.exe)" + '</a>');
x += addHtmlValue("Mesh Agent", '<a href="meshagents?id=4' + (urlargs.key?('&key=' + urlargs.key):'') + '" download onclick="setDialogMode(0)" title="' + "64bit version of the MeshAgent" + '">' + "Windows x64 (.exe)" + '</a>');
x += addHtmlValue("Mesh Agent", '<a onclick=downloadFile("meshagents?id=3' + (urlargs.key?('&key=' + urlargs.key):'') + '",null,true) title="' + "32bit version of the MeshAgent" + '">' + "Windows (.exe)" + '</a>');
x += addHtmlValue("Mesh Agent", '<a onclick=downloadFile("meshagents?id=4' + (urlargs.key?('&key=' + urlargs.key):'') + '",null,true) title="' + "64bit version of the MeshAgent" + '">' + "Windows x64 (.exe)" + '</a>');
x += '</div>';
// Linux agent uninstall
@ -4270,7 +4271,7 @@
// Linux binary installer
x += '<div id=agins_linux_inst style=display:none>' + "This is a executable on OS's with graphical user interfaces. You need to 'chmod +x meshagent' and run this file." + '<br /><br />';
x += addHtmlValue("Mesh Agent", '<a id=aginsbinlnk href="meshagents?id=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '" download onclick="setDialogMode(0)">' + "meshagent" + '</a> <img src=images/link4.png height=10 width=10 title="' + "Copy agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=' + meshid.split('/')[2] + '&installflags=",1)>');
x += addHtmlValue("Mesh Agent", '<a id=aginsbinlnk name="meshagents?id=' + meshid.split('/')[2] + '&installflags=0' + (urlargs.key?('&key=' + urlargs.key):'') + '">' + "meshagent" + '</a> <img src=images/link4.png height=10 width=10 title="' + "Copy agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentUrl("meshagents?id=' + meshid.split('/')[2] + '&installflags=",1)>');
x += addHtmlValue("Command", '<input id=aginsbincmd type=text style="width:216px" readonly value=\'wget -O meshagent' + (((features & 0x80000000) != 0)?' --no-check-certificate':'') + ' \"https://' + servername + portStr + domainUrl + 'meshagents?id=' + meshid.split('/')[2].split('$').join('%24').split('@').join('%40') + '\' /> <img src=images/link4.png height=10 width=10 title="' + "Copy agent URL to clipboard" + '" style=cursor:pointer onclick=copyAgentIdValue("aginsbincmd")>');
x += '</div>';
@ -4312,7 +4313,6 @@
function copyAgentIdValue(id) { copyTextToClip(Q(id).value); }
function copyAgentUrl(url,addflag) {
console.log('copyAgentUrl', url, addflag);
var servername = serverinfo.name;
if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
@ -4333,14 +4333,14 @@
QV('agins_linux_un', v == 4);
QV('agins_linux_inst', v == 5);
QV('aginsSysTypeDiv', v == 5);
Q('aginsbinlnk').href = (Q('aginsbinlnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'') + '&meshinstall=' + Q('aginsSysType').value;
Q('aginsbinlnk').onclick = function() { downloadFile((Q('aginsbinlnk').name.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'') + '&meshinstall=' + Q('aginsSysType').value); };
Q('aginsbincmd').value = (Q('aginsbincmd').value.split('&installflags=')[0]) + '&installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'') + '&meshinstall=' + Q('aginsSysType').value + '\"';
QV('aginsTypeDiv', (v == 0) || (v == 5));
// Fix the links if needed
Q('aginsw32lnk').href = (Q('aginsw32lnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'');
Q('aginsw64lnk').href = (Q('aginsw64lnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'');
if (debugmode > 0) { Q('aginswmshlnk').href = (Q('aginswmshlnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):''); }
Q('aginsw32lnk').onclick = function() { downloadFile((Q('aginsw32lnk').name.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):''), null, true); }
Q('aginsw64lnk').onclick = function() { downloadFile((Q('aginsw64lnk').name.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):''), null, true); }
if (debugmode > 0) { Q('aginswmshlnk').onclick = function() { downloadFile((Q('aginswmshlnk').name.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):''), null, true); } }
}
function validateDeviceToMesh() {
@ -6206,7 +6206,7 @@
date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day
}
QH('p10html2', '<table cellpadding=2 cellspacing=0><thead><tr style=><th scope=col style=text-align:center;width:150px>' + "Day" + '</th><th scope=col style=text-align:center><a download href="devicepowerevents.ashx?id=' + currentNode._id + (urlargs.key?('&key=' + urlargs.key):'') + '" onclick="setDialogMode(0)"><img title="' + "Download power events" + '" src="images/link4.png" /></a>' + "7 Day Power State" + '</th></tr></thead><tbody>' + x + '</tbody></table>');
QH('p10html2', '<table cellpadding=2 cellspacing=0><thead><tr style=><th scope=col style=text-align:center;width:150px>' + "Day" + '</th><th scope=col style=text-align:center><a onclick=downloadFile("devicepowerevents.ashx?id=' + currentNode._id + (urlargs.key?('&key=' + urlargs.key):'') + '",null,true)><img title="' + "Download power events" + '" src="images/link4.png" /></a>' + "7 Day Power State" + '</th></tr></thead><tbody>' + x + '</tbody></table>');
}
// Return a color for the given power state
@ -6410,7 +6410,7 @@
function p10showMeshRouterDialog() {
if (xxdialogMode) return;
var x = '<div>' + "MeshCentral Router is a Windows tool for TCP port mapping. You can, for example, RDP into a remote device thru this server." + '</div><br />';
x += addHtmlValue("Win32 Executable", '<a style=cursor:pointer download href="meshagents?meshaction=winrouter' + (urlargs.key?('&key=' + urlargs.key):'') + '" onclick="setDialogMode(0)">MeshCentralRouter.exe</a>');
x += addHtmlValue("Win32 Executable", '<a style=cursor:pointer onclick=downloadFile("meshagents?meshaction=winrouter' + (urlargs.key?('&key=' + urlargs.key):'') + '",null,true)>MeshCentralRouter.exe</a>');
var servername = serverinfo.name;
if ((servername.indexOf('.') == -1) || ((features & 2) != 0)) { servername = window.location.hostname; } // If the server name is not set or it's in LAN-only mode, use the URL hostname as server name.
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
@ -6419,7 +6419,7 @@
//x += addHtmlValue("Launch", '<a style=cursor:pointer target="mcrouterframe" rel="noreferrer noopener" download href="' + url + '">Start MeshCentral Router</a>');
//x += '<br /><div style=width:100%><a style=cursor:pointer target="mcrouterframe" rel="noreferrer noopener" download href="' + url + '">' + "Start MeshCentral Router" + '</a>' + ", for this link to work you must download MeshCentral Router run it and click the install button." + '</div>';
x += '<br /><div>' + "Run MeshCentral Router and click \"install\" to make it launchable from the browser." + '</div>';
x += '<br /><a style=cursor:pointer target="mcrouterframe" rel="noreferrer noopener" download href="' + url + '"><input type=button style=width:100%;cursor:pointer value="' + "Launch MeshCentral Router" + '" /></a>';
x += '<br /><a style=cursor:pointer target="mcrouterframe" rel="noreferrer noopener" href="' + url + '"><input type=button style=width:100%;cursor:pointer value="' + "Launch MeshCentral Router" + '" /></a>';
x += '<iframe style=display:none name="mcrouterframe"></iframe>';
setDialogMode(2, "MeshCentral Router", 1, null, x, 'fileDownload');
}
@ -6454,9 +6454,9 @@
if (mode == 0) { x += '<div>' + "MeshCmd is a command line tool that performs lots of different operations. The action file can optionally be downloaded and edited to provide server information and credentials." + '<br /><br />'; }
if (mode == 1) { x += '<div>' + "Download \"meshcmd\" with an action file to route traffic thru this server to this device. Make sure to edit meshaction.txt and add your account password or make any changes needed." + '<br /><br />'; }
x += addHtmlValue("Operating System", y);
x += addHtmlValue("MeshCmd", '<a id=meshcmddownloadid href="meshagents?meshcmd=3' + (urlargs.key?('&key=' + urlargs.key):'') + '" download></a>');
if (mode == 0) { x += addHtmlValue("Action File", '<a href="meshagents?meshaction=generic' + (urlargs.key?('&key=' + urlargs.key):'') + '" download>' + "MeshAction (.txt)" + '</a>'); }
if (mode == 1) { x += addHtmlValue("Action File", '<a href="meshagents?meshaction=route&nodeid=' + nodeid + (urlargs.key?('&key=' + urlargs.key):'') + '" download>' + "MeshAction (.txt)" + '</a>'); }
x += addHtmlValue("MeshCmd", '<a id=meshcmddownloadid onclick=downloadFile("meshagents?meshcmd=3' + (urlargs.key?('&key=' + urlargs.key):'') + '")></a>');
if (mode == 0) { x += addHtmlValue("Action File", '<a onclick=downloadFile("meshagents?meshaction=generic' + (urlargs.key?('&key=' + urlargs.key):'') + '")>' + "MeshAction (.txt)" + '</a>'); }
if (mode == 1) { x += addHtmlValue("Action File", '<a onclick=downloadFile("meshagents?meshaction=route&nodeid=' + nodeid + (urlargs.key?('&key=' + urlargs.key):'') + '")>' + "MeshAction (.txt)" + '</a>'); }
x += '</div>';
setDialogMode(2, "Download MeshCmd", 9, null, x, 'fileDownload');
meshCmdOsClick();
@ -7949,7 +7949,9 @@
// Local link
//link = '<a href=# style=cursor:pointer onclick="return p13downloadfile(\'' + encodeURIComponentEx(newlinkpath + '/' + name) + '\',\'' + encodeURIComponentEx(name) + '\',' + f.s + ')">' + shortname + '</a>';
// Server link
link = '<a href="devicefile.ashx?c=' + authCookie + '&m=' + currentNode.meshid.split('/')[2] + '&n=' + currentNode._id.split('/')[2] + '&f=' + encodeURIComponentEx(newlinkpath + '/' + name) + '" download style=cursor:pointer">' + shortname + '</a>';
//link = '<a href="devicefile.ashx?c=' + authCookie + '&m=' + currentNode.meshid.split('/')[2] + '&n=' + currentNode._id.split('/')[2] + '&f=' + encodeURIComponentEx(newlinkpath + '/' + name) + '" download="' + name + '" style=cursor:pointer>' + shortname + '</a>';
// Server link
link = '<a onclick=downloadFile("devicefile.ashx?c=' + authCookie + '&m=' + currentNode.meshid.split('/')[2] + '&n=' + currentNode._id.split('/')[2] + '&f=' + encodeURIComponentEx(newlinkpath + '/' + name) + '","' + name + '") style=cursor:pointer>' + shortname + '</a>';
}
h = '<div id=fileEntry cmenu=filesContextMenu fileIndex=' + i + ' class=filelist file=3><input file=3 style=float:left name=fd class=fcb type=checkbox onchange=p13setActions() value=\'' + f.nx + '\'>&nbsp;<span class=fsize>' + fdatestr + '</span><span style=float:right>' + EscapeHtml(fsize) + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
}
@ -10367,7 +10369,7 @@
} else {
var link = shortname, publiclink = '';
if (publicfolder) { publiclink = '<img src="images/link2.png" style=cursor:pointer title="' + "Display public link" + '" onclick=\'return p5showPublicLink("' + (publicPath + '/' + encodeURIComponentEx(f.nx)) + '?download=1' + '")\' width=10 height=10 /> <img src="images/link4.png" title="' + "Copy link to clipboard" + '" style="cursor:pointer" onclick=copyTextToClip2("' + encodeURIComponentEx(publicPath + '/' + encodeURIComponentEx(f.nx) + '?download=1') + '") width=10 height=10>'; }
if (f.s > 0) { link = publiclink + ' <a rel="noreferrer noopener" target="_blank" download href="downloadfile.ashx?link=' + encodeURIComponentEx(filetreelinkpath + '/' + f.nx) + '">' + shortname + '</a>'; }
if (f.s > 0) { link = publiclink + ' <a onclick=downloadFile("downloadfile.ashx?link=' + encodeURIComponentEx(filetreelinkpath + '/' + f.nx) + '")>' + shortname + '</a>'; }
h = '<div class=filelist file=3><input file=3 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value="' + f.nx + '">&nbsp;<span class=fsize>' + fdatestr + '</span><span style=float:right>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
}
@ -12445,7 +12447,7 @@
}
}
var actions = '', icon = 'm0';
if (rec.present == 1) { icon = 'm1'; actions = '<div style=cursor:pointer;float:right><a href=recordings.ashx?file=' + encodeURIComponentEx(rec.filename) + ' download><img src=images/link4.png height=10 width=10 title="Download Recording" download></a>&nbsp;</div>'; }
if (rec.present == 1) { icon = 'm1'; actions = '<div style=cursor:pointer;float:right><a onclick=downloadFile("recordings.ashx?file=' + encodeURIComponentEx(rec.filename) + '")><img src=images/link4.png height=10 width=10 title="Download Recording"></a>&nbsp;</div>'; }
var x = '<tr tabindex=0 onmouseover=userMouseHover2(this,1) onmouseout=userMouseHover2(this,0) onkeypress="if (event.key==\'Enter\') showRecordingDialog(event,\'' + i + '\')"><td style=cursor:pointer>';
x += '<div class=bar style=width:100%>';
//x += '<div class=baricon><input class=RecordingCheckbox value="' + encodeURIComponentEx(rec.filename) + '" onclick=p52updateInfo() type=checkbox></div>';
@ -13619,6 +13621,19 @@
function round(value, precision) { var multiplier = Math.pow(10, precision || 0); return Math.round(value * multiplier) / multiplier; }
function safeNewWindow(url, target) { var newWindow = window.open(url, target, 'noopener,noreferrer'); if (newWindow) { newWindow.opener = null; } }
// Webkit seems to have a problem with "download" tag causing "network error", but openning the download in a hidden frame fixes it.
// So we do that for all browsers except FireFox
function downloadFile(link, name, closeDialog) {
var element = document.createElement('a');
element.setAttribute('href', link);
element.setAttribute('rel', 'noreferrer noopener');
if (navigator.userAgent.indexOf('Firefox') >= 0) { element.setAttribute('download', name?name:''); } else { element.setAttribute('target', 'fileDownloadFrame'); }
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
if (closeDialog) { setDialogMode(0); }
}
</script>
</body>
</html>
</html>

View File

@ -675,7 +675,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (domain.auth == 'sspi') { parent.debug('web', 'handleLogoutRequest: failed checks.'); res.sendStatus(404); return; }
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
// Destroy the user's session to log them out will be re-created next request
if (req.session.userid) {
var user = obj.users[req.session.userid];
@ -2134,7 +2134,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
function handleRootRequestEx(req, res, domain, direct) {
var nologout = false, user = null, features = 0;
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
// Check if we have an incomplete domain name in the path
if ((domain.id != '') && (domain.dns == null) && (req.url.split('/').length == 2)) {
@ -2557,7 +2557,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
parent.debug('web', 'handleXTermRequest: sending xterm');
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
if (req.session && req.session.userid) {
if (req.session.domainid != domain.id) { res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
var user = obj.users[req.session.userid];
@ -2592,7 +2592,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// See if term.txt was loaded from the database
if ((parent.configurationFiles != null) && (parent.configurationFiles['terms.txt'] != null)) {
// Send the terms from the database
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
if (req.session && req.session.userid) {
if (req.session.domainid != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
var user = obj.users[req.session.userid];
@ -2611,7 +2611,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (err != null) { parent.debug('web', 'handleTermsRequest: no terms.txt'); res.sendStatus(404); return; }
// Send the terms from terms.txt
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
if (req.session && req.session.userid) {
if (req.session.domainid != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
var user = obj.users[req.session.userid];
@ -2626,7 +2626,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
} else {
// Send the default terms
parent.debug('web', 'handleTermsRequest: sending default terms');
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
if (req.session && req.session.userid) {
if (req.session.domainid != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
var user = obj.users[req.session.userid];
@ -2649,7 +2649,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
var webRtcConfig = null;
if (obj.parent.config.settings && obj.parent.config.settings.webrtconfig && (typeof obj.parent.config.settings.webrtconfig == 'object')) { webRtcConfig = encodeURIComponent(JSON.stringify(obj.parent.config.settings.webrtconfig)).replace(/'/g, '%27'); }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
render(req, res, getRenderPage('messenger', req, domain), getRenderArgs({ webrtconfig: webRtcConfig }, req, domain));
}
@ -2671,9 +2671,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((obj.userAllowedIp != null) && (checkIpAddressEx(req, res, obj.userAllowedIp, false) === false)) { parent.debug('web', 'handleRootCertRequest: invalid ip'); return; } // Check server-wide IP filter only.
parent.debug('web', 'handleRootCertRequest()');
try {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + certificates.RootName + '.cer"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + certificates.RootName + '.cer"' });
} catch (ex) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="rootcert.cer"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="rootcert.cer"' });
}
res.send(Buffer.from(getRootCertBase64(), 'base64'));
}
@ -2779,9 +2779,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (script == null) { res.sendStatus(404); } else {
try {
var cirafilename = obj.meshes[req.query.meshid].name.split('\\').join('').split('/').join('').split(':').join('').split('*').join('').split('?').join('').split('"').join('').split('<').join('').split('>').join('').split('|').join('').split(' ').join('').split('\'').join('');
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_setup_' + cirafilename + '.mescript"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_setup_' + cirafilename + '.mescript"' });
} catch (ex) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_setup.mescript"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_setup.mescript"' });
}
res.send(script);
}
@ -2790,7 +2790,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Get the CIRA cleanup script
obj.getCiraCleanupScript(function (script) {
if (script == null) { res.sendStatus(404); } else {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_cleanup.mescript"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_cleanup.mescript"' });
res.send(script);
}
});
@ -2817,9 +2817,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((stat != null) && ((stat.mode & 0x004000) == 0)) {
if (req.query.download == 1) {
try {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + filename + '\"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + filename + '\"' });
} catch (ex) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"file.bin\"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"file.bin\"' });
}
try { res.sendFile(obj.path.resolve(__dirname, path)); } catch (e) { res.sendStatus(404); }
} else {
@ -3035,7 +3035,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((user.siteadmin & 512) == 0) { res.sendStatus(401); return; } // Check if we have right to get recordings
// Send the recorded file
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + req.query.file + '\"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + req.query.file + '\"' });
try { res.sendFile(obj.path.join(recordingsPath, req.query.file)); } catch (ex) { res.sendStatus(404); }
}
@ -3045,7 +3045,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (domain == null) { return; }
parent.debug('web', 'handlePlayerRequest: sending player');
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
render(req, res, getRenderPage('player', req, domain), getRenderArgs({}, req, domain));
}
@ -3066,7 +3066,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Lets respond by sending out the desktop viewer.
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
parent.debug('web', 'handleDesktopRequest: Sending guest desktop page for \"' + c.uid + '\", guest \"' + c.gn + '\".');
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
res.set({ 'Cache-Control': 'no-store' });
render(req, res, getRenderPage('desktop', req, domain), getRenderArgs({ authCookie: authCookie, authRelayCookie: '', domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), nodeid: c.nid, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, expire: c.expire }, req, domain));
}
@ -3131,9 +3131,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
const file = obj.getServerFilePath(user, domain, req.query.link);
if (file == null) { res.sendStatus(404); return; }
try {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + file.name + '\"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + file.name + '\"' });
} catch (ex) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"file.bin\"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"file.bin\"' });
}
obj.fs.exists(file.fullpath, function (exists) { if (exists == true) { res.sendFile(file.fullpath); } else { res.sendStatus(404); } });
}
@ -4144,7 +4144,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
for (var i in meshsettingslines) { tokens = meshsettingslines[i].split('='); if (tokens.length == 2) { msh[tokens[0]] = tokens[1]; } }
var js = scriptInfo.data.replace('var msh = {};', 'var msh = ' + JSON.stringify(msh) + ';');
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshagent"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshagent"' });
res.statusCode = 200;
obj.parent.exeHandler.streamExeWithJavaScript({ platform: argentInfo.platform, sourceFileName: argentInfo.path, destinationStream: res, js: Buffer.from(js, 'utf8'), peinfo: argentInfo.pe });
} else if (req.query.id != null) {
@ -4152,7 +4152,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
var argentInfo = obj.parent.meshAgentBinaries[req.query.id];
if (argentInfo == null) { res.sendStatus(404); return; }
if ((req.query.meshid == null) || (argentInfo.platform != 'win32')) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + argentInfo.rname + '"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + argentInfo.rname + '"' });
if (argentInfo.data == null) { res.sendFile(argentInfo.path); } else { res.end(argentInfo.data); }
} else {
// Check if the meshid is a time limited, encrypted cookie
@ -4199,9 +4199,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (domain.agentconfig) { for (var i in domain.agentconfig) { meshsettings += domain.agentconfig[i] + '\r\n'; } }
try {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + meshfilename + '"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + meshfilename + '"' });
} catch (ex) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + argentInfo.rname + '"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + argentInfo.rname + '"' });
}
obj.parent.exeHandler.streamExeWithMeshPolicy({ platform: 'win32', sourceFileName: obj.parent.meshAgentBinaries[req.query.id].path, destinationStream: res, msh: meshsettings, peinfo: obj.parent.meshAgentBinaries[req.query.id].pe });
}
@ -4211,7 +4211,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Send a specific mesh install script back
var scriptInfo = obj.parent.meshAgentInstallScripts[req.query.script];
if (scriptInfo == null) { res.sendStatus(404); return; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="' + scriptInfo.rname + '"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="' + scriptInfo.rname + '"' });
var data = scriptInfo.data;
var cmdoptions = { wgetoptionshttp: '', wgetoptionshttps: '', curloptionshttp: '-L ', curloptionshttps: '-L ' }
if (obj.isTrustedCert(domain) != true) {
@ -4235,17 +4235,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((agentid == 3)) { // Signed Windows MeshCmd.exe x86
var stats = null, meshCmdPath = obj.path.join(__dirname, 'agents', 'MeshCmd-signed.exe');
try { stats = obj.fs.statSync(meshCmdPath); } catch (e) { }
if ((stats != null)) { res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 3) ? '.exe' : '') + '"' }); res.sendFile(meshCmdPath); return; }
if ((stats != null)) { res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 3) ? '.exe' : '') + '"' }); res.sendFile(meshCmdPath); return; }
} else if ((agentid == 4)) { // Signed Windows MeshCmd64.exe x64
var stats = null, meshCmd64Path = obj.path.join(__dirname, 'agents', 'MeshCmd64-signed.exe');
try { stats = obj.fs.statSync(meshCmd64Path); } catch (e) { }
if ((stats != null)) { res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') + '"' }); res.sendFile(meshCmd64Path); return; }
if ((stats != null)) { res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') + '"' }); res.sendFile(meshCmd64Path); return; }
}
// No signed agents, we are going to merge a new MeshCmd.
if ((agentid < 10000) && (obj.parent.meshAgentBinaries[agentid + 10000] != null)) { agentid += 10000; } // Avoid merging javascript to a signed mesh agent.
var argentInfo = obj.parent.meshAgentBinaries[agentid];
if ((argentInfo == null) || (obj.parent.defaultMeshCmd == null)) { res.sendStatus(404); return; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') + '"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') + '"' });
res.statusCode = 200;
if (argentInfo.signedMeshCmdPath != null) {
// If we have a pre-signed MeshCmd, send that.
@ -4281,7 +4281,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (req.query.key != null) { meshaction.loginKey = req.query.key; }
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + obj.getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="meshaction.txt"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="meshaction.txt"' });
res.send(JSON.stringify(meshaction, null, ' '));
});
} else if (req.query.meshaction == 'generic') {
@ -4296,12 +4296,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (req.query.key != null) { meshaction.loginKey = req.query.key; }
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + obj.getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="meshaction.txt"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="meshaction.txt"' });
res.send(JSON.stringify(meshaction, null, ' '));
} else if (req.query.meshaction == 'winrouter') {
var p = obj.path.join(__dirname, 'agents', 'MeshCentralRouter.exe');
if (obj.fs.existsSync(p)) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="MeshCentralRouter.exe"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="MeshCentralRouter.exe"' });
try { res.sendFile(p); } catch (e) { res.sendStatus(404); }
} else { res.sendStatus(404); }
} else {
@ -4324,7 +4324,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Download a dump file
var dumpFile = obj.path.join(parent.datapath, '..', 'meshcentral-coredumps', req.query.dldump);
if (obj.fs.existsSync(dumpFile)) {
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="' + req.query.dldump + '' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="' + req.query.dldump + '' });
res.sendFile(dumpFile); return;
} else {
res.sendStatus(404); return;
@ -4464,10 +4464,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
archive.on('error', function (err) { throw err; });
try {
// Set the agent download including the mesh name.
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="MeshAgent-' + mesh.name + '.zip"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="MeshAgent-' + mesh.name + '.zip"' });
} catch (ex) {
// If the mesh name contains invalid characters, just use a generic name.
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="MeshAgent.zip"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="MeshAgent.zip"' });
}
archive.pipe(res);
@ -4566,7 +4566,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
var meshsettings = getMshFromRequest(req, res, domain);
if (meshsettings == null) { res.sendStatus(401); return; }
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshagent.msh"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshagent.msh"' });
res.send(meshsettings);
};
@ -4590,7 +4590,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (obj.GetNodeRights(user, node.meshid, node._id) == 0) { res.sendStatus(401); return; }
// Get the list of power events and send them
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="powerevents.csv"' });
res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="powerevents.csv"' });
obj.db.getPowerTimeline(node._id, function (err, docs) {
var xevents = ['Time, State, Previous State'], prevState = 0;
for (var i in docs) {