parse-dashboard 6.0.0-beta.2 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,7 @@ const packageJson = require('package-json');
5
5
  const csrf = require('csurf');
6
6
  const Authentication = require('./Authentication.js');
7
7
  const fs = require('fs');
8
+ const ConfigKeyCache = require('./configKeyCache.js');
8
9
 
9
10
  const currentVersionFeatures = require('../package.json').parseDashboardFeatures;
10
11
 
@@ -80,11 +81,11 @@ module.exports = function(config, options) {
80
81
  });
81
82
 
82
83
  // Serve the configuration.
83
- app.get('/parse-dashboard-config.json', function(req, res) {
84
+ app.get('/parse-dashboard-config.json', async (req, res) => {
84
85
  const apps = config.apps.map((app) => Object.assign({}, app)); // make a copy
85
86
  const response = {
86
- apps: apps,
87
- newFeaturesInLatestVersion: newFeaturesInLatestVersion,
87
+ apps,
88
+ newFeaturesInLatestVersion,
88
89
  };
89
90
 
90
91
  //Based on advice from Doug Wilson here:
@@ -119,20 +120,31 @@ module.exports = function(config, options) {
119
120
  return app;
120
121
  });
121
122
  }
122
-
123
123
  if (successfulAuth) {
124
124
  if (appsUserHasAccess) {
125
- // Restric access to apps defined in user dictionary
126
- // If they didn't supply any app id, user will access all apps
127
- response.apps = response.apps.filter(function (app) {
128
- return appsUserHasAccess.find(appUserHasAccess => {
129
- const isSame = app.appId === appUserHasAccess.appId;
130
- if (isSame && appUserHasAccess.readOnly) {
125
+ const processedApps = await Promise.all(
126
+ response.apps.map(async (app) => {
127
+ const matchingAccess = appsUserHasAccess.find(
128
+ (access) => access.appId === app.appId
129
+ );
130
+
131
+ if (!matchingAccess) {
132
+ return null;
133
+ }
134
+
135
+ if (matchingAccess.readOnly) {
131
136
  app.masterKey = app.readOnlyMasterKey;
132
137
  }
133
- return isSame;
138
+
139
+ if (typeof app.masterKey === 'function') {
140
+ app.masterKey = await ConfigKeyCache.get(app.appId, 'masterKey', app.masterKeyTtl, app.masterKey);
141
+ }
142
+
143
+ return app;
134
144
  })
135
- });
145
+ );
146
+
147
+ response.apps = processedApps.filter((app) => app !== null);
136
148
  }
137
149
  // They provided correct auth
138
150
  return res.json(response);
@@ -147,6 +159,14 @@ module.exports = function(config, options) {
147
159
  //(ie. didn't supply usernames and passwords)
148
160
  if (requestIsLocal || options.dev) {
149
161
  //Allow no-auth access on localhost only, if they have configured the dashboard to not need auth
162
+ await Promise.all(
163
+ response.apps.map(async (app) => {
164
+ if (typeof app.masterKey === 'function') {
165
+ app.masterKey = await ConfigKeyCache.get(app.appId, 'masterKey', app.masterKeyTtl, app.masterKey);
166
+ }
167
+ })
168
+ );
169
+
150
170
  return res.json(response);
151
171
  }
152
172
  //We shouldn't get here. Fail closed.
@@ -0,0 +1,22 @@
1
+ class KeyCache {
2
+ constructor() {
3
+ this.cache = {};
4
+ }
5
+
6
+ async get(appId, key, ttl, callback) {
7
+ key = `${appId}:${key}`;
8
+ const cached = this.cache[key];
9
+ if (cached && cached.expiry > Date.now()) {
10
+ return cached.value;
11
+ }
12
+
13
+ const value = await Promise.resolve(callback());
14
+ this.cache[key] = {
15
+ value,
16
+ expiry: Date.now() + ttl,
17
+ };
18
+ return value;
19
+ }
20
+ }
21
+
22
+ module.exports = new KeyCache();
@@ -13,6 +13,7 @@ const startServer = require('./server');
13
13
  const program = require('commander');
14
14
  program.option('--appId [appId]', 'the app Id of the app you would like to manage.');
15
15
  program.option('--masterKey [masterKey]', 'the master key of the app you would like to manage.');
16
+ program.option('--masterKeyTtl [masterKeyTtl]', 'the master key ttl of the app you would like to manage.');
16
17
  program.option('--serverURL [serverURL]', 'the server url of the app you would like to manage.');
17
18
  program.option('--graphQLServerURL [graphQLServerURL]', 'the GraphQL server url of the app you would like to manage.');
18
19
  program.option('--dev', 'Enable development mode. This will disable authentication and allow non HTTPS connections. DO NOT ENABLE IN PRODUCTION SERVERS');