Skip to content

Commit 88d9631

Browse files
committed
Merge remote-tracking branch 'upstream/back4app1.1.2' into homolog
2 parents 1413a84 + a1e37c8 commit 88d9631

File tree

154 files changed

+1661
-799
lines changed

Some content is hidden

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

154 files changed

+1661
-799
lines changed

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.eslintrc.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"env": {
3+
"es6": true,
4+
"node": true,
5+
"browser": true
6+
},
7+
"parser": "babel-eslint",
8+
"extends": "eslint:recommended",
9+
"installedESLint": true,
10+
"parserOptions": {
11+
"ecmaFeatures": {
12+
"experimentalObjectRestSpread": true,
13+
"jsx": true
14+
},
15+
"sourceType": "module"
16+
},
17+
"plugins": [
18+
"react"
19+
],
20+
"rules": {
21+
"react/jsx-uses-vars": 1,
22+
"react/jsx-uses-react": 1,
23+
"react/react-in-jsx-scope": 1,
24+
"no-console": 0,
25+
"no-case-declarations": 0
26+
}
27+
}

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ PIG/bundles/
55
Parse-Dashboard/public/bundles/
66
Parse-Dashboard/parse-dashboard-config.json
77
npm-debug.log
8+
.eslintcache
89

910
// vim .swp
1011
*.swp
1112
.env
12-
1313
.idea/
1414

1515
npm-debug.log.*

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ node_js:
33
- '4.4'
44
- '5.7'
55
- '6.1'
6+
cache:
7+
directories:
8+
- node_modules
69
deploy:
710
provider: npm
811
on:
912
tags: true
1013
all_branches: true
1114
condition: "$TRAVIS_JOB_NUMBER = $TRAVIS_BUILD_NUMBER.1"
12-
repo: ParsePlatform/parse-dashboard
15+
repo: parse-community/parse-dashboard
1316
email:
1417
secure: NVlNLZh4bsCUaO1qYdXp6DpYnISQIXqz0xIaMfPI06CqFErkqlodWD7aOOYT2LyKos1f9QbQBbURl27drtJLudNqIXfMFbWMc0MwDJp4fJBa6vRFdn1jYNDcrqTbdAAoH5z6SU4r7YdiPz5pIJ7XjMajryaB7dAZLNiuZaTeTboF6QEQj+j+bw9IMcuiDIxQt3t+5f9Raah1HwZX5h5CBXS8voE97deCpf6jdVt3gaKvnZGvTvnDfYBsvmDE2ueqFK/xjt240PMArxqTbkEVFl/7Gti5jurLIKtX7StNsEZZZiGJS2+E9Px5nSFMM3JKnfD5Cj6IZxqobL9mQ4KueaL3tX5BOnbHfSpJs2t3Lp8TO0hnpmn8w/d7pekOjH3LihgC7AbZ3/ark9ZvPvP63XKhivKL4NuvNa+8yHeQNOLIzOjTPZl7ZS6XkibwxsOtgasMQWK4/Ttg6/jHHPjaXbnqn7ZoIM2GPZBv22xaReIWSRJdgW8G9ceSBEIIZFONkKsH0apDDq3eHg0vNEI4R3oEmV6t/R9yvpCzarfNLn5+l80ztMM+rX91eXT8B5V8Mpy+7urbQwIoFLUGRPDxbofEqEm8S6sLsjyYe7VnxBC4Lhir3DFxYL0+q5YLfhq64AejA4BM65+v5SyvXCUvyakzsRsydU230sJyaONHD5I=
1518
api_key:

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,44 @@
44

55
* _Contributing to this repo? Add info about your change here to be included in next release_
66

7+
### 1.1.2
8+
9+
* Fix: An issue introduced when using readOnlyMasterKey would make all users readOnly after one has logged in.
10+
* Reverts: Dependency updates that would render the build unstable / broken.
11+
12+
### 1.1.1
13+
14+
* Fix: Updating array of Dates now keeps it's type (was changing to array of ISO strings, issue #590), thanks to [David Riha](https://github.com/rihadavid)
15+
* Fix: NaN displayed when filter input is empty or negative number (#749), thanks to [Miguel Serrrano](https://github.com/miguel-s)
16+
* Fix: Addresses issue related to displaying iOS alert object containing title and body keys (#539), thanks to [Robert Martin del Campo](https://github.com/repertus)
17+
* Feature: Adds support for localized push notifications if server version is high enough, thanks to [Florent Vilmart](https://github.com/flovilmart)
18+
* Feature: Adds support for readOnly masterKey, thanks to [Florent Vilmart](https://github.com/flovilmart)
19+
* Feature: Adds support for polygon types, thansk to [Mads Bjerre](https://github.com/madsb)
20+
* Feature: Adds support for push time, expiration time, and expiration interval, thanks to [Marvel Mathew](https://github.com/marvelm)
21+
22+
### 1.1.0
23+
24+
* Feature: UI for managing push audiences (#712), thanks to [Davi Macedo](https://github.com/davimacedo)
25+
* Feature: When editing Object or Array fields the data is displayed in a prettier format and the textarea is resizable (#734), thanks to [Samuli Siivinen](https://github.com/ssamuli)
26+
* Fix: Display bug on safari when table has empty cells ('') (#731), thanks to [Samuli Siivinen](https://github.com/ssamuli)
27+
* Fix: Added message that notifies Background Jobs requiring additional setup (#740 & #741), thanks to [Samuli Siivinen](https://github.com/ssamuli) and [Natan Rolnik](https://github.com/natanrolnik)
28+
29+
### 1.0.28
30+
* Feature: Add ability to search Object columns (#727), thanks to [Samuli Siivinen](https://github.com/ssamuli)
31+
* Improvement: Added/fixed a filtering option "contains string" for String fields. Case insensitive for now (#728), thanks to [Samuli Siivinen](https://github.com/ssamuli)
32+
* Improvement: Sort config data according to parameter names (#726), thanks to [Natan Rolnik](https://github.com/natanrolnik)
33+
34+
### 1.0.27
35+
* Improvement: Show notifications upon success or failure of save and delete objects (#718), thanks to [Natan Rolnik](https://github.com/natanrolnik)
36+
* Improvement: Moves download option into file editor (#716), thanks to [Natan Rolnik](https://github.com/natanrolnik)
37+
38+
### 1.0.26
39+
* Improvement: Fixes broken links, thanks to [Arthur Cinader](https://github.com/acinader)
40+
* Improvement: Title on the add row button, thanks to [Abdul Basit](https://github.com/basitsattar)
41+
* Improvement: Use slim docker image, thanks to [Tyler Brock](https://github.com/tbrock)
42+
* Fix: table scrolling on google chrome (#671), thanks to [Jacer Omri](https://github.com/JacerOmri)
43+
* Various: adds eslint, thanks to [Jeremy Louie](https://github.com/JeremyPlease)
44+
745
### 1.0.25
846

947
* Improvement: Update and add links to sidebar footer (#661), thanks to [Natan Rolnik](https://github.com/natanrolnik)

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
FROM node:4.4.2
1+
FROM node:argon-slim
2+
ENV NPM_CONFIG_LOGLEVEL error
23
WORKDIR /src
34
ADD . /src
45
RUN cd /src \

LICENSE

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2424
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2525
IN ANY WAY OUT OF THE USE OF THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
2626
OF SUCH DAMAGE.
27+
28+
-----
29+
30+
As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code.

Parse-Dashboard/Authentication.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ function Authentication(validUsers, useEncryptedPasswords, mountPath) {
1717
this.mountPath = mountPath;
1818
}
1919

20-
function initialize(app) {
20+
function initialize(app, options) {
21+
options = options || {};
2122
var self = this;
2223
passport.use('local', new LocalStrategy(
2324
function(username, password, cb) {
@@ -43,11 +44,12 @@ function initialize(app) {
4344
cb(null, user);
4445
});
4546

47+
var cookieSessionSecret = options.cookieSessionSecret || require('crypto').randomBytes(64).toString('hex');
4648
app.use(require('connect-flash')());
4749
app.use(require('body-parser').urlencoded({ extended: true }));
4850
app.use(require('cookie-session')({
4951
key : 'parse_dash',
50-
secret : 'magic',
52+
secret : cookieSessionSecret,
5153
cookie : {
5254
maxAge: (2 * 7 * 24 * 60 * 60 * 1000) // 2 weeks
5355
}
@@ -77,8 +79,9 @@ function initialize(app) {
7779
* @returns {Object} Object with `isAuthenticated` and `appsUserHasAccessTo` properties
7880
*/
7981
function authenticate(userToTest, usernameOnly) {
80-
var appsUserHasAccessTo = null;
81-
var matchingUsername = null;
82+
let appsUserHasAccessTo = null;
83+
let matchingUsername = null;
84+
let isReadOnly = false;
8285

8386
//they provided auth
8487
let isAuthenticated = userToTest &&
@@ -94,6 +97,7 @@ function authenticate(userToTest, usernameOnly) {
9497
matchingUsername = user.user;
9598
// User restricted apps
9699
appsUserHasAccessTo = user.apps || null;
100+
isReadOnly = !!user.readOnly; // make it true/false
97101
}
98102

99103
return isAuthenticated;
@@ -102,7 +106,8 @@ function authenticate(userToTest, usernameOnly) {
102106
return {
103107
isAuthenticated,
104108
matchingUsername,
105-
appsUserHasAccessTo
109+
appsUserHasAccessTo,
110+
isReadOnly,
106111
};
107112
}
108113

Parse-Dashboard/app.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function checkIfIconsExistForApps(apps, iconsFolder) {
3131
var iconName = currentApp.iconName;
3232
var path = iconsFolder + "/" + iconName;
3333

34-
fs.stat(path, function(err, stat) {
34+
fs.stat(path, function(err) {
3535
if (err) {
3636
if ('ENOENT' == err.code) {// file does not exist
3737
console.warn("Icon with file name: " + iconName +" couldn't be found in icons folder!");
@@ -46,7 +46,8 @@ function checkIfIconsExistForApps(apps, iconsFolder) {
4646
}
4747
}
4848

49-
module.exports = function(config, allowInsecureHTTP) {
49+
module.exports = function(config, options) {
50+
options = options || {};
5051
var app = express();
5152
// Serve public files.
5253
app.use(express.static(path.join(__dirname,'public')));
@@ -62,7 +63,7 @@ module.exports = function(config, allowInsecureHTTP) {
6263
const users = config.users;
6364
const useEncryptedPasswords = config.useEncryptedPasswords ? true : false;
6465
const authInstance = new Authentication(users, useEncryptedPasswords, mountPath);
65-
authInstance.initialize(app);
66+
authInstance.initialize(app, { cookieSessionSecret: options.cookieSessionSecret });
6667

6768
// CSRF error handler
6869
app.use(function (err, req, res, next) {
@@ -75,8 +76,9 @@ module.exports = function(config, allowInsecureHTTP) {
7576

7677
// Serve the configuration.
7778
app.get('/parse-dashboard-config.json', function(req, res) {
79+
let apps = config.apps.map((app) => Object.assign({}, app)); // make a copy
7880
let response = {
79-
apps: config.apps,
81+
apps: apps,
8082
newFeaturesInLatestVersion: newFeaturesInLatestVersion,
8183
};
8284

@@ -86,7 +88,7 @@ module.exports = function(config, allowInsecureHTTP) {
8688
req.connection.remoteAddress === '127.0.0.1' ||
8789
req.connection.remoteAddress === '::ffff:127.0.0.1' ||
8890
req.connection.remoteAddress === '::1';
89-
if (!requestIsLocal && !req.secure && !allowInsecureHTTP) {
91+
if (!requestIsLocal && !req.secure && !options.allowInsecureHTTP) {
9092
//Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext
9193
return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' });
9294
}
@@ -100,14 +102,29 @@ module.exports = function(config, allowInsecureHTTP) {
100102

101103
const successfulAuth = authentication && authentication.isAuthenticated;
102104
const appsUserHasAccess = authentication && authentication.appsUserHasAccessTo;
105+
const isReadOnly = authentication && authentication.isReadOnly;
106+
// User is full read-only, replace the masterKey by the read-only one
107+
if (isReadOnly) {
108+
response.apps = response.apps.map((app) => {
109+
app.masterKey = app.readOnlyMasterKey;
110+
if (!app.masterKey) {
111+
throw new Error('You need to provide a readOnlyMasterKey to use read-only features.');
112+
}
113+
return app;
114+
});
115+
}
103116

104117
if (successfulAuth) {
105118
if (appsUserHasAccess) {
106119
// Restric access to apps defined in user dictionary
107120
// If they didn't supply any app id, user will access all apps
108121
response.apps = response.apps.filter(function (app) {
109122
return appsUserHasAccess.find(appUserHasAccess => {
110-
return app.appId == appUserHasAccess.appId
123+
const isSame = app.appId === appUserHasAccess.appId;
124+
if (isSame && appUserHasAccess.readOnly) {
125+
app.masterKey = app.readOnlyMasterKey;
126+
}
127+
return isSame;
111128
})
112129
});
113130
}

Parse-Dashboard/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ program.option('--allowInsecureHTTP [allowInsecureHTTP]', 'set this flag when yo
2525
program.option('--sslKey [sslKey]', 'the path to the SSL private key.');
2626
program.option('--sslCert [sslCert]', 'the path to the SSL certificate.');
2727
program.option('--trustProxy [trustProxy]', 'set this flag when you are behind a front-facing proxy, such as when hosting on Heroku. Uses X-Forwarded-* headers to determine the client\'s connection and IP address.');
28+
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');
2829

2930
program.parse(process.argv);
3031

3132
const host = program.host || process.env.HOST || '0.0.0.0';
3233
const port = program.port || process.env.PORT || 4040;
3334
const mountPath = program.mountPath || process.env.MOUNT_PATH || '/';
3435
const allowInsecureHTTP = program.allowInsecureHTTP || process.env.PARSE_DASHBOARD_ALLOW_INSECURE_HTTP;
36+
const cookieSessionSecret = program.cookieSessionSecret || process.env.PARSE_DASHBOARD_COOKIE_SESSION_SECRET;
3537
const trustProxy = program.trustProxy || process.env.PARSE_DASHBOARD_TRUST_PROXY;
3638

3739
if (trustProxy && allowInsecureHTTP) {
@@ -115,7 +117,8 @@ p.then(config => {
115117
if (allowInsecureHTTP || trustProxy) app.enable('trust proxy');
116118

117119
config.data.trustProxy = trustProxy;
118-
app.use(mountPath, parseDashboard(config.data, allowInsecureHTTP));
120+
let dashboardOptions = { allowInsecureHTTP: allowInsecureHTTP, cookieSessionSecret: cookieSessionSecret };
121+
app.use(mountPath, parseDashboard(config.data, dashboardOptions));
119122
if(!configSSLKey || !configSSLCert){
120123
// Start the server.
121124
const server = app.listen(port, host, function () {

0 commit comments

Comments
 (0)