Skip to content

Commit 9ef4a58

Browse files
committed
Merge pull request #214 from ParsePlatform/standalone-express-app
🚧 Splits express app from express server
2 parents aed7111 + fbaaff2 commit 9ef4a58

File tree

3 files changed

+93
-82
lines changed

3 files changed

+93
-82
lines changed

Parse-Dashboard/app.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'use strict';
2+
const express = require('express');
3+
const basicAuth = require('basic-auth');
4+
const path = require('path');
5+
const packageJson = require('package-json');
6+
7+
const currentVersionFeatures = require('../package.json').parseDashboardFeatures;
8+
9+
var newFeaturesInLatestVersion = [];
10+
packageJson('parse-dashboard', 'latest').then(latestPackage => {
11+
if (latestPackage.parseDashboardFeatures instanceof Array) {
12+
newFeaturesInLatestVersion = latestPackage.parseDashboardFeatures.filter(feature => {
13+
return currentVersionFeatures.indexOf(feature) === -1;
14+
});
15+
}
16+
});
17+
18+
module.exports = function(config) {
19+
var app = express();
20+
// Serve public files.
21+
app.use(express.static(path.join(__dirname,'public')));
22+
23+
// Serve the configuration.
24+
app.get('/parse-dashboard-config.json', function(req, res) {
25+
const response = {
26+
apps: config.apps,
27+
newFeaturesInLatestVersion: newFeaturesInLatestVersion,
28+
};
29+
const users = config.users;
30+
31+
let auth = null;
32+
//If they provide auth when their config has no users, ignore the auth
33+
if (users) {
34+
auth = basicAuth(req);
35+
}
36+
37+
//Based on advice from Doug Wilson here:
38+
//https://github.com/expressjs/express/issues/2518
39+
const requestIsLocal =
40+
req.connection.remoteAddress === '127.0.0.1' ||
41+
req.connection.remoteAddress === '::ffff:127.0.0.1' ||
42+
req.connection.remoteAddress === '::1';
43+
if (!requestIsLocal && !req.secure && !allowInsecureHTTP) {
44+
//Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext
45+
return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' });
46+
}
47+
48+
if (!requestIsLocal && !users) {
49+
//Accessing the dashboard over the internet can only be done with username and password
50+
return res.send({ success: false, error: 'Configure a user to access Parse Dashboard remotely' });
51+
}
52+
53+
const successfulAuth =
54+
//they provided auth
55+
auth &&
56+
//there are configured users
57+
users &&
58+
//the provided auth matches one of the users
59+
users.find(user => {
60+
return user.user == auth.name &&
61+
user.pass == auth.pass
62+
});
63+
if (successfulAuth) {
64+
//They provided correct auth
65+
return res.json(response);
66+
}
67+
68+
if (users || auth) {
69+
//They provided incorrect auth
70+
res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
71+
return res.sendStatus(401);
72+
}
73+
74+
//They didn't provide auth, and have configured the dashboard to not need auth
75+
//(ie. didn't supply usernames and passwords)
76+
if (requestIsLocal) {
77+
//Allow no-auth access on localhost only, if they have configured the dashboard to not need auth
78+
return res.json(response);
79+
}
80+
//We shouldn't get here. Fail closed.
81+
res.send({ success: false, error: 'Something went wrong.' });
82+
});
83+
84+
// For every other request, go to index.html. Let client-side handle the rest.
85+
app.get('/*', function(req, res) {
86+
res.sendFile(__dirname + '/index.html');
87+
});
88+
89+
return app;
90+
}

Parse-Dashboard/index.js

Lines changed: 2 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@
77
*/
88
// Command line tool for npm start
99
"use strict"
10-
const packageJson = require('package-json');
11-
const basicAuth = require('basic-auth');
1210
const path = require('path');
1311
const jsonFile = require('json-file-plus');
1412
const express = require('express');
13+
const parseDashboard = require('./app');
1514

1615
const program = require('commander');
1716
program.option('--appId [appId]', 'the app Id of the app you would like to manage.');
@@ -24,17 +23,6 @@ program.option('--allowInsecureHTTP [allowInsecureHTTP]', 'set this flag when yo
2423

2524
program.parse(process.argv);
2625

27-
const currentVersionFeatures = require('../package.json').parseDashboardFeatures;
28-
29-
var newFeaturesInLatestVersion = [];
30-
packageJson('parse-dashboard', 'latest').then(latestPackage => {
31-
if (latestPackage.parseDashboardFeatures instanceof Array) {
32-
newFeaturesInLatestVersion = latestPackage.parseDashboardFeatures.filter(feature => {
33-
return currentVersionFeatures.indexOf(feature) === -1;
34-
});
35-
}
36-
});
37-
3826
const port = program.port || process.env.PORT || 4040;
3927
const allowInsecureHTTP = program.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
4028

@@ -103,75 +91,7 @@ p.then(config => {
10391

10492
const app = express();
10593

106-
// Serve public files.
107-
app.use(express.static(path.join(__dirname,'public')));
108-
109-
// Serve the configuration.
110-
app.get('/parse-dashboard-config.json', function(req, res) {
111-
const response = {
112-
apps: config.data.apps,
113-
newFeaturesInLatestVersion: newFeaturesInLatestVersion,
114-
};
115-
const users = config.data.users;
116-
117-
let auth = null;
118-
//If they provide auth when their config has no users, ignore the auth
119-
if (users) {
120-
auth = basicAuth(req);
121-
}
122-
123-
//Based on advice from Doug Wilson here:
124-
//https://github.com/expressjs/express/issues/2518
125-
const requestIsLocal =
126-
req.connection.remoteAddress === '127.0.0.1' ||
127-
req.connection.remoteAddress === '::ffff:127.0.0.1' ||
128-
req.connection.remoteAddress === '::1';
129-
if (!requestIsLocal && !req.secure && !allowInsecureHTTP) {
130-
//Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext
131-
return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' });
132-
}
133-
134-
if (!requestIsLocal && !users) {
135-
//Accessing the dashboard over the internet can only be done with username and password
136-
return res.send({ success: false, error: 'Configure a user to access Parse Dashboard remotely' });
137-
}
138-
139-
const successfulAuth =
140-
//they provided auth
141-
auth &&
142-
//there are configured users
143-
users &&
144-
//the provided auth matches one of the users
145-
users.find(user => {
146-
return user.user == auth.name &&
147-
user.pass == auth.pass
148-
});
149-
if (successfulAuth) {
150-
//They provided correct auth
151-
return res.json(response);
152-
}
153-
154-
if (users || auth) {
155-
//They provided incorrect auth
156-
res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
157-
return res.sendStatus(401);
158-
}
159-
160-
//They didn't provide auth, and have configured the dashboard to not need auth
161-
//(ie. didn't supply usernames and passwords)
162-
if (requestIsLocal) {
163-
//Allow no-auth access on localhost only, if they have configured the dashboard to not need auth
164-
return res.json(response);
165-
}
166-
//We shouldn't get here. Fail closed.
167-
res.send({ success: false, error: 'Something went wrong.' });
168-
});
169-
170-
// For every other request, go to index.html. Let client-side handle the rest.
171-
app.get('/*', function(req, res) {
172-
res.sendFile(__dirname + '/index.html');
173-
});
174-
94+
app.use(parseDashboard(config.data));
17595
// Start the server.
17696
app.listen(port);
17797

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"engines": {
8282
"node": ">=4.3"
8383
},
84+
"main": "Parse-Dashboard/app.js",
8485
"jest": {
8586
"testPathDirs": [
8687
"src/lib"

0 commit comments

Comments
 (0)