parse-dashboard 9.0.1-alpha.7 → 9.1.0-alpha.10

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.
@@ -87,6 +87,32 @@ module.exports = function(config, options) {
87
87
  cookieSessionStore: options.cookieSessionStore
88
88
  });
89
89
 
90
+ /**
91
+ * Checks whether a request is from localhost.
92
+ */
93
+ function isLocalRequest(req) {
94
+ return req.connection.remoteAddress === '127.0.0.1' ||
95
+ req.connection.remoteAddress === '::ffff:127.0.0.1' ||
96
+ req.connection.remoteAddress === '::1';
97
+ }
98
+
99
+ /**
100
+ * Middleware that enforces remote access restrictions:
101
+ * - Requires HTTPS for remote requests (unless allowInsecureHTTP is set)
102
+ * - Requires users to be configured for remote access (unless dev mode is enabled)
103
+ */
104
+ function enforceRemoteAccessRestrictions(req, res, next) {
105
+ if (!options.dev && !isLocalRequest(req)) {
106
+ if (!req.secure && !options.allowInsecureHTTP) {
107
+ return res.status(403).json({ error: 'Parse Dashboard can only be remotely accessed via HTTPS' });
108
+ }
109
+ if (!users) {
110
+ return res.status(401).json({ error: 'Configure a user to access Parse Dashboard remotely' });
111
+ }
112
+ }
113
+ next();
114
+ }
115
+
90
116
  // CSRF error handler
91
117
  app.use(function (err, req, res, next) {
92
118
  if (err.code !== 'EBADCSRFTOKEN') {return next(err)}
@@ -109,13 +135,7 @@ module.exports = function(config, options) {
109
135
  agent: config.agent,
110
136
  };
111
137
 
112
- //Based on advice from Doug Wilson here:
113
- //https://github.com/expressjs/express/issues/2518
114
- const requestIsLocal =
115
- req.connection.remoteAddress === '127.0.0.1' ||
116
- req.connection.remoteAddress === '::ffff:127.0.0.1' ||
117
- req.connection.remoteAddress === '::1';
118
- if (!options.dev && !requestIsLocal) {
138
+ if (!options.dev && !isLocalRequest(req)) {
119
139
  if (!req.secure && !options.allowInsecureHTTP) {
120
140
  //Disallow HTTP requests except on localhost, to prevent the master key from being transmitted in cleartext
121
141
  return res.send({ success: false, error: 'Parse Dashboard can only be remotely accessed via HTTPS' });
@@ -179,7 +199,7 @@ module.exports = function(config, options) {
179
199
 
180
200
  //They didn't provide auth, and have configured the dashboard to not need auth
181
201
  //(ie. didn't supply usernames and passwords)
182
- if (requestIsLocal || options.dev) {
202
+ if (isLocalRequest(req) || options.dev) {
183
203
  //Allow no-auth access on localhost only, if they have configured the dashboard to not need auth
184
204
  await Promise.all(
185
205
  response.apps.map(async (app) => {
@@ -329,8 +349,9 @@ module.exports = function(config, options) {
329
349
  }
330
350
  }
331
351
 
332
- // Agent API endpoint — middleware chain: auth check (401) → CSRF validation (403) → handler
352
+ // Agent API endpoint — middleware chain: remote access guard → auth check (401) → CSRF validation (403) → handler
333
353
  app.post('/apps/:appId/agent',
354
+ enforceRemoteAccessRestrictions,
334
355
  (req, res, next) => {
335
356
  if (users && (!req.user || !req.user.isAuthenticated)) {
336
357
  return res.status(401).json({ error: 'Unauthorized' });