Skip to content

Commit 68432e7

Browse files
authored
Adds dev flag (#962)
* Adds dev mode when running with docker, as the local IP address is different from the dashboard all the security features would light up. This --dev flag let anyone run the dashboard locally easily * Update index.js
1 parent 4eac5f3 commit 68432e7

File tree

4 files changed

+49
-19
lines changed

4 files changed

+49
-19
lines changed

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ COPY --from=base /src/package*.json /src/
3030
# Copy compiled src dirs
3131
COPY --from=base /src/Parse-Dashboard/ /src/Parse-Dashboard/
3232

33+
USER node
34+
3335
ENTRYPOINT ["node", "Parse-Dashboard/index.js"]

Parse-Dashboard/app.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,17 @@ module.exports = function(config, options) {
8888
req.connection.remoteAddress === '127.0.0.1' ||
8989
req.connection.remoteAddress === '::ffff:127.0.0.1' ||
9090
req.connection.remoteAddress === '::1';
91-
if (!requestIsLocal && !req.secure && !options.allowInsecureHTTP) {
92-
//Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext
93-
return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' });
94-
}
91+
if (!options.dev && !requestIsLocal) {
92+
if (!req.secure && !options.allowInsecureHTTP) {
93+
//Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext
94+
return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' });
95+
}
9596

96-
if (!requestIsLocal && !users) {
97-
//Accessing the dashboard over the internet can only be done with username and password
98-
return res.send({ success: false, error: 'Configure a user to access Parse Dashboard remotely' });
97+
if (!users) {
98+
//Accessing the dashboard over the internet can only be done with username and password
99+
return res.send({ success: false, error: 'Configure a user to access Parse Dashboard remotely' });
100+
}
99101
}
100-
101102
const authentication = req.user;
102103

103104
const successfulAuth = authentication && authentication.isAuthenticated;
@@ -139,7 +140,7 @@ module.exports = function(config, options) {
139140

140141
//They didn't provide auth, and have configured the dashboard to not need auth
141142
//(ie. didn't supply usernames and passwords)
142-
if (requestIsLocal) {
143+
if (requestIsLocal || options.dev) {
143144
//Allow no-auth access on localhost only, if they have configured the dashboard to not need auth
144145
return res.json(response);
145146
}

Parse-Dashboard/index.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const program = require('commander');
1616
program.option('--appId [appId]', 'the app Id of the app you would like to manage.');
1717
program.option('--masterKey [masterKey]', 'the master key of the app you would like to manage.');
1818
program.option('--serverURL [serverURL]', 'the server url of the app you would like to manage.');
19+
program.option('--dev', 'Enable development mode. This will disable authentication and allow non HTTPS connections. DO NOT ENABLE IN PRODUCTION SERVERS');
1920
program.option('--appName [appName]', 'the name of the app you would like to manage. Optional.');
2021
program.option('--config [config]', 'the path to the configuration file');
2122
program.option('--host [host]', 'the host to run parse-dashboard');
@@ -35,6 +36,7 @@ const mountPath = program.mountPath || process.env.MOUNT_PATH || '/';
3536
const allowInsecureHTTP = program.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
3637
const cookieSessionSecret = program.cookieSessionSecret || process.env.PARSE_DASHBOARD_COOKIE_SESSION_SECRET;
3738
const trustProxy = program.trustProxy || process.env.PARSE_DASHBOARD_TRUST_PROXY;
39+
const dev = program.dev;
3840

3941
if (trustProxy && allowInsecureHTTP) {
4042
console.log("Set only trustProxy *or* allowInsecureHTTP, not both. Only one is needed to handle being behind a proxy.");
@@ -52,6 +54,25 @@ let configUserId = program.userId || process.env.PARSE_DASHBOARD_USER_ID;
5254
let configUserPassword = program.userPassword || process.env.PARSE_DASHBOARD_USER_PASSWORD;
5355
let configSSLKey = program.sslKey || process.env.PARSE_DASHBOARD_SSL_KEY;
5456
let configSSLCert = program.sslCert || process.env.PARSE_DASHBOARD_SSL_CERT;
57+
58+
function handleSIGs(server) {
59+
const signals = {
60+
'SIGINT': 2,
61+
'SIGTERM': 15
62+
};
63+
function shutdown(signal, value) {
64+
server.close(function () {
65+
console.log('server stopped by ' + signal);
66+
process.exit(128 + value);
67+
});
68+
}
69+
Object.keys(signals).forEach(function (signal) {
70+
process.on(signal, function () {
71+
shutdown(signal, signals[signal]);
72+
});
73+
});
74+
}
75+
5576
if (!program.config && !process.env.PARSE_DASHBOARD_CONFIG) {
5677
if (configServerURL && configMasterKey && configAppId) {
5778
configFromCLI = {
@@ -114,14 +135,15 @@ p.then(config => {
114135

115136
const app = express();
116137

117-
if (allowInsecureHTTP || trustProxy) app.enable('trust proxy');
138+
if (allowInsecureHTTP || trustProxy || dev) app.enable('trust proxy');
118139

119140
config.data.trustProxy = trustProxy;
120-
let dashboardOptions = { allowInsecureHTTP: allowInsecureHTTP, cookieSessionSecret: cookieSessionSecret };
141+
let dashboardOptions = { allowInsecureHTTP, cookieSessionSecret, dev };
121142
app.use(mountPath, parseDashboard(config.data, dashboardOptions));
143+
let server;
122144
if(!configSSLKey || !configSSLCert){
123145
// Start the server.
124-
const server = app.listen(port, host, function () {
146+
server = app.listen(port, host, function () {
125147
console.log(`The dashboard is now available at http://${server.address().address}:${server.address().port}${mountPath}`);
126148
});
127149
} else {
@@ -130,13 +152,14 @@ p.then(config => {
130152
var privateKey = fs.readFileSync(configSSLKey);
131153
var certificate = fs.readFileSync(configSSLCert);
132154

133-
const server = require('https').createServer({
155+
server = require('https').createServer({
134156
key: privateKey,
135157
cert: certificate
136158
}, app).listen(port, host, function () {
137159
console.log(`The dashboard is now available at https://${server.address().address}:${server.address().port}${mountPath}`);
138160
});
139161
}
162+
handleSIGs(server);
140163
}, error => {
141164
if (error instanceof SyntaxError) {
142165
console.log('Your config file contains invalid JSON. Exiting.');

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ npm install -g parse-dashboard
4747
You can launch the dashboard for an app with a single command by supplying an app ID, master key, URL, and name like this:
4848

4949
```
50-
parse-dashboard --appId yourAppId --masterKey yourMasterKey --serverURL "https://example.com/parse" --appName optionalName
50+
parse-dashboard --dev --appId yourAppId --masterKey yourMasterKey --serverURL "https://example.com/parse" --appName optionalName
5151
```
5252

5353
You may set the host, port and mount path by supplying the `--host`, `--port` and `--mountPath` options to parse-dashboard. You can use anything you want as the app name, or leave it out in which case the app ID will be used.
5454

55+
NB: the `--dev` parameter is disabling production-ready security features, do not use this parameter when starting the dashboard in production. This parameter is useful is you are running on docker.
56+
5557
After starting the dashboard, you can visit http://localhost:4040 in your browser:
5658

5759
![Parse Dashboard](.github/dash-shot.png)
@@ -451,24 +453,26 @@ You can provide a list of locales or languages you want to support for your dash
451453

452454
## Run with Docker
453455

454-
It is easy to use it with Docker. First build the image:
456+
The official docker image is published on [docker hub](https://hub.docker.com/r/parseplatform/parse-dashboard)
457+
458+
Run the image with your ``config.json`` mounted as a volume
455459

456460
```
457-
docker build -t parse-dashboard .
461+
docker run -d -p 8080:4040 -v host/path/to/config.json:/src/Parse-Dashboard/parse-dashboard-config.json parseplatform/parse-dashboard --dev
458462
```
459463

460-
Run the image with your ``config.json`` mounted as a volume
464+
You can also pass the appId, masterKey and serverURL as arguments:
461465

462466
```
463-
docker run -d -p 8080:4040 -v host/path/to/config.json:/src/Parse-Dashboard/parse-dashboard-config.json parse-dashboard
467+
docker run -d -p 4040:4040 parseplatform/parse-dashboard --dev --appId $APP_ID --masterKey $MASTER_KEY --serverURL $SERVER_URL
464468
```
465469

466470
By default, the container will start the app at port 4040 inside the container. However, you can run custom command as well (see ``Deploying in production`` for custom setup).
467471

468472
In this example, we want to run the application in production mode at port 80 of the host machine.
469473

470474
```
471-
docker run -d -p 80:8080 -v host/path/to/config.json:/src/Parse-Dashboard/parse-dashboard-config.json parse-dashboard --port 8080
475+
docker run -d -p 80:8080 -v host/path/to/config.json:/src/Parse-Dashboard/parse-dashboard-config.json parse-dashboard --port 8080 --dev
472476
```
473477

474478
If you are not familiar with Docker, ``--port 8080`` will be passed in as argument to the entrypoint to form the full command ``npm start -- --port 8080``. The application will start at port 8080 inside the container and port ``8080`` will be mounted to port ``80`` on your host machine.

0 commit comments

Comments
 (0)