Added Webkit download bug workaround.
Ylian Saint-Hilaire committed
Oct 2, 2020 at 13:17 UTC
dfe4273baf05da8c5d61a9fac572549287fdfb33
4 files changed
+79
-64
meshdevicefile.js
+2
-2
@@ -204,9 +204,9 @@ module.exports.CreateMeshDeviceFile = function (parent, ws, res, req, domain, us
204
if ((cmd == null) || (typeof cmd.op == 'string')) {
205
if (cmd.op == 'ok') {
206
if (typeof cmd.size == 'number') {
207
- 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 });
207
+ 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 });
208
} else {
209
- 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) + '"' });
209
+ this.res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + require('path').basename(this.file) + '"' });
210
}
211
} else {
212
try { this.res.sendStatus(401); } catch (ex) { }
redirserver.js
+1
-1
@@ -53,7 +53,7 @@ module.exports.CreateRedirServer = function (parent, db, args, func) {
53
obj.app.get('/MeshServerRootCert.cer', function (req, res) {
54
// The redirection server starts before certificates are loaded, make sure to handle the case where no certificate is loaded now.
55
if (obj.certificates != null) {
56
- 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\"" });
56
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + obj.certificates.RootName + '.cer"' });
57
var rootcert = obj.certificates.root.cert;
58
var i = rootcert.indexOf('-----BEGIN CERTIFICATE-----\r\n');
59
if (i >= 0) { rootcert = rootcert.substring(i + 29); }
views/default.handlebars
+41
-26
@@ -1212,6 +1212,7 @@
1212
<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>
1213
<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>
1214
<audio id="chimes"><source src="sounds/chimes.mp3" type="audio/mp3" /></audio>
1215
+ <iframe style=display:none name="fileDownloadFrame"></iframe>
1216
</div>
1217
<script type="text/javascript" nonce="abc">
1218
'use strict';
@@ -4116,14 +4117,14 @@
4117
// Setup CIRA using a MeshCommander script (Pretty Simple)
4118
x += '<div id=dlgAddCira0>' + format("To add a new Intel® 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 />';
4119
//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>');
4119
- x += addHtmlValue("Setup CIRA", '<a href="mescript.ashx?type=1' + (urlargs.key?('&key=' + urlargs.key):'') + '&meshid=' + meshid + '" download>cira_setup.mescript</a>');
4120
- x += addHtmlValue("Cleanup CIRA", '<a href="mescript.ashx?type=2' + (urlargs.key?('&key=' + urlargs.key):'') + '" download>cira_clean.mescript</a>');
4120
+ x += addHtmlValue("Setup CIRA", '<a onclick=downloadFile("mescript.ashx?type=1' + (urlargs.key?('&key=' + urlargs.key):'') + '&meshid=' + meshid + '")>cira_setup.mescript</a>');
4121
+ x += addHtmlValue("Cleanup CIRA", '<a onclick=downloadFile("mescript.ashx?type=2' + (urlargs.key?('&key=' + urlargs.key):'') + '")>cira_clean.mescript</a>');
4122
x += '</div>';
4123
4124
// Setup CIRA with user/pass authentication (Somewhat difficult)
4125
x += '<div id=dlgAddCira1 style=display:none>' + format("To add a new Intel® AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel® AMT", EscapeHtml(mesh.name));
4126
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 />'); }
4126
- x += addHtmlValue("Root Certificate", '<a href="' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '" download>' + "Root Certificate File" + '</a>');
4127
+ x += addHtmlValue("Root Certificate", '<a onclick=downloadFile("' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '")>' + "Root Certificate File" + '</a>');
4128
x += addHtmlValue("Username", '<input style=width:230px readonly value="' + meshidx.substring(0, 16) + '" />');
4129
if (serverinfo.mpspass) { x += addHtmlValue("Password", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpspass) + '" />'); }
4130
if (serverinfo != null) { x += addHtmlValue("MPS Server", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
@@ -4132,7 +4133,7 @@
4133
// Setup CIRA with certificate authentication (Really difficult, only if TLS offload is not used)
4134
if ((features & 16) == 0) {
4135
x += '<div id=dlgAddCira2 style=display:none>' + format("To add a new Intel® AMT device to device group \"{0}\" with CIRA, load the following certificate as trusted root within Intel® AMT, authenticate using a client certificate with the following common name and connect to the following server.", EscapeHtml(mesh.name)) + '<br /><br />';
4135
- x += addHtmlValue("Root Certificate", '<a href="' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '" download>' + "Root Certificate File" + '</a>');
4136
+ x += addHtmlValue("Root Certificate", '<a onclick=downloadFile("' + "MeshServerRootCert.cer" + (urlargs.key?('?key=' + urlargs.key):'') + '")>' + "Root Certificate File" + '</a>');
4137
x += addHtmlValue("Organization", '<input style=width:230px readonly value="' + meshidx + '" />');
4138
if (serverinfo != null) { x += addHtmlValue("MPS Server", '<input style=width:230px readonly value="' + EscapeHtml(serverinfo.mpsname) + ':' + serverinfo.mpsport + '" />'); }
4139
x += '</div>';
@@ -4242,9 +4243,9 @@
4243
4244
// Windows agent install
4245
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 />';
4245
- 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)>');
4246
- 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)>');
4247
- 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>'); }
4246
+ 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)>');
4247
+ 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)>');
4248
+ 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>'); }
4249
x += '</div>';
4250
4251
// Linux agent install
@@ -4254,13 +4255,13 @@
4255
4256
// macOS agent install
4257
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 />';
4257
- 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)>');
4258
+ 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)>');
4259
x += '</div>';
4260
4261
// Windows agent uninstall
4262
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 />';
4262
- 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>');
4263
- 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>');
4263
+ 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>');
4264
+ 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>');
4265
x += '</div>';
4266
4267
// Linux agent uninstall
@@ -4270,7 +4271,7 @@
4271
4272
// Linux binary installer
4273
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 />';
4273
- 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)>');
4274
+ 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)>');
4275
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")>');
4276
x += '</div>';
4277
@@ -4312,7 +4313,6 @@
4313
function copyAgentIdValue(id) { copyTextToClip(Q(id).value); }
4314
4315
function copyAgentUrl(url,addflag) {
4315
- console.log('copyAgentUrl', url, addflag);
4316
var servername = serverinfo.name;
4317
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.
4318
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
@@ -4333,14 +4333,14 @@
4333
QV('agins_linux_un', v == 4);
4334
QV('agins_linux_inst', v == 5);
4335
QV('aginsSysTypeDiv', v == 5);
4336
- Q('aginsbinlnk').href = (Q('aginsbinlnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'') + '&meshinstall=' + Q('aginsSysType').value;
4336
+ Q('aginsbinlnk').onclick = function() { downloadFile((Q('aginsbinlnk').name.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'') + '&meshinstall=' + Q('aginsSysType').value); };
4337
Q('aginsbincmd').value = (Q('aginsbincmd').value.split('&installflags=')[0]) + '&installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'') + '&meshinstall=' + Q('aginsSysType').value + '\"';
4338
QV('aginsTypeDiv', (v == 0) || (v == 5));
4339
4340
// Fix the links if needed
4341
- Q('aginsw32lnk').href = (Q('aginsw32lnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'');
4342
- Q('aginsw64lnk').href = (Q('aginsw64lnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):'');
4343
- if (debugmode > 0) { Q('aginswmshlnk').href = (Q('aginswmshlnk').href.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):''); }
4341
+ Q('aginsw32lnk').onclick = function() { downloadFile((Q('aginsw32lnk').name.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):''), null, true); }
4342
+ Q('aginsw64lnk').onclick = function() { downloadFile((Q('aginsw64lnk').name.split('installflags=')[0]) + 'installflags=' + Q('aginsType').value + (urlargs.key?('&key=' + urlargs.key):''), null, true); }
4343
+ 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); } }
4344
}
4345
4346
function validateDeviceToMesh() {
@@ -6206,7 +6206,7 @@
6206
date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day
6207
}
6208
6209
- 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>');
6209
+ 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>');
6210
}
6211
6212
// Return a color for the given power state
@@ -6410,7 +6410,7 @@
6410
function p10showMeshRouterDialog() {
6411
if (xxdialogMode) return;
6412
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 />';
6413
- x += addHtmlValue("Win32 Executable", '<a style=cursor:pointer download href="meshagents?meshaction=winrouter' + (urlargs.key?('&key=' + urlargs.key):'') + '" onclick="setDialogMode(0)">MeshCentralRouter.exe</a>');
6413
+ x += addHtmlValue("Win32 Executable", '<a style=cursor:pointer onclick=downloadFile("meshagents?meshaction=winrouter' + (urlargs.key?('&key=' + urlargs.key):'') + '",null,true)>MeshCentralRouter.exe</a>');
6414
var servername = serverinfo.name;
6415
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.
6416
var domainUrlNoSlash = domainUrl.substring(0, domainUrl.length - 1);
@@ -6419,7 +6419,7 @@
6419
//x += addHtmlValue("Launch", '<a style=cursor:pointer target="mcrouterframe" rel="noreferrer noopener" download href="' + url + '">Start MeshCentral Router</a>');
6420
//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>';
6421
x += '<br /><div>' + "Run MeshCentral Router and click \"install\" to make it launchable from the browser." + '</div>';
6422
- 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>';
6422
+ 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>';
6423
x += '<iframe style=display:none name="mcrouterframe"></iframe>';
6424
setDialogMode(2, "MeshCentral Router", 1, null, x, 'fileDownload');
6425
}
@@ -6454,9 +6454,9 @@
6454
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 />'; }
6455
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 />'; }
6456
x += addHtmlValue("Operating System", y);
6457
- x += addHtmlValue("MeshCmd", '<a id=meshcmddownloadid href="meshagents?meshcmd=3' + (urlargs.key?('&key=' + urlargs.key):'') + '" download></a>');
6458
- if (mode == 0) { x += addHtmlValue("Action File", '<a href="meshagents?meshaction=generic' + (urlargs.key?('&key=' + urlargs.key):'') + '" download>' + "MeshAction (.txt)" + '</a>'); }
6459
- if (mode == 1) { x += addHtmlValue("Action File", '<a href="meshagents?meshaction=route&nodeid=' + nodeid + (urlargs.key?('&key=' + urlargs.key):'') + '" download>' + "MeshAction (.txt)" + '</a>'); }
6457
+ x += addHtmlValue("MeshCmd", '<a id=meshcmddownloadid onclick=downloadFile("meshagents?meshcmd=3' + (urlargs.key?('&key=' + urlargs.key):'') + '")></a>');
6458
+ if (mode == 0) { x += addHtmlValue("Action File", '<a onclick=downloadFile("meshagents?meshaction=generic' + (urlargs.key?('&key=' + urlargs.key):'') + '")>' + "MeshAction (.txt)" + '</a>'); }
6459
+ if (mode == 1) { x += addHtmlValue("Action File", '<a onclick=downloadFile("meshagents?meshaction=route&nodeid=' + nodeid + (urlargs.key?('&key=' + urlargs.key):'') + '")>' + "MeshAction (.txt)" + '</a>'); }
6460
x += '</div>';
6461
setDialogMode(2, "Download MeshCmd", 9, null, x, 'fileDownload');
6462
meshCmdOsClick();
@@ -7949,7 +7949,9 @@
7949
// Local link
7950
//link = '<a href=# style=cursor:pointer onclick="return p13downloadfile(\'' + encodeURIComponentEx(newlinkpath + '/' + name) + '\',\'' + encodeURIComponentEx(name) + '\',' + f.s + ')">' + shortname + '</a>';
7951
// Server link
7952
- 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>';
7952
+ //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>';
7953
+ // Server link
7954
+ 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>';
7955
}
7956
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 + '\'> <span class=fsize>' + fdatestr + '</span><span style=float:right>' + EscapeHtml(fsize) + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
7957
}
@@ -10367,7 +10369,7 @@
10369
} else {
10370
var link = shortname, publiclink = '';
10371
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>'; }
10370
- if (f.s > 0) { link = publiclink + ' <a rel="noreferrer noopener" target="_blank" download href="downloadfile.ashx?link=' + encodeURIComponentEx(filetreelinkpath + '/' + f.nx) + '">' + shortname + '</a>'; }
10372
+ if (f.s > 0) { link = publiclink + ' <a onclick=downloadFile("downloadfile.ashx?link=' + encodeURIComponentEx(filetreelinkpath + '/' + f.nx) + '")>' + shortname + '</a>'; }
10373
h = '<div class=filelist file=3><input file=3 style=float:left name=fc class=fcb type=checkbox onchange=p5setActions() value="' + f.nx + '"> <span class=fsize>' + fdatestr + '</span><span style=float:right>' + fsize + '</span><span><div class=fileIcon' + f.t + '></div>' + link + '</span></div>';
10374
}
10375
@@ -12445,7 +12447,7 @@
12447
}
12448
}
12449
var actions = '', icon = 'm0';
12448
- 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> </div>'; }
12450
+ 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> </div>'; }
12451
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>';
12452
x += '<div class=bar style=width:100%>';
12453
//x += '<div class=baricon><input class=RecordingCheckbox value="' + encodeURIComponentEx(rec.filename) + '" onclick=p52updateInfo() type=checkbox></div>';
@@ -13619,6 +13621,19 @@
13621
function round(value, precision) { var multiplier = Math.pow(10, precision || 0); return Math.round(value * multiplier) / multiplier; }
13622
function safeNewWindow(url, target) { var newWindow = window.open(url, target, 'noopener,noreferrer'); if (newWindow) { newWindow.opener = null; } }
13623
13624
+ // Webkit seems to have a problem with "download" tag causing "network error", but openning the download in a hidden frame fixes it.
13625
+ // So we do that for all browsers except FireFox
13626
+ function downloadFile(link, name, closeDialog) {
13627
+ var element = document.createElement('a');
13628
+ element.setAttribute('href', link);
13629
+ element.setAttribute('rel', 'noreferrer noopener');
13630
+ if (navigator.userAgent.indexOf('Firefox') >= 0) { element.setAttribute('download', name?name:''); } else { element.setAttribute('target', 'fileDownloadFrame'); }
13631
+ document.body.appendChild(element);
13632
+ element.click();
13633
+ document.body.removeChild(element);
13634
+ if (closeDialog) { setDialogMode(0); }
13635
+ }
13636
+
13637
</script>
13638
</body>
13624
-</html>
13639
+</html>
\ No newline at end of file
webserver.js
+35
-35
@@ -675,7 +675,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
675
if (domain.auth == 'sspi') { parent.debug('web', 'handleLogoutRequest: failed checks.'); res.sendStatus(404); return; }
676
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
677
678
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
678
+ res.set({ 'Cache-Control': 'no-store' });
679
// Destroy the user's session to log them out will be re-created next request
680
if (req.session.userid) {
681
var user = obj.users[req.session.userid];
@@ -2134,7 +2134,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2134
2135
function handleRootRequestEx(req, res, domain, direct) {
2136
var nologout = false, user = null, features = 0;
2137
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
2137
+ res.set({ 'Cache-Control': 'no-store' });
2138
2139
// Check if we have an incomplete domain name in the path
2140
if ((domain.id != '') && (domain.dns == null) && (req.url.split('/').length == 2)) {
@@ -2557,7 +2557,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2557
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
2558
2559
parent.debug('web', 'handleXTermRequest: sending xterm');
2560
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
2560
+ res.set({ 'Cache-Control': 'no-store' });
2561
if (req.session && req.session.userid) {
2562
if (req.session.domainid != domain.id) { res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
2563
var user = obj.users[req.session.userid];
@@ -2592,7 +2592,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2592
// See if term.txt was loaded from the database
2593
if ((parent.configurationFiles != null) && (parent.configurationFiles['terms.txt'] != null)) {
2594
// Send the terms from the database
2595
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
2595
+ res.set({ 'Cache-Control': 'no-store' });
2596
if (req.session && req.session.userid) {
2597
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
2598
var user = obj.users[req.session.userid];
@@ -2611,7 +2611,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2611
if (err != null) { parent.debug('web', 'handleTermsRequest: no terms.txt'); res.sendStatus(404); return; }
2612
2613
// Send the terms from terms.txt
2614
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
2614
+ res.set({ 'Cache-Control': 'no-store' });
2615
if (req.session && req.session.userid) {
2616
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
2617
var user = obj.users[req.session.userid];
@@ -2626,7 +2626,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2626
} else {
2627
// Send the default terms
2628
parent.debug('web', 'handleTermsRequest: sending default terms');
2629
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
2629
+ res.set({ 'Cache-Control': 'no-store' });
2630
if (req.session && req.session.userid) {
2631
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
2632
var user = obj.users[req.session.userid];
@@ -2649,7 +2649,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2649
2650
var webRtcConfig = null;
2651
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'); }
2652
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
2652
+ res.set({ 'Cache-Control': 'no-store' });
2653
render(req, res, getRenderPage('messenger', req, domain), getRenderArgs({ webrtconfig: webRtcConfig }, req, domain));
2654
}
2655
@@ -2671,9 +2671,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2671
if ((obj.userAllowedIp != null) && (checkIpAddressEx(req, res, obj.userAllowedIp, false) === false)) { parent.debug('web', 'handleRootCertRequest: invalid ip'); return; } // Check server-wide IP filter only.
2672
parent.debug('web', 'handleRootCertRequest()');
2673
try {
2674
- 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"' });
2674
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + certificates.RootName + '.cer"' });
2675
} catch (ex) {
2676
- 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"' });
2676
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="rootcert.cer"' });
2677
}
2678
res.send(Buffer.from(getRootCertBase64(), 'base64'));
2679
}
@@ -2779,9 +2779,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2779
if (script == null) { res.sendStatus(404); } else {
2780
try {
2781
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('');
2782
- 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"' });
2782
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_setup_' + cirafilename + '.mescript"' });
2783
} catch (ex) {
2784
- 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"' });
2784
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_setup.mescript"' });
2785
}
2786
res.send(script);
2787
}
@@ -2790,7 +2790,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2790
// Get the CIRA cleanup script
2791
obj.getCiraCleanupScript(function (script) {
2792
if (script == null) { res.sendStatus(404); } else {
2793
- 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"' });
2793
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="cira_cleanup.mescript"' });
2794
res.send(script);
2795
}
2796
});
@@ -2817,9 +2817,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2817
if ((stat != null) && ((stat.mode & 0x004000) == 0)) {
2818
if (req.query.download == 1) {
2819
try {
2820
- 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 + '\"' });
2820
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + filename + '\"' });
2821
} catch (ex) {
2822
- 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\"' });
2822
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"file.bin\"' });
2823
}
2824
try { res.sendFile(obj.path.resolve(__dirname, path)); } catch (e) { res.sendStatus(404); }
2825
} else {
@@ -3035,7 +3035,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3035
if ((user.siteadmin & 512) == 0) { res.sendStatus(401); return; } // Check if we have right to get recordings
3036
3037
// Send the recorded file
3038
- 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 + '\"' });
3038
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + req.query.file + '\"' });
3039
try { res.sendFile(obj.path.join(recordingsPath, req.query.file)); } catch (ex) { res.sendStatus(404); }
3040
}
3041
@@ -3045,7 +3045,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3045
if (domain == null) { return; }
3046
3047
parent.debug('web', 'handlePlayerRequest: sending player');
3048
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
3048
+ res.set({ 'Cache-Control': 'no-store' });
3049
render(req, res, getRenderPage('player', req, domain), getRenderArgs({}, req, domain));
3050
}
3051
@@ -3066,7 +3066,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3066
// Lets respond by sending out the desktop viewer.
3067
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
3068
parent.debug('web', 'handleDesktopRequest: Sending guest desktop page for \"' + c.uid + '\", guest \"' + c.gn + '\".');
3069
- res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
3069
+ res.set({ 'Cache-Control': 'no-store' });
3070
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));
3071
}
3072
@@ -3131,9 +3131,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3131
const file = obj.getServerFilePath(user, domain, req.query.link);
3132
if (file == null) { res.sendStatus(404); return; }
3133
try {
3134
- 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 + '\"' });
3134
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"' + file.name + '\"' });
3135
} catch (ex) {
3136
- 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\"' });
3136
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=\"file.bin\"' });
3137
}
3138
obj.fs.exists(file.fullpath, function (exists) { if (exists == true) { res.sendFile(file.fullpath); } else { res.sendStatus(404); } });
3139
}
@@ -4144,7 +4144,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4144
for (var i in meshsettingslines) { tokens = meshsettingslines[i].split('='); if (tokens.length == 2) { msh[tokens[0]] = tokens[1]; } }
4145
var js = scriptInfo.data.replace('var msh = {};', 'var msh = ' + JSON.stringify(msh) + ';');
4146
4147
- 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"' });
4147
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshagent"' });
4148
res.statusCode = 200;
4149
obj.parent.exeHandler.streamExeWithJavaScript({ platform: argentInfo.platform, sourceFileName: argentInfo.path, destinationStream: res, js: Buffer.from(js, 'utf8'), peinfo: argentInfo.pe });
4150
} else if (req.query.id != null) {
@@ -4152,7 +4152,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4152
var argentInfo = obj.parent.meshAgentBinaries[req.query.id];
4153
if (argentInfo == null) { res.sendStatus(404); return; }
4154
if ((req.query.meshid == null) || (argentInfo.platform != 'win32')) {
4155
- 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 + '"' });
4155
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + argentInfo.rname + '"' });
4156
if (argentInfo.data == null) { res.sendFile(argentInfo.path); } else { res.end(argentInfo.data); }
4157
} else {
4158
// Check if the meshid is a time limited, encrypted cookie
@@ -4199,9 +4199,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4199
if (domain.agentconfig) { for (var i in domain.agentconfig) { meshsettings += domain.agentconfig[i] + '\r\n'; } }
4200
4201
try {
4202
- 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 + '"' });
4202
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + meshfilename + '"' });
4203
} catch (ex) {
4204
- 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 + '"' });
4204
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="' + argentInfo.rname + '"' });
4205
}
4206
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 });
4207
}
@@ -4211,7 +4211,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4211
// Send a specific mesh install script back
4212
var scriptInfo = obj.parent.meshAgentInstallScripts[req.query.script];
4213
if (scriptInfo == null) { res.sendStatus(404); return; }
4214
- 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 + '"' });
4214
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="' + scriptInfo.rname + '"' });
4215
var data = scriptInfo.data;
4216
var cmdoptions = { wgetoptionshttp: '', wgetoptionshttps: '', curloptionshttp: '-L ', curloptionshttps: '-L ' }
4217
if (obj.isTrustedCert(domain) != true) {
@@ -4235,17 +4235,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4235
if ((agentid == 3)) { // Signed Windows MeshCmd.exe x86
4236
var stats = null, meshCmdPath = obj.path.join(__dirname, 'agents', 'MeshCmd-signed.exe');
4237
try { stats = obj.fs.statSync(meshCmdPath); } catch (e) { }
4238
- 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; }
4238
+ 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; }
4239
} else if ((agentid == 4)) { // Signed Windows MeshCmd64.exe x64
4240
var stats = null, meshCmd64Path = obj.path.join(__dirname, 'agents', 'MeshCmd64-signed.exe');
4241
try { stats = obj.fs.statSync(meshCmd64Path); } catch (e) { }
4242
- 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; }
4242
+ 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; }
4243
}
4244
// No signed agents, we are going to merge a new MeshCmd.
4245
if ((agentid < 10000) && (obj.parent.meshAgentBinaries[agentid + 10000] != null)) { agentid += 10000; } // Avoid merging javascript to a signed mesh agent.
4246
var argentInfo = obj.parent.meshAgentBinaries[agentid];
4247
if ((argentInfo == null) || (obj.parent.defaultMeshCmd == null)) { res.sendStatus(404); return; }
4248
- 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' : '') + '"' });
4248
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshcmd' + ((req.query.meshcmd <= 4) ? '.exe' : '') + '"' });
4249
res.statusCode = 200;
4250
if (argentInfo.signedMeshCmdPath != null) {
4251
// If we have a pre-signed MeshCmd, send that.
@@ -4281,7 +4281,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4281
if (req.query.key != null) { meshaction.loginKey = req.query.key; }
4282
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
4283
if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + obj.getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
4284
- 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"' });
4284
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="meshaction.txt"' });
4285
res.send(JSON.stringify(meshaction, null, ' '));
4286
});
4287
} else if (req.query.meshaction == 'generic') {
@@ -4296,12 +4296,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4296
if (req.query.key != null) { meshaction.loginKey = req.query.key; }
4297
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
4298
if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + obj.getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
4299
- 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"' });
4299
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename="meshaction.txt"' });
4300
res.send(JSON.stringify(meshaction, null, ' '));
4301
} else if (req.query.meshaction == 'winrouter') {
4302
var p = obj.path.join(__dirname, 'agents', 'MeshCentralRouter.exe');
4303
if (obj.fs.existsSync(p)) {
4304
- 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"' });
4304
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="MeshCentralRouter.exe"' });
4305
try { res.sendFile(p); } catch (e) { res.sendStatus(404); }
4306
} else { res.sendStatus(404); }
4307
} else {
@@ -4324,7 +4324,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4324
// Download a dump file
4325
var dumpFile = obj.path.join(parent.datapath, '..', 'meshcentral-coredumps', req.query.dldump);
4326
if (obj.fs.existsSync(dumpFile)) {
4327
- 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 + '' });
4327
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="' + req.query.dldump + '' });
4328
res.sendFile(dumpFile); return;
4329
} else {
4330
res.sendStatus(404); return;
@@ -4464,10 +4464,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4464
archive.on('error', function (err) { throw err; });
4465
try {
4466
// Set the agent download including the mesh name.
4467
- 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"' });
4467
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="MeshAgent-' + mesh.name + '.zip"' });
4468
} catch (ex) {
4469
// If the mesh name contains invalid characters, just use a generic name.
4470
- 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"' });
4470
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/zip', 'Content-Disposition': 'attachment; filename="MeshAgent.zip"' });
4471
}
4472
archive.pipe(res);
4473
@@ -4566,7 +4566,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4566
var meshsettings = getMshFromRequest(req, res, domain);
4567
if (meshsettings == null) { res.sendStatus(401); return; }
4568
4569
- 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"' });
4569
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename="meshagent.msh"' });
4570
res.send(meshsettings);
4571
};
4572
@@ -4590,7 +4590,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4590
if (obj.GetNodeRights(user, node.meshid, node._id) == 0) { res.sendStatus(401); return; }
4591
4592
// Get the list of power events and send them
4593
- 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"' });
4593
+ res.set({ 'Cache-Control': 'no-store', 'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="powerevents.csv"' });
4594
obj.db.getPowerTimeline(node._id, function (err, docs) {
4595
var xevents = ['Time, State, Previous State'], prevState = 0;
4596
for (var i in docs) {