Skip to content

build: release beta #2328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
18b0e76
feat: remove Node 12 support (#2277)
damianstasik Sep 27, 2022
443e925
chore(release): 5.0.0-alpha.1 [skip ci]
semantic-release-bot Sep 27, 2022
50de52b
fix: increase required Node engine version to `>=14.20.1`; this is a …
mtrezza Sep 27, 2022
32ba45c
chore(release): 5.0.0-alpha.2 [skip ci]
semantic-release-bot Sep 27, 2022
4ac4c88
docs: fix too long changelog entry
mtrezza Sep 27, 2022
e9fa9ae
refactor: bump got and all-node-versions (#2228)
dependabot[bot] Sep 27, 2022
51d083b
fix: minor UI layout issues (#2270)
dblythy Sep 27, 2022
eb476be
chore(release): 5.0.0-alpha.3 [skip ci]
semantic-release-bot Sep 27, 2022
29a69f7
refactor: upgrade copy-to-clipboard from 3.3.1 to 3.3.2 (#2287)
snyk-bot Sep 29, 2022
0d61e20
refactor: upgrade typescript from 4.7.4 to 4.8.2 (#2283)
snyk-bot Sep 29, 2022
3ee3caf
refactor: upgrade graphiql from 1.10.0 to 2.0.6 (#2284)
snyk-bot Sep 29, 2022
5acb944
refactor: upgrade js-beautify from 1.14.4 to 1.14.6 (#2285)
snyk-bot Sep 29, 2022
dcc87ae
refactor: upgrade @babel/runtime from 7.18.9 to 7.19.0 (#2286)
snyk-bot Sep 29, 2022
69557f3
refactor: use `ref` API instead of `findDOMNode` (#1952)
damianstasik Sep 30, 2022
aeea299
ci: update test dependencies (#2289)
damianstasik Sep 30, 2022
f9d38b0
refactor: upgrade graphiql from 2.0.6 to 2.0.7 (#2292)
parseplatformorg Sep 30, 2022
0b01191
refactor: upgrade prismjs from 1.28.0 to 1.29.0 (#2295)
parseplatformorg Sep 30, 2022
f2c5e43
refactor: upgrade otpauth from 8.0.1 to 8.0.2 (#2294)
parseplatformorg Sep 30, 2022
7eaa0a0
refactor: upgrade core-js from 3.24.1 to 3.25.1 (#2291)
parseplatformorg Sep 30, 2022
5ca0b77
refactor: upgrade graphql from 16.5.0 to 16.6.0 (#2293)
parseplatformorg Sep 30, 2022
f9bce7f
refactor: remove unused dependencies (#2299)
damianstasik Oct 1, 2022
f3dc017
refactor: upgrade styling dependencies (#2300)
damianstasik Oct 1, 2022
650bcd5
refactor: upgrade React Router to v6 (#1954)
damianstasik Oct 1, 2022
c3bb6a1
refactor: upgrade semantic-release dependency (#2301)
damianstasik Oct 1, 2022
58f3d05
refactor: upgrade linting dependencies (#1946)
damianstasik Oct 1, 2022
894c6c7
refactor: bump json-schema and jsprim (#2303)
dependabot[bot] Oct 1, 2022
8e60931
refactor: upgrade typescript from 4.8.2 to 4.8.3 (#2308)
parseplatformorg Oct 2, 2022
d6d38bf
feat: keep entered filter value when changing filter operator (#2313)
dblythy Oct 9, 2022
2cc5d03
chore(release): 5.0.0-alpha.4 [skip ci]
semantic-release-bot Oct 9, 2022
716820c
refactor: upgrade graphiql from 2.0.7 to 2.0.8 (#2321)
parseplatformorg Oct 14, 2022
d04c5c3
refactor: upgrade otpauth from 8.0.2 to 8.0.3 (#2322)
parseplatformorg Oct 15, 2022
23c12ff
feat: improve distinction between deletion confirmation dialogs (#2319)
sadakchap Oct 15, 2022
d5788b8
chore(release): 5.0.0-alpha.5 [skip ci]
semantic-release-bot Oct 15, 2022
4af7b98
fix: raw value of read-only date field in data browser cannot be copi…
mtrezza Oct 15, 2022
bd975b0
chore(release): 5.0.0-alpha.6 [skip ci]
semantic-release-bot Oct 15, 2022
7d9b957
fix: using browser navigation backward / forward button clears data b…
damianstasik Oct 17, 2022
46c29db
chore(release): 5.0.0-alpha.7 [skip ci]
semantic-release-bot Oct 17, 2022
aadbe88
Merge branch 'beta' into build-beta
mtrezza Oct 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
{
"root": true,
"env": {
"es6": true,
"node": true,
"browser": true
},
"parser": "babel-eslint",
"parser": "@babel/eslint-parser",
"extends": "eslint:recommended",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
"plugins": ["react"],
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,8 @@ jobs:
strategy:
matrix:
include:
- name: Node 12
NODE_VERSION: 12.22.12
- name: Node 14
NODE_VERSION: 14.20.0
NODE_VERSION: 14.20.1
- name: Node 16
NODE_VERSION: 16.17.0
- name: Node 18
Expand Down
176 changes: 13 additions & 163 deletions Parse-Dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@
*/
// Command line tool for npm start
'use strict'
const path = require('path');
const fs = require('fs');
const express = require('express');
const parseDashboard = require('./app');
const CLIHelper = require('./CLIHelper.js');
const startServer = require('./server');

const program = require('commander');
program.option('--appId [appId]', 'the app Id of the app you would like to manage.');
Expand All @@ -31,168 +28,21 @@ program.option('--trustProxy [trustProxy]', 'set this flag when you are behind a
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');
program.option('--createUser', 'helper tool to allow you to generate secure user passwords and secrets. Use this on trusted devices only.');
program.option('--createMFA', 'helper tool to allow you to generate multi-factor authentication secrets.');

program.parse(process.argv);
const options = program.opts();

for (const key in options) {
const func = CLIHelper[key];
if (func && typeof func === 'function') {
func();
return;
}
}

const host = options.host || process.env.HOST || '0.0.0.0';
const port = options.port || process.env.PORT || 4040;
const mountPath = options.mountPath || process.env.MOUNT_PATH || '/';
const allowInsecureHTTP = options.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
const cookieSessionSecret = options.cookieSessionSecret || process.env.PARSE_DASHBOARD_COOKIE_SESSION_SECRET;
const trustProxy = options.trustProxy || process.env.PARSE_DASHBOARD_TRUST_PROXY;
const dev = options.dev;

if (trustProxy && allowInsecureHTTP) {
console.log('Set only trustProxy *or* allowInsecureHTTP, not both. Only one is needed to handle being behind a proxy.');
process.exit(-1);
}

let explicitConfigFileProvided = !!options.config;
let configFile = null;
let configFromCLI = null;
let configServerURL = options.serverURL || process.env.PARSE_DASHBOARD_SERVER_URL;
let configGraphQLServerURL = options.graphQLServerURL || process.env.PARSE_DASHBOARD_GRAPHQL_SERVER_URL;
let configMasterKey = options.masterKey || process.env.PARSE_DASHBOARD_MASTER_KEY;
let configAppId = options.appId || process.env.PARSE_DASHBOARD_APP_ID;
let configAppName = options.appName || process.env.PARSE_DASHBOARD_APP_NAME;
let configUserId = options.userId || process.env.PARSE_DASHBOARD_USER_ID;
let configUserPassword = options.userPassword || process.env.PARSE_DASHBOARD_USER_PASSWORD;
let configSSLKey = options.sslKey || process.env.PARSE_DASHBOARD_SSL_KEY;
let configSSLCert = options.sslCert || process.env.PARSE_DASHBOARD_SSL_CERT;

function handleSIGs(server) {
const signals = {
'SIGINT': 2,
'SIGTERM': 15
};
function shutdown(signal, value) {
server.close(function () {
console.log('server stopped by ' + signal);
process.exit(128 + value);
});
}
Object.keys(signals).forEach(function (signal) {
process.on(signal, function () {
shutdown(signal, signals[signal]);
});
});
}

if (!options.config && !process.env.PARSE_DASHBOARD_CONFIG) {
if (configServerURL && configMasterKey && configAppId) {
configFromCLI = {
data: {
apps: [
{
appId: configAppId,
serverURL: configServerURL,
masterKey: configMasterKey,
appName: configAppName,
},
]
}
};
if (configGraphQLServerURL) {
configFromCLI.data.apps[0].graphQLServerURL = configGraphQLServerURL;
}
if (configUserId && configUserPassword) {
configFromCLI.data.users = [
{
user: configUserId,
pass: configUserPassword,
}
];
program.action(async (options) => {
for (const key in options) {
const func = CLIHelper[key];
if (func && typeof func === 'function') {
await func();
process.exit(0);
}
} else if (!configServerURL && !configMasterKey && !configAppName) {
configFile = path.join(__dirname, 'parse-dashboard-config.json');
}
} else if (!options.config && process.env.PARSE_DASHBOARD_CONFIG) {
configFromCLI = {
data: JSON.parse(process.env.PARSE_DASHBOARD_CONFIG)
};
} else {
configFile = options.config;
if (options.appId || options.serverURL || options.masterKey || options.appName || options.graphQLServerURL) {
console.log('You must provide either a config file or other CLI options (appName, appId, masterKey, serverURL, and graphQLServerURL); not both.');
process.exit(3);
}
}

let config = null;
let configFilePath = null;
if (configFile) {
try {
config = {
data: JSON.parse(fs.readFileSync(configFile, 'utf8'))
};
configFilePath = path.dirname(configFile);
} catch (error) {
if (error instanceof SyntaxError) {
console.log('Your config file contains invalid JSON. Exiting.');
process.exit(1);
} else if (error.code === 'ENOENT') {
if (explicitConfigFileProvided) {
console.log('Your config file is missing. Exiting.');
process.exit(2);
} else {
console.log('You must provide either a config file or required CLI options (app ID, Master Key, and server URL); not both.');
process.exit(3);
}
} else {
console.log('There was a problem with your config. Exiting.');
process.exit(-1);
}
}
} else if (configFromCLI) {
config = configFromCLI;
} else {
//Failed to load default config file.
console.log('You must provide either a config file or an app ID, Master Key, and server URL. See parse-dashboard --help for details.');
process.exit(4);
}

config.data.apps.forEach(app => {
if (!app.appName) {
app.appName = app.appId;
}
});

if (config.data.iconsFolder && configFilePath) {
config.data.iconsFolder = path.join(configFilePath, config.data.iconsFolder);
}

const app = express();
async function run() {
await program.parseAsync(process.argv);
const options = program.opts();

if (allowInsecureHTTP || trustProxy || dev) app.enable('trust proxy');

config.data.trustProxy = trustProxy;
let dashboardOptions = { allowInsecureHTTP, cookieSessionSecret, dev };
app.use(mountPath, parseDashboard(config.data, dashboardOptions));
let server;
if(!configSSLKey || !configSSLCert){
// Start the server.
server = app.listen(port, host, function () {
console.log(`The dashboard is now available at http://${server.address().address}:${server.address().port}${mountPath}`);
});
} else {
// Start the server using SSL.
var privateKey = fs.readFileSync(configSSLKey);
var certificate = fs.readFileSync(configSSLCert);

server = require('https').createServer({
key: privateKey,
cert: certificate
}, app).listen(port, host, function () {
console.log(`The dashboard is now available at https://${server.address().address}:${server.address().port}${mountPath}`);
});
startServer(options);
}
handleSIGs(server);

run();
169 changes: 169 additions & 0 deletions Parse-Dashboard/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2016-present, Parse, LLC
* All rights reserved.
*
* This source code is licensed under the license found in the LICENSE file in
* the root directory of this source tree.
*/
// Command line tool for npm start
'use strict'
const path = require('path');
const fs = require('fs');
const express = require('express');
const parseDashboard = require('./app');

module.exports = (options) => {
const host = options.host || process.env.HOST || '0.0.0.0';
const port = options.port || process.env.PORT || 4040;
const mountPath = options.mountPath || process.env.MOUNT_PATH || '/';
const allowInsecureHTTP = options.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
const cookieSessionSecret = options.cookieSessionSecret || process.env.PARSE_DASHBOARD_COOKIE_SESSION_SECRET;
const trustProxy = options.trustProxy || process.env.PARSE_DASHBOARD_TRUST_PROXY;
const dev = options.dev;

if (trustProxy && allowInsecureHTTP) {
console.log('Set only trustProxy *or* allowInsecureHTTP, not both. Only one is needed to handle being behind a proxy.');
process.exit(-1);
}

let explicitConfigFileProvided = !!options.config;
let configFile = null;
let configFromCLI = null;
let configServerURL = options.serverURL || process.env.PARSE_DASHBOARD_SERVER_URL;
let configGraphQLServerURL = options.graphQLServerURL || process.env.PARSE_DASHBOARD_GRAPHQL_SERVER_URL;
let configMasterKey = options.masterKey || process.env.PARSE_DASHBOARD_MASTER_KEY;
let configAppId = options.appId || process.env.PARSE_DASHBOARD_APP_ID;
let configAppName = options.appName || process.env.PARSE_DASHBOARD_APP_NAME;
let configUserId = options.userId || process.env.PARSE_DASHBOARD_USER_ID;
let configUserPassword = options.userPassword || process.env.PARSE_DASHBOARD_USER_PASSWORD;
let configSSLKey = options.sslKey || process.env.PARSE_DASHBOARD_SSL_KEY;
let configSSLCert = options.sslCert || process.env.PARSE_DASHBOARD_SSL_CERT;

function handleSIGs(server) {
const signals = {
'SIGINT': 2,
'SIGTERM': 15
};
function shutdown(signal, value) {
server.close(function () {
console.log('server stopped by ' + signal);
process.exit(128 + value);
});
}
Object.keys(signals).forEach(function (signal) {
process.on(signal, function () {
shutdown(signal, signals[signal]);
});
});
}

if (!options.config && !process.env.PARSE_DASHBOARD_CONFIG) {
if (configServerURL && configMasterKey && configAppId) {
configFromCLI = {
data: {
apps: [
{
appId: configAppId,
serverURL: configServerURL,
masterKey: configMasterKey,
appName: configAppName,
},
]
}
};
if (configGraphQLServerURL) {
configFromCLI.data.apps[0].graphQLServerURL = configGraphQLServerURL;
}
if (configUserId && configUserPassword) {
configFromCLI.data.users = [
{
user: configUserId,
pass: configUserPassword,
}
];
}
} else if (!configServerURL && !configMasterKey && !configAppName) {
configFile = path.join(__dirname, 'parse-dashboard-config.json');
}
} else if (!options.config && process.env.PARSE_DASHBOARD_CONFIG) {
configFromCLI = {
data: JSON.parse(process.env.PARSE_DASHBOARD_CONFIG)
};
} else {
configFile = options.config;
if (options.appId || options.serverURL || options.masterKey || options.appName || options.graphQLServerURL) {
console.log('You must provide either a config file or other CLI options (appName, appId, masterKey, serverURL, and graphQLServerURL); not both.');
process.exit(3);
}
}

let config = null;
let configFilePath = null;
if (configFile) {
try {
config = {
data: JSON.parse(fs.readFileSync(configFile, 'utf8'))
};
configFilePath = path.dirname(configFile);
} catch (error) {
if (error instanceof SyntaxError) {
console.log('Your config file contains invalid JSON. Exiting.');
process.exit(1);
} else if (error.code === 'ENOENT') {
if (explicitConfigFileProvided) {
console.log('Your config file is missing. Exiting.');
process.exit(2);
} else {
console.log('You must provide either a config file or required CLI options (app ID, Master Key, and server URL); not both.');
process.exit(3);
}
} else {
console.log('There was a problem with your config. Exiting.');
process.exit(-1);
}
}
} else if (configFromCLI) {
config = configFromCLI;
} else {
//Failed to load default config file.
console.log('You must provide either a config file or an app ID, Master Key, and server URL. See parse-dashboard --help for details.');
process.exit(4);
}

config.data.apps.forEach(app => {
if (!app.appName) {
app.appName = app.appId;
}
});

if (config.data.iconsFolder && configFilePath) {
config.data.iconsFolder = path.join(configFilePath, config.data.iconsFolder);
}

const app = express();

if (allowInsecureHTTP || trustProxy || dev) app.enable('trust proxy');

config.data.trustProxy = trustProxy;
let dashboardOptions = { allowInsecureHTTP, cookieSessionSecret, dev };
app.use(mountPath, parseDashboard(config.data, dashboardOptions));
let server;
if(!configSSLKey || !configSSLCert){
// Start the server.
server = app.listen(port, host, function () {
console.log(`The dashboard is now available at http://${server.address().address}:${server.address().port}${mountPath}`);
});
} else {
// Start the server using SSL.
var privateKey = fs.readFileSync(configSSLKey);
var certificate = fs.readFileSync(configSSLCert);

server = require('https').createServer({
key: privateKey,
cert: certificate
}, app).listen(port, host, function () {
console.log(`The dashboard is now available at https://${server.address().address}:${server.address().port}${mountPath}`);
});
}
handleSIGs(server);
};
Loading