Improved web interface for getting started.
Ylian Saint-Hilaire committed
Oct 2, 2017 at 14:12 UTC
5474f1d3869cd6dbe6e0d1a22c5637a8792651c9
9 files changed
+263
-127
MeshCentralServer.njsproj
-3
@@ -71,7 +71,6 @@
71
<Content Include="public\images-isdu\info.gif" />
72
<Content Include="public\images-isdu\warning.gif" />
73
<Content Include="public\images-isdu\isdu.ico" />
74
- <Content Include="public\styles\font-awesome\css\font-awesome.css" />
74
<Content Include="public\styles\font-awesome\css\font-awesome.min.css" />
75
<Content Include="public\styles\font-awesome\fonts\fontawesome-webfont.eot" />
76
<Content Include="public\styles\font-awesome\fonts\fontawesome-webfont.svg" />
@@ -120,8 +119,6 @@
119
<Folder Include="public\images-isdu" />
120
<Folder Include="public\scripts\" />
121
<Folder Include="public\styles\" />
123
- <Folder Include="public\styles\font-awesome\" />
124
- <Folder Include="public\styles\font-awesome\css\" />
122
<Folder Include="public\styles\font-awesome\fonts\" />
123
<Folder Include="public\styles\font-awesome\less\" />
124
<Folder Include="public\styles\font-awesome\scss\" />
agents/meshcore.js
+2
-2
@@ -277,9 +277,9 @@ function createMeshCore(agent) {
277
else if (data.type == 'tunnel') { // Process a new tunnel connection request
278
if (data.value && data.sessionid) {
279
// Create a new tunnel object
280
- //sendConsoleText(data.value);
280
+ sendConsoleText(data.value);
281
var xurl = getServerTargetUrlEx(data.value);
282
- //sendConsoleText(xurl);
282
+ sendConsoleText(xurl);
283
if (xurl != null) {
284
var tunnel = http.request(http.parseUri(xurl));
285
tunnel.upgrade = onTunnelUpgrade;
certoperations.js
+37
-28
@@ -38,24 +38,23 @@ module.exports.CertificateOperations = function () {
38
cert.validity.notAfter = new Date();
39
cert.validity.notAfter.setFullYear(cert.validity.notAfter.getFullYear() + 30);
40
if (addThumbPrintToName == true) { commonName += '-' + obj.pki.getPublicKeyFingerprint(cert.publicKey, { encoding: 'hex' }).substring(0, 6); }
41
- var attrs = [ { name: 'commonName', value: commonName } ];
42
- if (country != undefined) attrs.push({ name: 'countryName', value: country });
43
- if (organization != undefined) attrs.push({ name: 'organizationName', value: organization });
41
+ if (country == undefined) { country = 'unknown'; }
42
+ if (organization == undefined) { organization = 'unknown'; }
43
+ var attrs = [{ name: 'commonName', value: commonName }, { name: 'organizationName', value: organization }, { name: 'countryName', value: country }];
44
cert.setSubject(attrs);
45
cert.setIssuer(attrs);
46
- cert.setExtensions([
47
- { name: 'basicConstraints', cA: true },
48
- {
46
+ // Create a root certificate
47
+ cert.setExtensions([{
48
+ name: 'basicConstraints',
49
+ cA: true
50
+ }, {
51
name: 'nsCertType',
50
- client: false,
51
- server: false,
52
- email: false,
53
- objsign: false,
52
sslCA: true,
55
- emailCA: false,
53
+ emailCA: true,
54
objCA: true
57
- }
58
- ]);
55
+ }, {
56
+ name: 'subjectKeyIdentifier'
57
+ }]);
58
cert.sign(keys.privateKey, obj.forge.md.sha256.create());
59
60
return { cert: cert, key: keys.privateKey };
@@ -136,7 +135,8 @@ module.exports.CertificateOperations = function () {
135
}
136
137
// Returns the web server TLS certificate and private key, if not present, create demonstration ones.
139
- obj.GetMeshServerCertificate = function (directory, certargs, func) {
138
+ obj.GetMeshServerCertificate = function (directory, args, func) {
139
+ var certargs = args.cert;
140
// commonName, country, organization
141
142
// If the certificates directory does not exist, create it.
@@ -151,16 +151,25 @@ module.exports.CertificateOperations = function () {
151
r.root = { cert: rootCertificate, key: rootPrivateKey };
152
rcount++;
153
}
154
-
155
- // If the web certificate already exist, load it
156
- if (obj.fileExists(directory + '/webserver-cert-public.crt') && obj.fileExists(directory + '/webserver-cert-private.key')) {
157
- var webCertificate = obj.fs.readFileSync(directory + '/webserver-cert-public.crt', 'utf8');
158
- var webPrivateKey = obj.fs.readFileSync(directory + '/webserver-cert-private.key', 'utf8');
159
- r.web = { cert: webCertificate, key: webPrivateKey };
160
- rcount++;
154
+
155
+ if (args.tlsoffload == true) {
156
+ // If the web certificate already exist, load it. Load just the certificate since we are in TLS offload situation
157
+ if (obj.fileExists(directory + '/webserver-cert-public.crt')) {
158
+ var webCertificate = obj.fs.readFileSync(directory + '/webserver-cert-public.crt', 'utf8');
159
+ r.web = { cert: webCertificate };
160
+ rcount++;
161
+ }
162
+ } else {
163
+ // If the web certificate already exist, load it. Load both certificate and private key
164
+ if (obj.fileExists(directory + '/webserver-cert-public.crt') && obj.fileExists(directory + '/webserver-cert-private.key')) {
165
+ var webCertificate = obj.fs.readFileSync(directory + '/webserver-cert-public.crt', 'utf8');
166
+ var webPrivateKey = obj.fs.readFileSync(directory + '/webserver-cert-private.key', 'utf8');
167
+ r.web = { cert: webCertificate, key: webPrivateKey };
168
+ rcount++;
169
+ }
170
}
171
163
- // If the bin certificate already exist, load it
172
+ // If the mps certificate already exist, load it
173
if (obj.fileExists(directory + '/mpsserver-cert-public.crt') && obj.fileExists(directory + '/mpsserver-cert-private.key')) {
174
var mpsCertificate = obj.fs.readFileSync(directory + '/mpsserver-cert-public.crt', 'utf8');
175
var mpsPrivateKey = obj.fs.readFileSync(directory + '/mpsserver-cert-private.key', 'utf8');
@@ -168,7 +177,7 @@ module.exports.CertificateOperations = function () {
177
rcount++;
178
}
179
171
- // If the bin certificate already exist, load it
180
+ // If the agent certificate already exist, load it
181
if (obj.fileExists(directory + '/agentserver-cert-public.crt') && obj.fileExists(directory + '/agentserver-cert-private.key')) {
182
var agentCertificate = obj.fs.readFileSync(directory + '/agentserver-cert-public.crt', 'utf8');
183
var agentPrivateKey = obj.fs.readFileSync(directory + '/agentserver-cert-private.key', 'utf8');
@@ -176,7 +185,7 @@ module.exports.CertificateOperations = function () {
185
rcount++;
186
}
187
179
- // If the bin certificate already exist, load it
188
+ // If the console certificate already exist, load it
189
if (obj.fileExists(directory + '/amtconsole-cert-public.crt') && obj.fileExists(directory + '/agentserver-cert-private.key')) {
190
var amtConsoleCertificate = obj.fs.readFileSync(directory + '/amtconsole-cert-public.crt', 'utf8');
191
var amtConsolePrivateKey = obj.fs.readFileSync(directory + '/amtconsole-cert-private.key', 'utf8');
@@ -198,14 +207,14 @@ module.exports.CertificateOperations = function () {
207
r.calist = calist;
208
209
// Decode certificate arguments
201
- var commonName = 'un-configured', country, organization;
210
+ var commonName = 'un-configured', country, organization, forceWebCertGen = 0;
211
if (certargs != undefined) {
212
var args = certargs.split(',');
213
if (args.length > 0) commonName = args[0];
214
if (args.length > 1) country = args[1];
215
if (args.length > 2) organization = args[2];
216
}
208
-
217
+
218
if (rcount == 5) {
219
// Fetch the Intel AMT console name
220
var consoleCertificate = obj.pki.certificateFromPem(r.console.cert);
@@ -220,7 +229,7 @@ module.exports.CertificateOperations = function () {
229
if (xcountryField != null) { xcountry = xcountryField.value; }
230
var xorganization, xorganizationField = webCertificate.subject.getField('O');
231
if (xorganizationField != null) { xorganization = xorganizationField.value; }
223
- if ((r.CommonName == commonName) && (xcountry == country) && (xorganization == organization)) { if (func != undefined) { func(r); } return r; } // If the certificate matches what we want, keep it.
232
+ if ((r.CommonName == commonName) && (xcountry == country) && (xorganization == organization)) { if (func != undefined) { func(r); } return r; } else { forceWebCertGen = 1; } // If the certificate matches what we want, keep it.
233
}
234
console.log('Generating certificates...');
235
@@ -242,7 +251,7 @@ module.exports.CertificateOperations = function () {
251
252
// If the web certificate does not exist, create one
253
var webCertAndKey, webCertificate, webPrivateKey;
245
- if (r.web == undefined) {
254
+ if ((r.web == undefined) || (forceWebCertGen == 1)) {
255
webCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, commonName, country, organization);
256
webCertificate = obj.pki.certificateToPem(webCertAndKey.cert);
257
webPrivateKey = obj.pki.privateKeyToPem(webCertAndKey.key);
meshcentral.js
+7
-3
@@ -201,8 +201,12 @@ function CreateMeshCentralServer() {
201
var xdomains = {}; for (var i in obj.config.domains) { if (!obj.config.domains[i].title) { obj.config.domains[i].title = 'MeshCentral'; } if (!obj.config.domains[i].title2) { obj.config.domains[i].title2 = '2.0 Beta 1'; } xdomains[i.toLowerCase()] = obj.config.domains[i]; } obj.config.domains = xdomains;
202
var bannedDomains = ['public', 'private', 'images', 'scripts', 'styles', 'views']; // List of banned domains
203
for (var i in obj.config.domains) { for (var j in bannedDomains) { if (i == bannedDomains[j]) { console.log("ERROR: Domain '" + i + "' is not allowed domain name in ./data/config.json."); return; } } }
204
- for (var i in obj.config.domains) { obj.config.domains[i].url = (i == '')?'/':('/' + i + '/'); obj.config.domains[i].id = i; }
205
-
204
+ for (var i in obj.config.domains) {
205
+ for (var j in obj.config.domains[i]) { obj.config.domains[i][j.toLocaleLowerCase()] = obj.config.domains[i][j]; } // LowerCase all domain keys
206
+ obj.config.domains[i].url = (i == '') ? '/' : ('/' + i + '/'); obj.config.domains[i].id = i;
207
+ if (typeof obj.config.domains[i].userallowedip == 'string') { obj.config.domains[i].userallowedip = null; if (obj.config.domains[i].userallowedip != "") { obj.config.domains[i].userallowedip = obj.config.domains[i].userallowedip.split(','); } }
208
+ }
209
+
210
// Log passed arguments into Windows Service Log
211
//if (obj.servicelog != null) { var s = ''; for (var i in obj.args) { if (i != '_') { if (s.length > 0) { s += ', '; } s += i + "=" + obj.args[i]; } } logInfoEvent('MeshServer started with arguments: ' + s); }
212
@@ -283,7 +287,7 @@ function CreateMeshCentralServer() {
287
obj.updateMeshCore();
288
289
// Load server certificates
286
- obj.certificateOperations.GetMeshServerCertificate(obj.datapath, obj.args.cert, function (certs) {
290
+ obj.certificateOperations.GetMeshServerCertificate(obj.datapath, obj.args, function (certs) {
291
obj.certificates = certs;
292
293
// If the certificate is un-configured, force LAN-only mode
mesherrors.txt
+94
@@ -189,3 +189,97 @@ TypeError: Cannot read property 'SSL_OP_NO_SSLv2' of undefined
189
at Immediate._onImmediate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:498:34)
190
191
192
+-------- 10/1/2017, 10:21:38 AM --------
193
+
194
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:91
195
+ console.log(obj.servers4.keys());
196
+ ^
197
+
198
+TypeError: obj.servers4.keys is not a function
199
+ at setupServers (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:91:34)
200
+ at Object.obj.start (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:136:9)
201
+ at InternalFieldObject.ondone (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshcentral.js:328:98)
202
+
203
+
204
+-------- 10/1/2017, 10:21:40 AM --------
205
+
206
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:91
207
+ console.log(obj.servers4.keys());
208
+ ^
209
+
210
+TypeError: obj.servers4.keys is not a function
211
+ at setupServers (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:91:34)
212
+ at Object.obj.start (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:136:9)
213
+ at InternalFieldObject.ondone (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshcentral.js:328:98)
214
+
215
+
216
+-------- 10/1/2017, 10:54:43 AM --------
217
+
218
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:96
219
+ performScan(server6);
220
+ ^
221
+
222
+ReferenceError: performScan is not defined
223
+ at Socket.<anonymous> (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:96:21)
224
+ at Socket.g (events.js:286:16)
225
+ at emitNone (events.js:86:13)
226
+ at Socket.emit (events.js:185:7)
227
+ at startListening (dgram.js:121:10)
228
+ at dgram.js:228:7
229
+ at _combinedTickCallback (internal/process/next_tick.js:77:11)
230
+ at process._tickCallback (internal/process/next_tick.js:98:9)
231
+
232
+
233
+-------- 10/1/2017, 10:54:45 AM --------
234
+
235
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:96
236
+ performScan(server6);
237
+ ^
238
+
239
+ReferenceError: performScan is not defined
240
+ at Socket.<anonymous> (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:96:21)
241
+ at Socket.g (events.js:286:16)
242
+ at emitNone (events.js:86:13)
243
+ at Socket.emit (events.js:185:7)
244
+ at startListening (dgram.js:121:10)
245
+ at dgram.js:228:7
246
+ at _combinedTickCallback (internal/process/next_tick.js:77:11)
247
+ at process._tickCallback (internal/process/next_tick.js:98:9)
248
+
249
+
250
+-------- 10/1/2017, 10:54:47 AM --------
251
+
252
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:96
253
+ performScan(server6);
254
+ ^
255
+
256
+ReferenceError: performScan is not defined
257
+ at Socket.<anonymous> (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshscanner.js:96:21)
258
+ at Socket.g (events.js:286:16)
259
+ at emitNone (events.js:86:13)
260
+ at Socket.emit (events.js:185:7)
261
+ at startListening (dgram.js:121:10)
262
+ at dgram.js:228:7
263
+ at _combinedTickCallback (internal/process/next_tick.js:77:11)
264
+ at process._tickCallback (internal/process/next_tick.js:98:9)
265
+
266
+
267
+-------- 10/1/2017, 11:49:12 AM --------
268
+
269
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\node-forge\js\x509.js:2052
270
+ throw error;
271
+ ^
272
+
273
+Error: Attribute value not specified.
274
+ at _fillMissingFields (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\node-forge\js\x509.js:2050:19)
275
+ at Object.cert.setSubject (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\node-forge\js\x509.js:948:5)
276
+ at Object.obj.GenerateRootCertificate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\certoperations.js:44:14)
277
+ at Object.obj.GetMeshServerCertificate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\certoperations.js:230:34)
278
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\meshcentral.js:286:43
279
+ at newArguments.(anonymous function) (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\executor.js:29:17)
280
+ at Cursor.execFn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:484:12)
281
+ at callback (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:126:19)
282
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:193:12
283
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:329:14
284
+
285
+
meshscanner.js
+39
-29
@@ -22,8 +22,7 @@ module.exports.CreateMeshScanner = function (parent) {
22
23
// Get a list of IPv4 and IPv6 interface addresses
24
function getInterfaceList() {
25
- var ipv4 = [];
26
- var ipv6 = [];
25
+ var ipv4 = ['*'], ipv6 = ['*'];
26
var interfaces = require('os').networkInterfaces();
27
for (var i in interfaces) {
28
var interface = interfaces[i];
@@ -50,25 +49,32 @@ module.exports.CreateMeshScanner = function (parent) {
49
obj.servers4[localAddress].xxclear = false;
50
} else {
51
// Create a new IPv4 server
53
- var server4 = obj.dgram.createSocket("udp4");
54
- server4.xxclear = false;
55
- server4.xxtype = 4;
56
- server4.xxlocal = localAddress;
57
- server4.on('error', function (err) { console.log("ERROR: Server port " + server4.xxlocal + ":16989 not available, check if server is running twice."); server4.close(); server4 = null; });
58
- server4.bind({ address: server4.xxlocal, port: 16989, exclusive: false }, function () {
59
- try {
60
- server4.setBroadcast(true);
61
- server4.setMulticastTTL(128);
62
- server4.addMembership(membershipIPv4);
63
- server4.on('error', function (error) { console.log('Error: ' + error); });
64
- server4.on('message', function (msg, info) { onUdpPacket(msg, info, server4); });
65
- obj.performScan(server4);
66
- obj.performScan(server4);
67
- } catch (e) { }
68
- });
69
- obj.servers4[localAddress] = server4;
52
+ try {
53
+ var server4 = obj.dgram.createSocket("udp4");
54
+ server4.xxclear = false;
55
+ server4.xxtype = 4;
56
+ server4.xxlocal = localAddress;
57
+ server4.on('error', function (err) { console.log("ERROR: Server port " + server4.xxlocal + ":16989 not available, check if server is running twice."); server4.close(); server4 = null; });
58
+ var bindOptions = { port: 16989, exclusive: false };
59
+ if (server4.xxlocal != '*') { bindOptions.address = server4.xxlocal; }
60
+ server4.bind(bindOptions, function () {
61
+ try {
62
+ this.setBroadcast(true);
63
+ this.setMulticastTTL(128);
64
+ this.addMembership(membershipIPv4);
65
+ server4.on('error', function (error) { console.log('Error: ' + error); });
66
+ server4.on('message', function (msg, info) { onUdpPacket(msg, info, server4); });
67
+ obj.performScan(this);
68
+ obj.performScan(this);
69
+ } catch (e) { }
70
+ });
71
+ obj.servers4[localAddress] = server4;
72
+ } catch (e) {
73
+ console.log(e);
74
+ }
75
}
76
}
77
+
78
for (var i in addresses.ipv6) {
79
var localAddress = addresses.ipv6[i];
80
if (obj.servers6[localAddress] != null) {
@@ -80,16 +86,18 @@ module.exports.CreateMeshScanner = function (parent) {
86
server6.xxclear = false;
87
server6.xxtype = 6;
88
server6.xxlocal = localAddress;
83
- server6.on('error', function (err) { console.log("ERROR: Server port [" + server6.xxlocal + "]:16989 not available, check if server is running twice.");server6.close(); obj.server6 = null; });
84
- server6.bind({ address: server6.xxlocal, port: 16989, exclusive: false }, function () {
89
+ server6.on('error', function (err) { console.log("ERROR: Server port [" + server6.xxlocal + "]:16989 not available, check if server is running twice."); server6.close(); obj.server6 = null; });
90
+ var bindOptions = { port: 16989, exclusive: false };
91
+ if (server6.xxlocal != '*') { bindOptions.address = server6.xxlocal; }
92
+ server6.bind(bindOptions, function () {
93
try {
86
- server6.setBroadcast(true);
87
- server6.setMulticastTTL(128);
88
- server6.addMembership(membershipIPv6);
89
- server6.on('error', function (error) { console.log('Error: ' + error); });
90
- server6.on('message', function (msg, info) { onUdpPacket(msg, info, server6); });
91
- performScan(server6);
92
- performScan(server6);
94
+ this.setBroadcast(true);
95
+ this.setMulticastTTL(128);
96
+ this.addMembership(membershipIPv6);
97
+ this.on('error', function (error) { console.log('Error: ' + error); });
98
+ this.on('message', function (msg, info) { onUdpPacket(msg, info, this); });
99
+ obj.performScan(this);
100
+ obj.performScan(this);
101
} catch (e) { }
102
});
103
obj.servers6[localAddress] = server6;
@@ -128,6 +136,8 @@ module.exports.CreateMeshScanner = function (parent) {
136
if (server != null) {
137
if (server.xxtype == 4) { server.send(obj.multicastPacket4, 0, obj.multicastPacket4.length, 16990, membershipIPv4); }
138
if (server.xxtype == 6) { server.send(obj.multicastPacket6, 0, obj.multicastPacket6.length, 16990, membershipIPv6); }
139
+ if ((server.xxtype == 4) && (server.xxlocal == '*')) { server.send(obj.multicastPacket4, 0, obj.multicastPacket4.length, 16990, '127.0.0.1'); server.send(obj.multicastPacket4, 0, obj.multicastPacket4.length, 16990, '255.255.255.255'); }
140
+ if ((server.xxtype == 6) && (server.xxlocal == '*')) { server.send(obj.multicastPacket6, 0, obj.multicastPacket6.length, 16990, '::1'); }
141
} else {
142
for (var i in obj.servers4) { obj.servers4[i].send(obj.multicastPacket4, 0, obj.multicastPacket4.length, 16990, membershipIPv4); }
143
for (var i in obj.servers6) { obj.servers6[i].send(obj.multicastPacket6, 0, obj.multicastPacket6.length, 16990, membershipIPv6); }
@@ -137,7 +147,7 @@ module.exports.CreateMeshScanner = function (parent) {
147
148
// Called when a UDP packet is received from an agent.
149
function onUdpPacket(msg, info, server) {
140
- // console.log('Received ' + msg.length + ' bytes from ' + info.address + ':' + info.port + ', on interface: ' + server.xxlocal + '.');
150
+ //console.log('Received ' + msg.length + ' bytes from ' + info.address + ':' + info.port + ', on interface: ' + server.xxlocal + '.');
151
if ((msg.length == 64) && (msg.toString('ascii') == obj.agentCertificatHashHex.toUpperCase())) {
152
if (server.xxtype == 4) { server.send(obj.multicastPacket4, 0, obj.multicastPacket4.length, info.port, info.address); }
153
if (server.xxtype == 6) { server.send(obj.multicastPacket6, 0, obj.multicastPacket6.length, info.port, info.address); }
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.0.8-g",
3
+ "version": "0.0.8-j",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
views/default.handlebars
+22
-16
@@ -119,7 +119,7 @@
119
<div class="auto-style1" style="height: 100%; float: right">
120
<div style="height:100%;width:4px;float:right;background-color:#ffffff"></div>
121
<div class=h2 style="height:100%;float:right"> </div>
122
- <div style=float:right>
122
+ <div style=float:right id=devListToolbarView>
123
View
124
<select id=viewselect onchange=onDeviceViewChange()>
125
<option value=1>3 wide</option>
@@ -138,18 +138,17 @@
138
</div>
139
</div>
140
</div>
141
- <div id=NoNodesPanel style=display:none>
142
- <table style="width: 100%">
141
+ <div id=NoMeshesPanel style=display:none>
142
+ <table style="width:100%;padding:20px">
143
<tr>
144
<td valign="top" style="width: 50px">
145
<img src="images/info.png" height="48" width="47" />
146
</td>
147
<td>
148
- No nodes found with this search criteria. To create a mesh network and add devices, start at the <a onclick=go(2) style="cursor:pointer">My Account</a> page.
148
+ To get started managing devices, <a onclick=account_createMesh() style=cursor:pointer><strong>click here to create a new group of devices called a Mesh</strong></a>.
149
</td>
150
</tr>
151
</table>
152
- <p></p>
152
</div>
153
<div id="xdevices" style="max-height:calc(100vh - 228px);overflow-y:auto;-webkit-overflow-scrolling:touch"></div>
154
<div id="xdevicesmap" style="height:500px;width:100%;overflow:hidden;position:relative">
@@ -184,7 +183,7 @@
183
( <a onclick=account_createMesh() style=cursor:pointer><img height=12 src="images/icon-addnew.png" width=12 border=0 /> New</a> )
184
<br /><br />
185
<div id=p2meshes></div>
187
- <div id=p2noMeshFound style=margin-left:40px;display:none>No meshes found. <a onclick=account_createMesh() style=cursor:pointer><strong>Get started here!</strong></a><br /><br /></div>
186
+ <div id=p2noMeshFound style=margin-left:40px;display:none>No meshes. <a onclick=account_createMesh() style=cursor:pointer><strong>Get started here!</strong></a><br /><br /></div>
187
</div>
188
<div id=p3 style=display:none>
189
<h1>My Events</h1>
@@ -406,13 +405,13 @@
405
<td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign=bottom>
406
<div id="p13rightOfButtons" style="float:right;margin-top:3px"></div>
407
<div>
409
- <input type=button id="p13FolderUp" disabled="disabled" onclick="p13folderup()" value="Up" />
410
- <input type=button id="p13SelectAllButton" disabled="disabled" onclick="p13selectallfile()" value="Select All" onkeypress="return false" onkeydown="return false" />
411
- <input type=button id="p13RenameFileButton" disabled="disabled" value="Rename" onclick="p13renamefile()" onkeypress="return false" onkeydown="return false" />
412
- <input type=button id="p13DeleteFileButton" disabled="disabled" value="Delete" onclick="p13deletefile()" onkeypress="return false" onkeydown="return false" />
413
- <input type=button id="p13NewFolderButton" disabled="disabled" value="New Folder" onclick="p13createfolder()" onkeypress="return false" onkeydown="return false" />
414
- <input type=button id="p13UploadButton" disabled="disabled" value="Upload" onclick="p13uploadFile()" onkeypress="return false" onkeydown="return false" />
415
- <input type=button id="p13RefreshButton" disabled="disabled" value="Refresh" onclick="p13folderup(9999)" onkeypress="return false" onkeydown="return false" />
408
+ <input type=button id=p13FolderUp disabled="disabled" onclick="p13folderup()" value="Up" />
409
+ <input type=button id=p13SelectAllButton disabled="disabled" onclick="p13selectallfile()" value="Select All" onkeypress="return false" onkeydown="return false" />
410
+ <input type=button id=p13RenameFileButton disabled="disabled" value="Rename" onclick="p13renamefile()" onkeypress="return false" onkeydown="return false" />
411
+ <input type=button id=p13DeleteFileButton disabled="disabled" value="Delete" onclick="p13deletefile()" onkeypress="return false" onkeydown="return false" />
412
+ <input type=button id=p13NewFolderButton disabled="disabled" value="New Folder" onclick="p13createfolder()" onkeypress="return false" onkeydown="return false" />
413
+ <input type=button id=p13UploadButton disabled="disabled" value="Upload" onclick="p13uploadFile()" onkeypress="return false" onkeydown="return false" />
414
+ <input type=button id=p13RefreshButton disabled="disabled" value="Refresh" onclick="p13folderup(9999)" onkeypress="return false" onkeydown="return false" />
415
</div>
416
</td>
417
</tr>
@@ -602,6 +601,7 @@
601
var showHostnames = false;
602
var meshserver = null;
603
var meshes = {};
604
+ var meshcount = 0;
605
var nodes = [];
606
var filetree = {};
607
var userinfo = null;
@@ -1195,8 +1195,11 @@
1195
QV('devListToolbar', view < 3);
1196
QV('devMapToolbar', view == 3);
1197
QV('devListToolbarSort', view < 3);
1198
+ QV('NoMeshesPanel', meshcount == 0);
1199
+ QV('devListToolbarView', (meshcount != 0) && (nodes.length > 0));
1200
+ QV('devListToolbarSort', (meshcount != 0) && (nodes.length > 0));
1201
+ if ((meshcount == 0) || (nodes.length == 0)) { view = 1; }
1202
if (view == 3) {
1199
- QV('NoNodesPanel',false); //Hide NoNodesPanel user views Map
1203
setTimeout( function() { if (xxmap.map != null) { xxmap.map.updateSize(); } }, 200);
1204
// TODO
1205
} else {
@@ -1300,9 +1303,12 @@
1303
}
1304
r += '</tr></table><div style=height:1px></div>'; // This height of 1 div fixes a problem in Linux firefox browsers
1305
1306
+ // Add a "Add Mesh" option
1307
+ if (view == 1) { r += '<div style=border-top-style:solid;border-top-width:1px;border-top-color:#DDDDDD;cursor:pointer;font-size:10px title="Create a new group of computers."><a onclick=account_createMesh() style=cursor:pointer>Add Mesh</a></div>'; }
1308
+
1309
QH('xdevices', r);
1310
deviceHeaderSet();
1305
- QV('NoNodesPanel', count == 0);
1311
+ //QV('NoMeshesPanel', count == 0);
1312
1313
// Re-check nodeid's
1314
var elements = document.getElementsByClassName("DeviceCheckbox"), checkcount = 0;
@@ -1671,7 +1677,6 @@
1677
markersLayer: null,
1678
mapLayer: null, // Create a tile and use OSM source
1679
mapView: null, // Sets the initial view
1674
- selectedNodes: {} // Save details of Node that was selected from 'Put a node' option from contextmenu
1680
}
1681
1682
// Add a feature for every Node and change style if connection status changes
@@ -3642,6 +3647,7 @@
3647
}
3648
r += '</tr></table>';
3649
3650
+ meshcount = count;
3651
QH('p2meshes', r);
3652
QV('p2noMeshFound', count == 0);
3653
}
webserver.js
+61
-45
@@ -138,7 +138,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
138
for (var i in docs) { var u = obj.users[docs[i]._id] = docs[i]; domainUserCount[u.domain]++; }
139
for (var i in parent.config.domains) {
140
if (domainUserCount[i] == 0) {
141
- if (parent.config.domains[i].newAccounts == 0) { parent.config.domains[i].newAccounts = 2; }
141
+ if (parent.config.domains[i].newaccounts == 0) { parent.config.domains[i].newaccounts = 2; }
142
console.log('Server ' + ((i == '') ? '' : (i + ' ')) + 'has no users, next new account will be site administrator.');
143
}
144
}
@@ -178,22 +178,35 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
178
}
179
*/
180
181
- // Check if the source IP address is allowed, return false if not
182
- function checkUserIpAddress(req, res) {
183
- if (obj.userAllowedIp == null) { return true; }
181
+ // Check if the source IP address is allowed for a given allowed list, return false if not
182
+ function checkUserIpAddressEx(req, res, allowedIpList) {
183
+ if (allowedIpList == null) { return true; }
184
try {
185
- if (typeof obj.userAllowedIp == 'string') { if (obj.userAllowedIp == "") { obj.userAllowedIp = null; return true; } else { obj.userAllowedIp = obj.userAllowedIp.split(','); } }
185
var ip = null, type = 0;
186
if (req.connection) { ip = req.connection.remoteAddress; type = 1; } // HTTP(S) request
187
else if (req._socket) { ip = req._socket.remoteAddress; type = 2; } // WebSocket request
188
if (ip.startsWith('::ffff:')) { ip = ip.substring(7); } // Fix IPv4 IP's encoded in IPv6 form
190
- if ((ip != null) && (obj.userAllowedIp.indexOf(ip) >= 0)) { return true; }
189
+ if ((ip != null) && (allowedIpList.indexOf(ip) >= 0)) { return true; }
190
if (type == 1) { res.sendStatus(401); }
191
else if (type == 2) { try { req.close(); } catch (e) { } }
192
} catch (e) { console.log(e); }
193
return false;
194
}
195
196
+ // Check if the source IP address is allowed, return domain if allowed
197
+ function checkUserIpAddress(req, res, rootonly) {
198
+ if (obj.userAllowedIp != null) {
199
+ if (typeof obj.userAllowedIp == 'string') { if (obj.userAllowedIp == "") { obj.userAllowedIp = null; return true; } else { obj.userAllowedIp = obj.userAllowedIp.split(','); } }
200
+ if (checkUserIpAddressEx(req, res, obj.userAllowedIp) == false) return null;
201
+ }
202
+ if (rootonly == true) return;
203
+ var domain;
204
+ if (req.url) { domain = getDomain(req); } else { domain = getDomain(res); }
205
+ if (domain.userallowedip == null) return domain;
206
+ if (checkUserIpAddressEx(req, res, domain.userallowedip) == false) return null;
207
+ return domain;
208
+ }
209
+
210
// Return the current domain of the request
211
function getDomain(req) {
212
var x = req.url.split('/');
@@ -203,8 +216,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
216
}
217
218
function handleLogoutRequest(req, res) {
206
- if (checkUserIpAddress(req, res) == false) { return; }
207
- var domain = getDomain(req);
219
+ var domain = checkUserIpAddress(req, res);
220
+ if (domain == null) return;
221
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
222
// Destroy the user's session to log them out will be re-created next request
223
if (req.session.userid) {
@@ -217,8 +230,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
230
}
231
232
function handleLoginRequest(req, res) {
220
- if (checkUserIpAddress(req, res) == false) { return; }
221
- var domain = getDomain(req);
233
+ var domain = checkUserIpAddress(req, res);
234
+ if (domain == null) return;
235
obj.authenticate(req.body.username, req.body.password, domain, function (err, userid, passhint) {
236
if (userid) {
237
var user = obj.users[userid];
@@ -269,16 +282,16 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
282
}
283
284
function handleCreateAccountRequest(req, res) {
272
- if (checkUserIpAddress(req, res) == false) { return; }
273
- var domain = getDomain(req);
274
- if (domain.newAccounts == 0) { res.sendStatus(401); return; }
285
+ var domain = checkUserIpAddress(req, res);
286
+ if (domain == null) return;
287
+ if (domain.newaccounts == 0) { res.sendStatus(401); return; }
288
if (!req.body.username || !req.body.email || !req.body.password1 || !req.body.password2 || (req.body.password1 != req.body.password2) || req.body.username == '~') {
289
req.session.loginmode = 2;
290
req.session.error = '<b style=color:#8C001A>Unable to create account.</b>';;
291
res.redirect(domain.url);
292
} else {
293
// Check if there is domain.newAccountToken, check if supplied token is valid
281
- if ((domain.newAccountsPass != null) && (domain.newAccountsPass != '') && (req.body.anewaccountpass != domain.newAccountsPass)) {
294
+ if ((domain.newaccountspass != null) && (domain.newaccountspass != '') && (req.body.anewaccountpass != domain.newaccountspass)) {
295
req.session.loginmode = 2;
296
req.session.error = '<b style=color:#8C001A>Invalid account creation token.</b>';
297
res.redirect(domain.url);
@@ -294,7 +307,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
307
var user = { type: 'user', _id: 'user/' + domain.id + '/' + req.body.username.toLowerCase(), name: req.body.username, email: req.body.email, creation: Date.now(), login: Date.now(), domain: domain.id, passhint: hint };
308
var usercount = 0;
309
for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
297
- if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; if (domain.newAccounts == 2) { domain.newAccounts = 0; } } // If this is the first user, give the account site admin.
310
+ if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; if (domain.newaccounts == 2) { domain.newaccounts = 0; } } // If this is the first user, give the account site admin.
311
obj.users[user._id] = user;
312
req.session.userid = user._id;
313
req.session.domainid = domain.id;
@@ -312,8 +325,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
325
}
326
327
function handleDeleteAccountRequest(req, res) {
315
- if (checkUserIpAddress(req, res) == false) { return; }
316
- var domain = getDomain(req);
328
+ var domain = checkUserIpAddress(req, res);
329
+ if (domain == null) return;
330
// Check if the user is logged and we have all required parameters
331
if (!req.session || !req.session.userid || !req.body.apassword1 || (req.body.apassword1 != req.body.apassword2) || (req.session.domainid != domain.id)) { res.redirect(domain.url); return; }
332
var user = obj.users[req.session.userid];
@@ -335,8 +348,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
348
349
// Handle password changes
350
function handlePasswordChangeRequest(req, res) {
338
- if (checkUserIpAddress(req, res) == false) { return; }
339
- var domain = getDomain(req);
351
+ var domain = checkUserIpAddress(req, res);
352
+ if (domain == null) return;
353
// Check if the user is logged and we have all required parameters
354
if (!req.session || !req.session.userid || !req.body.apassword1 || (req.body.apassword1 != req.body.apassword2) || (req.session.domainid != domain.id)) { res.redirect(domain.url); return; }
355
@@ -359,7 +372,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
372
373
// Indicates that any request to "/" should render "default" or "login" depending on login state
374
function handleRootRequest(req, res) {
362
- if (checkUserIpAddress(req, res) == false) { return; }
375
+ var domain = checkUserIpAddress(req, res);
376
+ if (domain == null) return;
377
if (!obj.args) { res.sendStatus(500); return; }
378
var domain = getDomain(req);
379
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
@@ -412,7 +426,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
426
res.render(obj.path.join(__dirname, 'views/default'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: obj.certificates.CommonName, serverPublicPort: args.port, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, mpspass: args.mpspass });
427
} else {
428
// Send back the login application
415
- res.render(obj.path.join(__dirname, 'views/login'), { loginmode: req.session.loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newAccounts, newAccountPass: (((domain.newAccountsPass == null) || (domain.newAccountsPass == ''))?0:1), serverDnsName: obj.certificates.CommonName, serverPublicPort: obj.args.port });
429
+ res.render(obj.path.join(__dirname, 'views/login'), { loginmode: req.session.loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == ''))?0:1), serverDnsName: obj.certificates.CommonName, serverPublicPort: obj.args.port });
430
}
431
}
432
@@ -425,8 +439,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
439
440
// Renter the terms of service.
441
function handleTermsRequest(req, res) {
428
- if (checkUserIpAddress(req, res) == false) { return; }
429
- var domain = getDomain(req);
442
+ var domain = checkUserIpAddress(req, res);
443
+ if (domain == null) return;
444
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
445
if (req.session && req.session.userid) {
446
if (req.session.domainid != domain.id) { req.session.destroy(function () { res.redirect(domain.url); }); return; } // Check is the session is for the correct domain
@@ -449,14 +463,14 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
463
464
// Returns the mesh server root certificate
465
function handleRootCertRequest(req, res) {
452
- if (checkUserIpAddress(req, res) == false) { return; }
466
+ if (checkUserIpAddress(req, res, true) == false) { return; }
467
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' });
468
res.send(new Buffer(getRootCertBase64(), 'base64'));
469
}
470
471
// Returns an mescript for Intel AMT configuration
472
function handleMeScriptRequest(req, res) {
459
- if (checkUserIpAddress(req, res) == false) { return; }
473
+ if (checkUserIpAddress(req, res, true) == false) { return; }
474
if (req.query.type == 1) {
475
var filename = 'cira_setup.mescript';
476
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 });
@@ -527,8 +541,9 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
541
542
// Handle user public file downloads
543
function handleDownloadUserFiles(req, res) {
530
- if (checkUserIpAddress(req, res) == false) { return; }
531
- var domain = getDomain(req), domainname = 'domain', spliturl = decodeURIComponent(req.path).split('/'), filename = '';
544
+ var domain = checkUserIpAddress(req, res);
545
+ if (domain == null) return;
546
+ var domainname = 'domain', spliturl = decodeURIComponent(req.path).split('/'), filename = '';
547
if ((spliturl.length < 3) || (obj.common.IsFilenameValid(spliturl[2]) == false) || (domain.userQuota == -1)) { res.sendStatus(404); return; }
548
if (domain.id != '') { domainname = 'domain-' + domain.id; }
549
var path = obj.path.join(obj.filespath, domainname + "/user-" + spliturl[2] + "/Public");
@@ -550,8 +565,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
565
566
// Download a file from the server
567
function handleDownloadFile(req, res) {
553
- if (checkUserIpAddress(req, res) == false) { return; }
554
- var domain = getDomain(req);
568
+ var domain = checkUserIpAddress(req, res);
569
+ if (domain == null) return;
570
if ((req.query.link == null) || (req.session == null) || (req.session.userid == null) || (domain == null) || (domain.userQuota == -1)) { res.sendStatus(404); return; }
571
var user = obj.users[req.session.userid];
572
if (user == null) { res.sendStatus(404); return; }
@@ -563,8 +578,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
578
579
// Upload a MeshCore.js file to the server
580
function handleUploadMeshCoreFile(req, res) {
566
- if (checkUserIpAddress(req, res) == false) { return; }
567
- var domain = getDomain(req);
581
+ var domain = checkUserIpAddress(req, res);
582
+ if (domain == null) return;
583
if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid)) { res.sendStatus(401); return; }
584
var user = obj.users[req.session.userid];
585
if (user.siteadmin != 0xFFFFFFFF) { res.sendStatus(401); return; } // Check if we have mesh core upload rights (Full admin only)
@@ -588,8 +603,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
603
604
// Upload a file to the server
605
function handleUploadFile(req, res) {
591
- if (checkUserIpAddress(req, res) == false) { return; }
592
- var domain = getDomain(req);
606
+ var domain = checkUserIpAddress(req, res);
607
+ if (domain == null) return;
608
if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid) || (domain.userQuota == -1)) { res.sendStatus(401); return; }
609
var user = obj.users[req.session.userid];
610
if ((user.siteadmin & 8) == 0) { res.sendStatus(401); return; } // Check if we have file rights
@@ -650,8 +665,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
665
666
// Handle a web socket relay request
667
function handleRelayWebSocket(ws, req) {
653
- if (checkUserIpAddress(ws, req) == false) { return; }
654
- var node, domain = getDomain(req);
668
+ var domain = checkUserIpAddress(ws, req);
669
+ if (domain == null) return;
670
// Check if this is a logged in user
671
var user, peering = true;
672
if (req.query.auth == null) {
@@ -677,7 +692,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
692
// Fetch information about the target
693
obj.db.Get(req.query.host, function (err, docs) {
694
if (docs.length == 0) { console.log('ERR: Node not found'); return; }
680
- node = docs[0];
695
+ var node = docs[0];
696
if (!node.intelamt) { console.log('ERR: Not AMT node'); return; }
697
698
// Check if this user has permission to manage this computer
@@ -915,7 +930,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
930
931
// Handle the web socket echo request, just echo back the data sent
932
function handleEchoWebSocket(ws, req) {
918
- if (checkUserIpAddress(ws, req) == false) { return; }
933
+ var domain = checkUserIpAddress(ws, req);
934
+ if (domain == null) return;
935
936
// When data is received from the web socket, echo it back
937
ws.on('message', function (data) {
@@ -968,8 +984,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
984
985
// Indicates we want to handle websocket requests on "/control.ashx".
986
function handleControlRequest(ws, req) {
971
- if (checkUserIpAddress(ws, req) == false) { return; }
972
- var domain = getDomain(req);
987
+ var domain = checkUserIpAddress(ws, req);
988
+ if (domain == null) return;
989
try {
990
// Check if the user is logged in
991
if ((!req.session) || (!req.session.userid) || (req.session.domainid != domain.id)) { try { ws.close(); } catch (e) { } return; }
@@ -1840,8 +1856,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
1856
1857
// Handle a server backup request
1858
function handleBackupRequest(req, res) {
1843
- if (checkUserIpAddress(req, res) == false) { return; }
1844
- var domain = getDomain(req);
1859
+ var domain = checkUserIpAddress(req, res);
1860
+ if (domain == null) return;
1861
if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid) || (obj.parent.args.noserverbackup == 1)) { res.sendStatus(401); return; }
1862
var user = obj.users[req.session.userid];
1863
if ((user.siteadmin & 1) == 0) { res.sendStatus(401); return; } // Check if we have server backup rights
@@ -1873,8 +1889,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
1889
1890
// Handle a server restore request
1891
function handleRestoreRequest(req, res) {
1876
- if (checkUserIpAddress(req, res) == false) { return; }
1877
- var domain = getDomain(req);
1892
+ var domain = checkUserIpAddress(req, res);
1893
+ if (domain == null) return;
1894
if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid) || (obj.parent.args.noserverbackup == 1)) { res.sendStatus(401); return; }
1895
var user = obj.users[req.session.userid];
1896
if ((user.siteadmin & 4) == 0) { res.sendStatus(401); return; } // Check if we have server restore rights
@@ -1918,8 +1934,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
1934
1935
// Handle a request to download a mesh settings
1936
obj.handleMeshSettingsRequest = function (req, res) {
1921
- if (checkUserIpAddress(req, res) == false) { return; }
1922
- var domain = getDomain(req);
1937
+ var domain = checkUserIpAddress(req, res);
1938
+ if (domain == null) return;
1939
//if ((domain.id !== '') || (!req.session) || (req.session == null) || (!req.session.userid)) { res.sendStatus(401); return; }
1940
1941
// Delete a mesh and all computers within it