forked from parse-community/parse-dashboard
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'heroku_master' into aws_master
* heroku_master: (91 commits) added latest configfile Updating ISSUE_TEMPLATE to match the latest versions (parse-community#525) Added support for node 4.3 and some documentation to Authentication.js (parse-community#513) Added add row button to data browser toolbar. (parse-community#512) Made the encrypted passwords an option (parse-community#510) Allow sorting by `createdAt` ascending (parse-community#508) Version 1.0.18 (parse-community#507) E2e test (parse-community#505) Version 1.0.17 (parse-community#502) Revert "using mount path when mounted as express module" (parse-community#501) Version 1.0.16 (parse-community#498) Added the ability to accept encrypted passwords (parse-community#487) using mount path when mounted as express module (parse-community#486) fix misspelling (parse-community#497) Add AttachSelectedRowsDialog (parse-community#465) Version 1.0.15 Add/relation viewer (parse-community#452) Changed Sidebar Footer links to open in a new tab (parse-community#460) Updated paths Procfile (parse-community#461) Add allowInsecureHTTP option with Express (parse-community#457) ... # Conflicts: # Parse-Dashboard/index.js # Parse-Dashboard/parse-dashboard-config.json
- Loading branch information
Showing
68 changed files
with
1,801 additions
and
491 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
language: node_js | ||
node_js: | ||
- "4.3" | ||
- "4.4" | ||
- "5.7" | ||
- "6.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
FROM node:4.3.2 | ||
ADD package.json /src/package.json | ||
RUN cd /src && npm install | ||
ADD . /src | ||
FROM node:4.4.2 | ||
WORKDIR /src | ||
ENTRYPOINT ["npm", "start", "--"] | ||
ADD . /src | ||
RUN cd /src \ | ||
&& npm install \ | ||
&& npm run build \ | ||
&& npm cache clear \ | ||
&& rm -rf ~/.npm \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
ENTRYPOINT ["npm", "run", "dashboard"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
"use strict"; | ||
|
||
/** | ||
* Constructor for Authentication class | ||
* | ||
* @class Authentication | ||
* @param {Object[]} validUsers | ||
* @param {boolean} useEncryptedPasswords | ||
*/ | ||
function Authentication(validUsers, useEncryptedPasswords) { | ||
this.validUsers = validUsers; | ||
this.useEncryptedPasswords = useEncryptedPasswords || false; | ||
} | ||
|
||
/** | ||
* Authenticates the `userToTest` | ||
* | ||
* @param {Object} userToTest | ||
* @returns {Object} Object with `isAuthenticated` and `appsUserHasAccessTo` properties | ||
*/ | ||
function authenticate(userToTest) { | ||
let bcrypt = require('bcryptjs'); | ||
|
||
var appsUserHasAccessTo = null; | ||
|
||
//they provided auth | ||
let isAuthenticated = userToTest && | ||
//there are configured users | ||
this.validUsers && | ||
//the provided auth matches one of the users | ||
this.validUsers.find(user => { | ||
let isAuthenticated = userToTest.name == user.user && | ||
(this.useEncryptedPasswords ? bcrypt.compareSync(userToTest.pass, user.pass) : userToTest.pass == user.pass); | ||
if (isAuthenticated) { | ||
// User restricted apps | ||
appsUserHasAccessTo = user.apps || null; | ||
} | ||
|
||
return isAuthenticated; | ||
}) ? true : false; | ||
|
||
return { | ||
isAuthenticated, | ||
appsUserHasAccessTo | ||
}; | ||
} | ||
|
||
Authentication.prototype.authenticate = authenticate; | ||
|
||
module.exports = Authentication; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
'use strict'; | ||
const express = require('express'); | ||
const basicAuth = require('basic-auth'); | ||
const path = require('path'); | ||
const packageJson = require('package-json'); | ||
var fs = require('fs'); | ||
|
||
const currentVersionFeatures = require('../package.json').parseDashboardFeatures; | ||
|
||
var newFeaturesInLatestVersion = []; | ||
packageJson('parse-dashboard', 'latest').then(latestPackage => { | ||
if (latestPackage.parseDashboardFeatures instanceof Array) { | ||
newFeaturesInLatestVersion = latestPackage.parseDashboardFeatures.filter(feature => { | ||
return currentVersionFeatures.indexOf(feature) === -1; | ||
}); | ||
} | ||
}); | ||
|
||
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; | ||
} | ||
|
||
function checkIfIconsExistForApps(apps, iconsFolder) { | ||
for (var i in apps) { | ||
var currentApp = apps[i]; | ||
var iconName = currentApp.iconName; | ||
var path = iconsFolder + "/" + iconName; | ||
|
||
fs.stat(path, function(err, stat) { | ||
if (err) { | ||
if ('ENOENT' == err.code) {// file does not exist | ||
console.warn("Icon with file name: " + iconName +" couldn't be found in icons folder!"); | ||
} else { | ||
console.log( | ||
'An error occurd while checking for icons, please check permission!'); | ||
} | ||
} else { | ||
//every thing was ok so for example you can read it and send it to client | ||
} | ||
} ); | ||
} | ||
} | ||
|
||
module.exports = function(config, allowInsecureHTTP) { | ||
var app = express(); | ||
// Serve public files. | ||
app.use(express.static(path.join(__dirname,'public'))); | ||
|
||
// Serve the configuration. | ||
app.get('/parse-dashboard-config.json', function(req, res) { | ||
let response = { | ||
apps: config.apps, | ||
newFeaturesInLatestVersion: newFeaturesInLatestVersion, | ||
}; | ||
|
||
const users = config.users; | ||
const useEncryptedPasswords = config.useEncryptedPasswords ? true : false; | ||
|
||
let auth = null; | ||
//If they provide auth when their config has no users, ignore the auth | ||
if (users) { | ||
auth = basicAuth(req); | ||
} | ||
|
||
//Based on advice from Doug Wilson here: | ||
//https://github.com/expressjs/express/issues/2518 | ||
const requestIsLocal = | ||
req.connection.remoteAddress === '127.0.0.1' || | ||
req.connection.remoteAddress === '::ffff:127.0.0.1' || | ||
req.connection.remoteAddress === '::1'; | ||
if (!requestIsLocal && !req.secure && !allowInsecureHTTP) { | ||
//Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext | ||
return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' }); | ||
} | ||
|
||
if (!requestIsLocal && !users) { | ||
//Accessing the dashboard over the internet can only be done with username and password | ||
return res.send({ success: false, error: 'Configure a user to access Parse Dashboard remotely' }); | ||
} | ||
|
||
let Authentication = require('./Authentication'); | ||
const authInstance = new Authentication(users, useEncryptedPasswords); | ||
const authentication = authInstance.authenticate(auth); | ||
|
||
const successfulAuth = authentication.isAuthenticated; | ||
const appsUserHasAccess = authentication.appsUserHasAccessTo; | ||
|
||
if (successfulAuth) { | ||
if (appsUserHasAccess) { | ||
// Restric access to apps defined in user dictionary | ||
// If they didn't supply any app id, user will access all apps | ||
response.apps = response.apps.filter(function (app) { | ||
return appsUserHasAccess.find(appUserHasAccess => { | ||
return app.appId == appUserHasAccess.appId | ||
}) | ||
}); | ||
} | ||
// They provided correct auth | ||
return res.json(response); | ||
} | ||
|
||
if (users || auth) { | ||
//They provided incorrect auth | ||
res.set('WWW-Authenticate', 'Basic realm=Authorization Required'); | ||
return res.sendStatus(401); | ||
} | ||
|
||
//They didn't provide auth, and have configured the dashboard to not need auth | ||
//(ie. didn't supply usernames and passwords) | ||
if (requestIsLocal) { | ||
//Allow no-auth access on localhost only, if they have configured the dashboard to not need auth | ||
return res.json(response); | ||
} | ||
//We shouldn't get here. Fail closed. | ||
res.send({ success: false, error: 'Something went wrong.' }); | ||
}); | ||
|
||
// Serve the app icons. Uses the optional `iconsFolder` parameter as | ||
// directory name, that was setup in the config file. | ||
// We are explicitly not using `__dirpath` here because one may be | ||
// running parse-dashboard from globally installed npm. | ||
if (config.iconsFolder) { | ||
try { | ||
var stat = fs.statSync(config.iconsFolder); | ||
if (stat.isDirectory()) { | ||
app.use('/appicons', express.static(config.iconsFolder)); | ||
//Check also if the icons really exist | ||
checkIfIconsExistForApps(config.apps, config.iconsFolder); | ||
} | ||
} catch (e) { | ||
// Directory doesn't exist or something. | ||
console.warn("Iconsfolder at path: " + config.iconsFolder + | ||
" not found!"); | ||
} | ||
} | ||
|
||
// For every other request, go to index.html. Let client-side handle the rest. | ||
app.get('/*', function(req, res) { | ||
let mountPath = getMount(req); | ||
res.send(`<!DOCTYPE html> | ||
<head> | ||
<link rel="shortcut icon" type="image/x-icon" href="${mountPath}favicon.ico" /> | ||
<base href="${mountPath}"/> | ||
<script> | ||
PARSE_DASHBOARD_PATH = "${mountPath}"; | ||
</script> | ||
</head> | ||
<html> | ||
<title>Parse Dashboard</title> | ||
<body> | ||
<div id="browser_mount"></div> | ||
<script src="${mountPath}bundles/dashboard.bundle.js"></script> | ||
</body> | ||
</html> | ||
`); | ||
}); | ||
|
||
return app; | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.