From 2893bfdab1778ade89198cc4f682cd86b82ddea9 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Fri, 1 Apr 2016 18:30:46 -0400 Subject: [PATCH 1/4] :zap: adds ability to run the dashboard from any mount point - fixes allowInsecureHTTP --- Parse-Dashboard/app.js | 25 +++++++++++++++++++++++-- Parse-Dashboard/index.js | 2 +- src/components/Icon/Icon.react.js | 2 +- src/dashboard/Dashboard.js | 3 +-- src/dashboard/index.js | 3 ++- 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Parse-Dashboard/app.js b/Parse-Dashboard/app.js index c92f4cd851..20b0ecd1d4 100644 --- a/Parse-Dashboard/app.js +++ b/Parse-Dashboard/app.js @@ -15,7 +15,7 @@ packageJson('parse-dashboard', 'latest').then(latestPackage => { } }); -module.exports = function(config) { +module.exports = function(config, allowInsecureHTTP) { var app = express(); // Serve public files. app.use(express.static(path.join(__dirname,'public'))); @@ -83,7 +83,28 @@ module.exports = function(config) { // For every other request, go to index.html. Let client-side handle the rest. app.get('/*', function(req, res) { - res.sendFile(__dirname + '/index.html'); + let url = req.url; + let originalUrl = req.originalUrl; + var mountPathLength = req.originalUrl.length - req.url.length; + var mountPath = req.originalUrl.slice(0, mountPathLength); + if (!mountPath.endsWith('/')) { + mountPath += '/'; + } + res.send(` + + + + + + Parse Dashboard + +
+ + + + `); }); return app; diff --git a/Parse-Dashboard/index.js b/Parse-Dashboard/index.js index 6b4808b456..cec29e7b0a 100644 --- a/Parse-Dashboard/index.js +++ b/Parse-Dashboard/index.js @@ -91,7 +91,7 @@ p.then(config => { const app = express(); - app.use(parseDashboard(config.data)); + app.use(parseDashboard(config.data, allowInsecureHTTP)); // Start the server. app.listen(port); diff --git a/src/components/Icon/Icon.react.js b/src/components/Icon/Icon.react.js index 6ab9be0100..e32e65eabb 100644 --- a/src/components/Icon/Icon.react.js +++ b/src/components/Icon/Icon.react.js @@ -18,7 +18,7 @@ let Icon = ({ name, fill, width, height }) => { } return ( - + ); }; diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index c79639cc66..ec7c5f8f77 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -108,7 +108,6 @@ const PARSE_DOT_COM_SERVER_INFO = { class Dashboard extends React.Component { constructor(props) { super(); - this.state = { configLoadingError: '', configLoadingState: AsyncStatus.PROGRESS, @@ -117,7 +116,7 @@ class Dashboard extends React.Component { } componentDidMount() { - get('/parse-dashboard-config.json').then(({ apps, newFeaturesInLatestVersion = [] }) => { + get(this.props.configURI).then(({ apps, newFeaturesInLatestVersion = [] }) => { this.setState({ newFeaturesInLatestVersion }); let appInfoPromises = apps.map(app => { if (app.serverURL.startsWith('https://api.parse.com/1')) { diff --git a/src/dashboard/index.js b/src/dashboard/index.js index 750645b8b9..d8d33f5a1b 100644 --- a/src/dashboard/index.js +++ b/src/dashboard/index.js @@ -17,4 +17,5 @@ import 'babel-polyfill'; require('stylesheets/fonts.scss'); installDevTools(Immutable); -ReactDOM.render(, document.getElementById('browser_mount')); +var configURI = window.PARSE_DASHBOARD_CONFIG_URI || '/parse-dashboard-config.json'; +ReactDOM.render(, document.getElementById('browser_mount')); From 4f922082143b3143104a6950651520285496492d Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Fri, 1 Apr 2016 20:59:08 -0400 Subject: [PATCH 2/4] PushPreview images part of the build system --- src/components/PushPreview/PushPreview.scss | 8 ++++---- .../components/PushPreview}/android.jpg | Bin .../components/PushPreview}/iphone.jpg | Bin .../components/PushPreview}/laptop.jpg | Bin .../components/PushPreview}/windowsphone.jpg | Bin webpack/base.config.js | 5 ++++- 6 files changed, 8 insertions(+), 5 deletions(-) rename {Parse-Dashboard/public/images => src/components/PushPreview}/android.jpg (100%) rename {Parse-Dashboard/public/images => src/components/PushPreview}/iphone.jpg (100%) rename {Parse-Dashboard/public/images => src/components/PushPreview}/laptop.jpg (100%) rename {Parse-Dashboard/public/images => src/components/PushPreview}/windowsphone.jpg (100%) diff --git a/src/components/PushPreview/PushPreview.scss b/src/components/PushPreview/PushPreview.scss index 7f6b2f5796..151504eb00 100644 --- a/src/components/PushPreview/PushPreview.scss +++ b/src/components/PushPreview/PushPreview.scss @@ -93,7 +93,7 @@ } .ios { - background-image: url(/images/iphone.jpg); + background-image: url(components/PushPreview/iphone.jpg); background-size: 325px auto; font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif; color: white; @@ -159,7 +159,7 @@ } .android { - background-image: url(/images/android.jpg); + background-image: url(components/PushPreview/android.jpg); background-size: 325px auto; font-family: 'Roboto', 'Helvetica Neue', 'Arial', sans-serif; @@ -229,7 +229,7 @@ } .osx { - background-image: url(/images/laptop.jpg); + background-image: url(components/PushPreview/laptop.jpg); background-size: 325px auto; font-family: '.SFNSDisplay-Regular', 'Helvetica Neue', 'Lucida Grande', sans-serif; color: #555252; @@ -272,7 +272,7 @@ } .windows { - background-image: url(/images/windowsphone.jpg); + background-image: url(components/PushPreview/windowsphone.jpg); background-size: 325px auto; font-family: 'Arial', sans-serif; color: white; diff --git a/Parse-Dashboard/public/images/android.jpg b/src/components/PushPreview/android.jpg similarity index 100% rename from Parse-Dashboard/public/images/android.jpg rename to src/components/PushPreview/android.jpg diff --git a/Parse-Dashboard/public/images/iphone.jpg b/src/components/PushPreview/iphone.jpg similarity index 100% rename from Parse-Dashboard/public/images/iphone.jpg rename to src/components/PushPreview/iphone.jpg diff --git a/Parse-Dashboard/public/images/laptop.jpg b/src/components/PushPreview/laptop.jpg similarity index 100% rename from Parse-Dashboard/public/images/laptop.jpg rename to src/components/PushPreview/laptop.jpg diff --git a/Parse-Dashboard/public/images/windowsphone.jpg b/src/components/PushPreview/windowsphone.jpg similarity index 100% rename from Parse-Dashboard/public/images/windowsphone.jpg rename to src/components/PushPreview/windowsphone.jpg diff --git a/webpack/base.config.js b/webpack/base.config.js index 549f6d2fdf..379dd6ee20 100644 --- a/webpack/base.config.js +++ b/webpack/base.config.js @@ -14,7 +14,7 @@ module.exports = { context: path.join(__dirname, '../src'), output: { filename: '[name].bundle.js', - publicPath: '/bundles/' + publicPath: 'bundles/' }, resolve: { root: [__dirname,path.join(__dirname, '../src'), path.join(__dirname, 'node_modules')] @@ -41,6 +41,9 @@ module.exports = { }, { test: /\.png$/, loader: 'file-loader?name=img/[hash].[ext]', + }, { + test: /\.jpg$/, + loader: 'file-loader?name=img/[hash].[ext]', } ] }, From 7a7185faadcbbbe7acde2248ddcb0b50759abea1 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Fri, 1 Apr 2016 21:36:22 -0400 Subject: [PATCH 3/4] :zap: passes path to Dashboard component for AJAX --- Parse-Dashboard/app.js | 21 +++++++++++++-------- Parse-Dashboard/index.html | 8 -------- src/dashboard/Dashboard.js | 4 +++- src/dashboard/index.js | 4 ++-- src/lib/AJAX.js | 14 ++++++++++++++ 5 files changed, 32 insertions(+), 19 deletions(-) delete mode 100644 Parse-Dashboard/index.html diff --git a/Parse-Dashboard/app.js b/Parse-Dashboard/app.js index 20b0ecd1d4..39d7d95bff 100644 --- a/Parse-Dashboard/app.js +++ b/Parse-Dashboard/app.js @@ -15,6 +15,17 @@ packageJson('parse-dashboard', 'latest').then(latestPackage => { } }); +function getMount(req) { + let url = req.url; + let originalUrl = req.originalUrl; + var mountPathLength = req.originalUrl.length - req.url.length; + var mountPath = req.originalUrl.slice(0, mountPathLength); + if (!mountPath.endsWith('/')) { + mountPath += '/'; + } + return mountPath; +} + module.exports = function(config, allowInsecureHTTP) { var app = express(); // Serve public files. @@ -83,18 +94,12 @@ module.exports = function(config, allowInsecureHTTP) { // For every other request, go to index.html. Let client-side handle the rest. app.get('/*', function(req, res) { - let url = req.url; - let originalUrl = req.originalUrl; - var mountPathLength = req.originalUrl.length - req.url.length; - var mountPath = req.originalUrl.slice(0, mountPathLength); - if (!mountPath.endsWith('/')) { - mountPath += '/'; - } + let mountPath = getMount(req); res.send(` diff --git a/Parse-Dashboard/index.html b/Parse-Dashboard/index.html deleted file mode 100644 index 52d3a0f2d4..0000000000 --- a/Parse-Dashboard/index.html +++ /dev/null @@ -1,8 +0,0 @@ - - - Parse Dashboard - -
- - - diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index ec7c5f8f77..a16d37c5ec 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -48,6 +48,7 @@ import Webhooks from './Data/Webhooks/Webhooks.react'; import { AsyncStatus } from 'lib/Constants'; import { center } from 'stylesheets/base.scss'; import { get } from 'lib/AJAX'; +import { setBasePath } from 'lib/AJAX'; import { Router, Route, @@ -113,10 +114,11 @@ class Dashboard extends React.Component { configLoadingState: AsyncStatus.PROGRESS, newFeaturesInLatestVersion: [], }; + setBasePath(props.path); } componentDidMount() { - get(this.props.configURI).then(({ apps, newFeaturesInLatestVersion = [] }) => { + get('/parse-dashboard-config.json').then(({ apps, newFeaturesInLatestVersion = [] }) => { this.setState({ newFeaturesInLatestVersion }); let appInfoPromises = apps.map(app => { if (app.serverURL.startsWith('https://api.parse.com/1')) { diff --git a/src/dashboard/index.js b/src/dashboard/index.js index d8d33f5a1b..825c84b6e5 100644 --- a/src/dashboard/index.js +++ b/src/dashboard/index.js @@ -17,5 +17,5 @@ import 'babel-polyfill'; require('stylesheets/fonts.scss'); installDevTools(Immutable); -var configURI = window.PARSE_DASHBOARD_CONFIG_URI || '/parse-dashboard-config.json'; -ReactDOM.render(, document.getElementById('browser_mount')); +var path = window.PARSE_DASHBOARD_PATH || '/'; +ReactDOM.render(, document.getElementById('browser_mount')); diff --git a/src/lib/AJAX.js b/src/lib/AJAX.js index f4e87bbbe1..a48dc6d9d9 100644 --- a/src/lib/AJAX.js +++ b/src/lib/AJAX.js @@ -9,8 +9,22 @@ import * as CSRFManager from 'lib/CSRFManager'; import encodeFormData from 'lib/encodeFormData'; import { Promise } from 'parse'; +let basePath = ''; +export function setBasePath(newBasePath) { + basePath = newBasePath || ''; + if (basePath.endsWith('/')) { + basePath = basePath.slice(0, basePath.length-1); + } +} + // abortable flag used to pass xhr reference so user can abort accordingly export function request(method, url, body, abortable = false, withCredentials = true, useRequestedWith = true) { + if (!url.startsWith('http://') + && !url.startsWith('https://') + && basePath.length + && !url.startsWith(basePath)) { + url = basePath + url; + } let xhr = new XMLHttpRequest(); xhr.open(method, url, true); if (method === 'POST' || method === 'PUT' || method === 'DELETE') { From eb09de5111ca410afa4670deae90c81dd9e5e311 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Fri, 1 Apr 2016 21:37:22 -0400 Subject: [PATCH 4/4] removes --progres on prepublish that break heroku builds --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 85307eeba3..cc50fb2cef 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "build": "NODE_ENV=production webpack --config webpack/production.config.js && webpack --config webpack/PIG.config.js", "test": "NODE_PATH=./node_modules jest", "generate": "node scripts/generate.js", - "prepublish": "webpack --config webpack/publish.config.js --progress", + "prepublish": "webpack --config webpack/publish.config.js", "start": "node ./Parse-Dashboard/index.js" }, "bin": {