Skip to content

Commit 293846d

Browse files
authored
build: release (#2336)
2 parents 9885ad0 + 684f088 commit 293846d

File tree

96 files changed

+8077
-7845
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+8077
-7845
lines changed

.eslintrc.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
{
2+
"root": true,
23
"env": {
34
"es6": true,
45
"node": true,
56
"browser": true
67
},
7-
"parser": "babel-eslint",
8+
"parser": "@babel/eslint-parser",
89
"extends": "eslint:recommended",
910
"parserOptions": {
10-
"ecmaFeatures": {
11-
"experimentalObjectRestSpread": true,
12-
"jsx": true
13-
},
1411
"sourceType": "module"
1512
},
1613
"plugins": ["react"],

.github/workflows/ci.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,8 @@ jobs:
111111
strategy:
112112
matrix:
113113
include:
114-
- name: Node 12
115-
NODE_VERSION: 12.22.12
116114
- name: Node 14
117-
NODE_VERSION: 14.20.0
115+
NODE_VERSION: 14.20.1
118116
- name: Node 16
119117
NODE_VERSION: 16.17.0
120118
- name: Node 18

Parse-Dashboard/index.js

+13-163
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@
77
*/
88
// Command line tool for npm start
99
'use strict'
10-
const path = require('path');
11-
const fs = require('fs');
12-
const express = require('express');
13-
const parseDashboard = require('./app');
1410
const CLIHelper = require('./CLIHelper.js');
11+
const startServer = require('./server');
1512

1613
const program = require('commander');
1714
program.option('--appId [appId]', 'the app Id of the app you would like to manage.');
@@ -31,168 +28,21 @@ program.option('--trustProxy [trustProxy]', 'set this flag when you are behind a
3128
program.option('--cookieSessionSecret [cookieSessionSecret]', 'set the cookie session secret, defaults to a random string. You should set that value if you want sessions to work across multiple server, or across restarts');
3229
program.option('--createUser', 'helper tool to allow you to generate secure user passwords and secrets. Use this on trusted devices only.');
3330
program.option('--createMFA', 'helper tool to allow you to generate multi-factor authentication secrets.');
34-
35-
program.parse(process.argv);
36-
const options = program.opts();
37-
38-
for (const key in options) {
39-
const func = CLIHelper[key];
40-
if (func && typeof func === 'function') {
41-
func();
42-
return;
43-
}
44-
}
45-
46-
const host = options.host || process.env.HOST || '0.0.0.0';
47-
const port = options.port || process.env.PORT || 4040;
48-
const mountPath = options.mountPath || process.env.MOUNT_PATH || '/';
49-
const allowInsecureHTTP = options.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
50-
const cookieSessionSecret = options.cookieSessionSecret || process.env.PARSE_DASHBOARD_COOKIE_SESSION_SECRET;
51-
const trustProxy = options.trustProxy || process.env.PARSE_DASHBOARD_TRUST_PROXY;
52-
const dev = options.dev;
53-
54-
if (trustProxy && allowInsecureHTTP) {
55-
console.log('Set only trustProxy *or* allowInsecureHTTP, not both. Only one is needed to handle being behind a proxy.');
56-
process.exit(-1);
57-
}
58-
59-
let explicitConfigFileProvided = !!options.config;
60-
let configFile = null;
61-
let configFromCLI = null;
62-
let configServerURL = options.serverURL || process.env.PARSE_DASHBOARD_SERVER_URL;
63-
let configGraphQLServerURL = options.graphQLServerURL || process.env.PARSE_DASHBOARD_GRAPHQL_SERVER_URL;
64-
let configMasterKey = options.masterKey || process.env.PARSE_DASHBOARD_MASTER_KEY;
65-
let configAppId = options.appId || process.env.PARSE_DASHBOARD_APP_ID;
66-
let configAppName = options.appName || process.env.PARSE_DASHBOARD_APP_NAME;
67-
let configUserId = options.userId || process.env.PARSE_DASHBOARD_USER_ID;
68-
let configUserPassword = options.userPassword || process.env.PARSE_DASHBOARD_USER_PASSWORD;
69-
let configSSLKey = options.sslKey || process.env.PARSE_DASHBOARD_SSL_KEY;
70-
let configSSLCert = options.sslCert || process.env.PARSE_DASHBOARD_SSL_CERT;
71-
72-
function handleSIGs(server) {
73-
const signals = {
74-
'SIGINT': 2,
75-
'SIGTERM': 15
76-
};
77-
function shutdown(signal, value) {
78-
server.close(function () {
79-
console.log('server stopped by ' + signal);
80-
process.exit(128 + value);
81-
});
82-
}
83-
Object.keys(signals).forEach(function (signal) {
84-
process.on(signal, function () {
85-
shutdown(signal, signals[signal]);
86-
});
87-
});
88-
}
89-
90-
if (!options.config && !process.env.PARSE_DASHBOARD_CONFIG) {
91-
if (configServerURL && configMasterKey && configAppId) {
92-
configFromCLI = {
93-
data: {
94-
apps: [
95-
{
96-
appId: configAppId,
97-
serverURL: configServerURL,
98-
masterKey: configMasterKey,
99-
appName: configAppName,
100-
},
101-
]
102-
}
103-
};
104-
if (configGraphQLServerURL) {
105-
configFromCLI.data.apps[0].graphQLServerURL = configGraphQLServerURL;
106-
}
107-
if (configUserId && configUserPassword) {
108-
configFromCLI.data.users = [
109-
{
110-
user: configUserId,
111-
pass: configUserPassword,
112-
}
113-
];
31+
program.action(async (options) => {
32+
for (const key in options) {
33+
const func = CLIHelper[key];
34+
if (func && typeof func === 'function') {
35+
await func();
36+
process.exit(0);
11437
}
115-
} else if (!configServerURL && !configMasterKey && !configAppName) {
116-
configFile = path.join(__dirname, 'parse-dashboard-config.json');
117-
}
118-
} else if (!options.config && process.env.PARSE_DASHBOARD_CONFIG) {
119-
configFromCLI = {
120-
data: JSON.parse(process.env.PARSE_DASHBOARD_CONFIG)
121-
};
122-
} else {
123-
configFile = options.config;
124-
if (options.appId || options.serverURL || options.masterKey || options.appName || options.graphQLServerURL) {
125-
console.log('You must provide either a config file or other CLI options (appName, appId, masterKey, serverURL, and graphQLServerURL); not both.');
126-
process.exit(3);
127-
}
128-
}
129-
130-
let config = null;
131-
let configFilePath = null;
132-
if (configFile) {
133-
try {
134-
config = {
135-
data: JSON.parse(fs.readFileSync(configFile, 'utf8'))
136-
};
137-
configFilePath = path.dirname(configFile);
138-
} catch (error) {
139-
if (error instanceof SyntaxError) {
140-
console.log('Your config file contains invalid JSON. Exiting.');
141-
process.exit(1);
142-
} else if (error.code === 'ENOENT') {
143-
if (explicitConfigFileProvided) {
144-
console.log('Your config file is missing. Exiting.');
145-
process.exit(2);
146-
} else {
147-
console.log('You must provide either a config file or required CLI options (app ID, Master Key, and server URL); not both.');
148-
process.exit(3);
149-
}
150-
} else {
151-
console.log('There was a problem with your config. Exiting.');
152-
process.exit(-1);
153-
}
154-
}
155-
} else if (configFromCLI) {
156-
config = configFromCLI;
157-
} else {
158-
//Failed to load default config file.
159-
console.log('You must provide either a config file or an app ID, Master Key, and server URL. See parse-dashboard --help for details.');
160-
process.exit(4);
161-
}
162-
163-
config.data.apps.forEach(app => {
164-
if (!app.appName) {
165-
app.appName = app.appId;
16638
}
16739
});
16840

169-
if (config.data.iconsFolder && configFilePath) {
170-
config.data.iconsFolder = path.join(configFilePath, config.data.iconsFolder);
171-
}
172-
173-
const app = express();
41+
async function run() {
42+
await program.parseAsync(process.argv);
43+
const options = program.opts();
17444

175-
if (allowInsecureHTTP || trustProxy || dev) app.enable('trust proxy');
176-
177-
config.data.trustProxy = trustProxy;
178-
let dashboardOptions = { allowInsecureHTTP, cookieSessionSecret, dev };
179-
app.use(mountPath, parseDashboard(config.data, dashboardOptions));
180-
let server;
181-
if(!configSSLKey || !configSSLCert){
182-
// Start the server.
183-
server = app.listen(port, host, function () {
184-
console.log(`The dashboard is now available at http://${server.address().address}:${server.address().port}${mountPath}`);
185-
});
186-
} else {
187-
// Start the server using SSL.
188-
var privateKey = fs.readFileSync(configSSLKey);
189-
var certificate = fs.readFileSync(configSSLCert);
190-
191-
server = require('https').createServer({
192-
key: privateKey,
193-
cert: certificate
194-
}, app).listen(port, host, function () {
195-
console.log(`The dashboard is now available at https://${server.address().address}:${server.address().port}${mountPath}`);
196-
});
45+
startServer(options);
19746
}
198-
handleSIGs(server);
47+
48+
run();

Parse-Dashboard/server.js

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright (c) 2016-present, Parse, LLC
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the license found in the LICENSE file in
6+
* the root directory of this source tree.
7+
*/
8+
// Command line tool for npm start
9+
'use strict'
10+
const path = require('path');
11+
const fs = require('fs');
12+
const express = require('express');
13+
const parseDashboard = require('./app');
14+
15+
module.exports = (options) => {
16+
const host = options.host || process.env.HOST || '0.0.0.0';
17+
const port = options.port || process.env.PORT || 4040;
18+
const mountPath = options.mountPath || process.env.MOUNT_PATH || '/';
19+
const allowInsecureHTTP = options.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
20+
const cookieSessionSecret = options.cookieSessionSecret || process.env.PARSE_DASHBOARD_COOKIE_SESSION_SECRET;
21+
const trustProxy = options.trustProxy || process.env.PARSE_DASHBOARD_TRUST_PROXY;
22+
const dev = options.dev;
23+
24+
if (trustProxy && allowInsecureHTTP) {
25+
console.log('Set only trustProxy *or* allowInsecureHTTP, not both. Only one is needed to handle being behind a proxy.');
26+
process.exit(-1);
27+
}
28+
29+
let explicitConfigFileProvided = !!options.config;
30+
let configFile = null;
31+
let configFromCLI = null;
32+
let configServerURL = options.serverURL || process.env.PARSE_DASHBOARD_SERVER_URL;
33+
let configGraphQLServerURL = options.graphQLServerURL || process.env.PARSE_DASHBOARD_GRAPHQL_SERVER_URL;
34+
let configMasterKey = options.masterKey || process.env.PARSE_DASHBOARD_MASTER_KEY;
35+
let configAppId = options.appId || process.env.PARSE_DASHBOARD_APP_ID;
36+
let configAppName = options.appName || process.env.PARSE_DASHBOARD_APP_NAME;
37+
let configUserId = options.userId || process.env.PARSE_DASHBOARD_USER_ID;
38+
let configUserPassword = options.userPassword || process.env.PARSE_DASHBOARD_USER_PASSWORD;
39+
let configSSLKey = options.sslKey || process.env.PARSE_DASHBOARD_SSL_KEY;
40+
let configSSLCert = options.sslCert || process.env.PARSE_DASHBOARD_SSL_CERT;
41+
42+
function handleSIGs(server) {
43+
const signals = {
44+
'SIGINT': 2,
45+
'SIGTERM': 15
46+
};
47+
function shutdown(signal, value) {
48+
server.close(function () {
49+
console.log('server stopped by ' + signal);
50+
process.exit(128 + value);
51+
});
52+
}
53+
Object.keys(signals).forEach(function (signal) {
54+
process.on(signal, function () {
55+
shutdown(signal, signals[signal]);
56+
});
57+
});
58+
}
59+
60+
if (!options.config && !process.env.PARSE_DASHBOARD_CONFIG) {
61+
if (configServerURL && configMasterKey && configAppId) {
62+
configFromCLI = {
63+
data: {
64+
apps: [
65+
{
66+
appId: configAppId,
67+
serverURL: configServerURL,
68+
masterKey: configMasterKey,
69+
appName: configAppName,
70+
},
71+
]
72+
}
73+
};
74+
if (configGraphQLServerURL) {
75+
configFromCLI.data.apps[0].graphQLServerURL = configGraphQLServerURL;
76+
}
77+
if (configUserId && configUserPassword) {
78+
configFromCLI.data.users = [
79+
{
80+
user: configUserId,
81+
pass: configUserPassword,
82+
}
83+
];
84+
}
85+
} else if (!configServerURL && !configMasterKey && !configAppName) {
86+
configFile = path.join(__dirname, 'parse-dashboard-config.json');
87+
}
88+
} else if (!options.config && process.env.PARSE_DASHBOARD_CONFIG) {
89+
configFromCLI = {
90+
data: JSON.parse(process.env.PARSE_DASHBOARD_CONFIG)
91+
};
92+
} else {
93+
configFile = options.config;
94+
if (options.appId || options.serverURL || options.masterKey || options.appName || options.graphQLServerURL) {
95+
console.log('You must provide either a config file or other CLI options (appName, appId, masterKey, serverURL, and graphQLServerURL); not both.');
96+
process.exit(3);
97+
}
98+
}
99+
100+
let config = null;
101+
let configFilePath = null;
102+
if (configFile) {
103+
try {
104+
config = {
105+
data: JSON.parse(fs.readFileSync(configFile, 'utf8'))
106+
};
107+
configFilePath = path.dirname(configFile);
108+
} catch (error) {
109+
if (error instanceof SyntaxError) {
110+
console.log('Your config file contains invalid JSON. Exiting.');
111+
process.exit(1);
112+
} else if (error.code === 'ENOENT') {
113+
if (explicitConfigFileProvided) {
114+
console.log('Your config file is missing. Exiting.');
115+
process.exit(2);
116+
} else {
117+
console.log('You must provide either a config file or required CLI options (app ID, Master Key, and server URL); not both.');
118+
process.exit(3);
119+
}
120+
} else {
121+
console.log('There was a problem with your config. Exiting.');
122+
process.exit(-1);
123+
}
124+
}
125+
} else if (configFromCLI) {
126+
config = configFromCLI;
127+
} else {
128+
//Failed to load default config file.
129+
console.log('You must provide either a config file or an app ID, Master Key, and server URL. See parse-dashboard --help for details.');
130+
process.exit(4);
131+
}
132+
133+
config.data.apps.forEach(app => {
134+
if (!app.appName) {
135+
app.appName = app.appId;
136+
}
137+
});
138+
139+
if (config.data.iconsFolder && configFilePath) {
140+
config.data.iconsFolder = path.join(configFilePath, config.data.iconsFolder);
141+
}
142+
143+
const app = express();
144+
145+
if (allowInsecureHTTP || trustProxy || dev) app.enable('trust proxy');
146+
147+
config.data.trustProxy = trustProxy;
148+
let dashboardOptions = { allowInsecureHTTP, cookieSessionSecret, dev };
149+
app.use(mountPath, parseDashboard(config.data, dashboardOptions));
150+
let server;
151+
if(!configSSLKey || !configSSLCert){
152+
// Start the server.
153+
server = app.listen(port, host, function () {
154+
console.log(`The dashboard is now available at http://${server.address().address}:${server.address().port}${mountPath}`);
155+
});
156+
} else {
157+
// Start the server using SSL.
158+
var privateKey = fs.readFileSync(configSSLKey);
159+
var certificate = fs.readFileSync(configSSLCert);
160+
161+
server = require('https').createServer({
162+
key: privateKey,
163+
cert: certificate
164+
}, app).listen(port, host, function () {
165+
console.log(`The dashboard is now available at https://${server.address().address}:${server.address().port}${mountPath}`);
166+
});
167+
}
168+
handleSIGs(server);
169+
};

0 commit comments

Comments
 (0)