Skip to content

Commit 77e2535

Browse files
committed
feat: upgrading from express 4 to 5
1 parent a579eeb commit 77e2535

26 files changed

+970
-278
lines changed

package-lock.json

+913-216
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@
2727
"@parse/fs-files-adapter": "3.0.0",
2828
"@parse/push-adapter": "6.8.0",
2929
"bcryptjs": "2.4.3",
30-
"body-parser": "1.20.3",
3130
"commander": "12.1.0",
3231
"cors": "2.8.5",
3332
"deepcopy": "2.1.0",
34-
"express": "4.21.2",
33+
"express": "5.0.1",
3534
"express-rate-limit": "7.4.1",
3635
"follow-redirects": "1.15.9",
3736
"graphql": "16.9.0",
@@ -57,6 +56,7 @@
5756
"punycode": "2.3.1",
5857
"rate-limit-redis": "4.2.0",
5958
"redis": "4.7.0",
59+
"router": "2.0.0",
6060
"semver": "7.6.3",
6161
"subscriptions-transport-ws": "0.11.0",
6262
"tv4": "1.3.0",
@@ -128,11 +128,11 @@
128128
"test:mongodb:7.0.1": "npm run test:mongodb --dbversion=7.0.1",
129129
"test:mongodb:8.0.3": "npm run test:mongodb --dbversion=8.0.3",
130130
"test:postgres:testonly": "cross-env PARSE_SERVER_TEST_DB=postgres PARSE_SERVER_TEST_DATABASE_URI=postgres://postgres:password@localhost:5432/parse_server_postgres_adapter_test_database npm run testonly",
131-
"pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} mongodb-runner start -t ${MONGODB_TOPOLOGY} --version ${MONGODB_VERSION} -- --port 27017",
132-
"testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} TESTING=1 jasmine",
131+
"pretest": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=6.0.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} mongodb-runner start -t ${MONGODB_TOPOLOGY} --version ${MONGODB_VERSION} -- --port 27017",
132+
"testonly": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=6.0.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} TESTING=1 jasmine",
133133
"test": "npm run testonly",
134-
"posttest": "cross-env mongodb-runner stop --all",
135-
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=5.3.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} TESTING=1 nyc jasmine",
134+
"posttest": "cross-env mongodb-runner stop --all --debug",
135+
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=6.0.2} MONGODB_TOPOLOGY=${MONGODB_TOPOLOGY:=standalone} TESTING=1 nyc jasmine",
136136
"start": "node ./bin/parse-server",
137137
"prettier": "prettier --write {src,spec}/{**/*,*}.js",
138138
"prepare": "npm run build",

spec/HTTPRequest.spec.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22

33
const httpRequest = require('../lib/request'),
44
HTTPResponse = require('../lib/request').HTTPResponse,
5-
bodyParser = require('body-parser'),
65
express = require('express');
76

87
const port = 13371;
98
const httpRequestServer = `http://localhost:${port}`;
109

1110
function startServer(done) {
1211
const app = express();
13-
app.use(bodyParser.json({ type: '*/*' }));
12+
app.use(express.json({ type: '*/*' }));
1413
app.get('/hello', function (req, res) {
1514
res.json({ response: 'OK' });
1615
});

spec/ParseHooks.spec.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const request = require('../lib/request');
44
const triggers = require('../lib/triggers');
55
const HooksController = require('../lib/Controllers/HooksController').default;
66
const express = require('express');
7-
const bodyParser = require('body-parser');
87
const auth = require('../lib/Auth');
98
const Config = require('../lib/Config');
109

@@ -17,7 +16,7 @@ describe('Hooks', () => {
1716
beforeEach(done => {
1817
if (!app) {
1918
app = express();
20-
app.use(bodyParser.json({ type: '*/*' }));
19+
app.use(express.json({ type: '*/*' }));
2120
server = app.listen(port, undefined, done);
2221
} else {
2322
done();

spec/vulnerabilities.spec.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,10 @@ describe('Vulnerabilities', () => {
250250

251251
it_id('e8b5f1e1-8326-4c70-b5f4-1e8678dfff8d')(it)('denies creating a hook with polluted data', async () => {
252252
const express = require('express');
253-
const bodyParser = require('body-parser');
254253
const port = 34567;
255254
const hookServerURL = 'http://localhost:' + port;
256255
const app = express();
257-
app.use(bodyParser.json({ type: '*/*' }));
256+
app.use(express.json({ type: '*/*' }));
258257
const server = await new Promise(resolve => {
259258
const res = app.listen(port, undefined, () => resolve(res));
260259
});

src/Controllers/AnalyticsController.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export class AnalyticsController extends AdaptableController {
55
appOpened(req) {
66
return Promise.resolve()
77
.then(() => {
8-
return this.adapter.appOpened(req.body, req);
8+
return this.adapter.appOpened(req.body || {}, req);
99
})
1010
.then(response => {
1111
return { response: response || {} };
@@ -18,7 +18,7 @@ export class AnalyticsController extends AdaptableController {
1818
trackEvent(req) {
1919
return Promise.resolve()
2020
.then(() => {
21-
return this.adapter.trackEvent(req.params.eventName, req.body, req);
21+
return this.adapter.trackEvent(req.params.eventName, req.body || {}, req);
2222
})
2323
.then(response => {
2424
return { response: response || {} };

src/ParseServer.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// ParseServer - open-source compatible API Server for Parse apps
22

33
var batch = require('./batch'),
4-
bodyParser = require('body-parser'),
54
express = require('express'),
65
middlewares = require('./middlewares'),
76
Parse = require('parse/node').Parse,
@@ -272,13 +271,13 @@ class ParseServer {
272271

273272
api.use(
274273
'/',
275-
bodyParser.urlencoded({ extended: false }),
274+
express.urlencoded({ extended: false }),
276275
pages.enableRouter
277276
? new PagesRouter(pages).expressRouter()
278277
: new PublicAPIRouter().expressRouter()
279278
);
280279

281-
api.use(bodyParser.json({ type: '*/*', limit: maxUploadSize }));
280+
api.use(express.json({ type: '*/*', limit: maxUploadSize }));
282281
api.use(middlewares.allowMethodOverride);
283282
api.use(middlewares.handleParseHeaders);
284283
const routes = Array.isArray(rateLimit) ? rateLimit : [rateLimit];

src/PromiseRouter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Parse from 'parse/node';
99
import express from 'express';
1010
import log from './logger';
1111
import { inspect } from 'util';
12-
const Layer = require('express/lib/router/layer');
12+
const Layer = require('router/lib/layer');
1313

1414
function validateParameter(key, value) {
1515
if (key == 'className') {

src/Routers/AggregateRouter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import UsersRouter from './UsersRouter';
66

77
export class AggregateRouter extends ClassesRouter {
88
handleFind(req) {
9-
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
9+
const body = Object.assign(req.body || {}, ClassesRouter.JSONFromQuery(req.query));
1010
const options = {};
1111
if (body.distinct) {
1212
options.distinct = String(body.distinct);

src/Routers/AudiencesRouter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class AudiencesRouter extends ClassesRouter {
88
}
99

1010
handleFind(req) {
11-
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
11+
const body = Object.assign(req.body || {}, ClassesRouter.JSONFromQuery(req.query));
1212
const options = ClassesRouter.optionsFromBody(body, req.config.defaultLimit);
1313

1414
return rest

src/Routers/ClassesRouter.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class ClassesRouter extends PromiseRouter {
1919
}
2020

2121
handleFind(req) {
22-
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
22+
const body = Object.assign(req.body || {}, ClassesRouter.JSONFromQuery(req.query));
2323
const options = ClassesRouter.optionsFromBody(body, req.config.defaultLimit);
2424
if (req.config.maxLimit && body.limit > req.config.maxLimit) {
2525
// Silently replace the limit on the query with the max configured
@@ -48,7 +48,7 @@ export class ClassesRouter extends PromiseRouter {
4848

4949
// Returns a promise for a {response} object.
5050
handleGet(req) {
51-
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
51+
const body = Object.assign(req.body || {}, ClassesRouter.JSONFromQuery(req.query));
5252
const options = {};
5353

5454
for (const key of Object.keys(body)) {
@@ -117,7 +117,7 @@ export class ClassesRouter extends PromiseRouter {
117117
req.config,
118118
req.auth,
119119
this.className(req),
120-
req.body,
120+
req.body || {},
121121
req.info.clientSDK,
122122
req.info.context
123123
);
@@ -130,7 +130,7 @@ export class ClassesRouter extends PromiseRouter {
130130
req.auth,
131131
this.className(req),
132132
where,
133-
req.body,
133+
req.body || {},
134134
req.info.clientSDK,
135135
req.info.context
136136
);

src/Routers/CloudCodeRouter.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export class CloudCodeRouter extends PromiseRouter {
7777
}
7878

7979
static createJob(req) {
80-
const { job_schedule } = req.body;
80+
const { job_schedule } = req.body || {};
8181
validateJobSchedule(req.config, job_schedule);
8282
return rest.create(
8383
req.config,
@@ -91,7 +91,7 @@ export class CloudCodeRouter extends PromiseRouter {
9191

9292
static editJob(req) {
9393
const { objectId } = req.params;
94-
const { job_schedule } = req.body;
94+
const { job_schedule } = req.body || {};
9595
validateJobSchedule(req.config, job_schedule);
9696
return rest
9797
.update(

src/Routers/FilesRouter.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import express from 'express';
2-
import BodyParser from 'body-parser';
32
import * as Middlewares from '../middlewares';
43
import Parse from 'parse/node';
54
import Config from '../Config';
@@ -45,7 +44,7 @@ export class FilesRouter {
4544

4645
router.post(
4746
'/files/:filename',
48-
BodyParser.raw({
47+
express.raw({
4948
type: () => {
5049
return true;
5150
},

src/Routers/FunctionsRouter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class FunctionsRouter extends PromiseRouter {
5858
}
5959

6060
static handleCloudJob(req) {
61-
const jobName = req.params.jobName || req.body.jobName;
61+
const jobName = req.params.jobName || req.body?.jobName;
6262
const applicationId = req.config.applicationId;
6363
const jobHandler = jobStatusHandler(req.config);
6464
const jobFunction = triggers.getJob(jobName, applicationId);

src/Routers/GlobalConfigRouter.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ export class GlobalConfigRouter extends PromiseRouter {
4646
"read-only masterKey isn't allowed to update the config."
4747
);
4848
}
49-
const params = req.body.params;
50-
const masterKeyOnly = req.body.masterKeyOnly || {};
49+
const params = req.body.params || {};
50+
const masterKeyOnly = req.body?.masterKeyOnly || {};
5151
// Transform in dot notation to make sure it works
5252
const update = Object.keys(params).reduce((acc, key) => {
5353
acc[`params.${key}`] = params[key];

src/Routers/GraphQLRouter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class GraphQLRouter extends PromiseRouter {
1919
"read-only masterKey isn't allowed to update the GraphQL config."
2020
);
2121
}
22-
const data = await req.config.parseGraphQLController.updateGraphQLConfig(req.body.params);
22+
const data = await req.config.parseGraphQLController.updateGraphQLConfig(req.body.params || {});
2323
return {
2424
response: data,
2525
};

src/Routers/HooksRouter.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export class HooksRouter extends PromiseRouter {
1212
}
1313

1414
handlePost(req) {
15-
return this.createHook(req.body, req.config);
15+
return this.createHook(req.body || {}, req.config);
1616
}
1717

1818
handleGetFunctions(req) {
@@ -66,11 +66,11 @@ export class HooksRouter extends PromiseRouter {
6666

6767
handleUpdate(req) {
6868
var hook;
69-
if (req.params.functionName && req.body.url) {
69+
if (req.params.functionName && req.body?.url) {
7070
hook = {};
7171
hook.functionName = req.params.functionName;
7272
hook.url = req.body.url;
73-
} else if (req.params.className && req.params.triggerName && req.body.url) {
73+
} else if (req.params.className && req.params.triggerName && req.body?.url) {
7474
hook = {};
7575
hook.className = req.params.className;
7676
hook.triggerName = req.params.triggerName;
@@ -82,7 +82,7 @@ export class HooksRouter extends PromiseRouter {
8282
}
8383

8484
handlePut(req) {
85-
var body = req.body;
85+
var body = req.body || {};
8686
if (body.__op == 'Delete') {
8787
return this.handleDelete(req);
8888
} else {

src/Routers/IAPValidationRouter.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ function getFileForProductIdentifier(productIdentifier, req) {
6868

6969
export class IAPValidationRouter extends PromiseRouter {
7070
handleRequest(req) {
71-
let receipt = req.body.receipt;
72-
const productIdentifier = req.body.productIdentifier;
71+
let receipt = req.body?.receipt;
72+
const productIdentifier = req.body?.productIdentifier;
7373

7474
if (!receipt || !productIdentifier) {
7575
// TODO: Error, malformed request
@@ -84,7 +84,7 @@ export class IAPValidationRouter extends PromiseRouter {
8484
}
8585
}
8686

87-
if (process.env.TESTING == '1' && req.body.bypassAppStoreValidation) {
87+
if (process.env.TESTING == '1' && req.body?.bypassAppStoreValidation) {
8888
return getFileForProductIdentifier(productIdentifier, req);
8989
}
9090

src/Routers/InstallationsRouter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class InstallationsRouter extends ClassesRouter {
1010
}
1111

1212
handleFind(req) {
13-
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
13+
const body = Object.assign(req.body || {}, ClassesRouter.JSONFromQuery(req.query));
1414
const options = ClassesRouter.optionsFromBody(body, req.config.defaultLimit);
1515
return rest
1616
.find(

src/Routers/PagesRouter.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export class PagesRouter extends PromiseRouter {
113113

114114
resendVerificationEmail(req) {
115115
const config = req.config;
116-
const username = req.body.username;
116+
const username = req.body?.username;
117117

118118
if (!config) {
119119
this.invalidRequest();
@@ -187,7 +187,7 @@ export class PagesRouter extends PromiseRouter {
187187
this.invalidRequest();
188188
}
189189

190-
const { username, new_password, token: rawToken } = req.body;
190+
const { username, new_password, token: rawToken } = req.body || {};
191191
const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken;
192192

193193
if ((!username || !token || !new_password) && req.xhr === false) {

src/Routers/PublicAPIRouter.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class PublicAPIRouter extends PromiseRouter {
4545
}
4646

4747
resendVerificationEmail(req) {
48-
const username = req.body.username;
48+
const username = req.body?.username;
4949
const appId = req.params.appId;
5050
const config = Config.get(appId);
5151

@@ -154,7 +154,7 @@ export class PublicAPIRouter extends PromiseRouter {
154154
return this.missingPublicServerURL();
155155
}
156156

157-
const { username, new_password, token: rawToken } = req.body;
157+
const { username, new_password, token: rawToken } = req.body || {};
158158
const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken;
159159

160160
if ((!username || !token || !new_password) && req.xhr === false) {

src/Routers/PushRouter.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class PushRouter extends PromiseRouter {
2626
});
2727
let pushStatusId;
2828
pushController
29-
.sendPush(req.body, where, req.config, req.auth, objectId => {
29+
.sendPush(req.body || {}, where, req.config, req.auth, objectId => {
3030
pushStatusId = objectId;
3131
resolve({
3232
headers: {

src/Routers/SchemasRouter.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,18 @@ async function createSchema(req) {
7777
"read-only masterKey isn't allowed to create a schema."
7878
);
7979
}
80-
if (req.params.className && req.body.className) {
80+
if (req.params.className && req.body?.className) {
8181
if (req.params.className != req.body.className) {
8282
return classNameMismatchResponse(req.body.className, req.params.className);
8383
}
8484
}
8585

86-
const className = req.params.className || req.body.className;
86+
const className = req.params.className || req.body?.className;
8787
if (!className) {
8888
throw new Parse.Error(135, `POST ${req.path} needs a class name.`);
8989
}
9090

91-
return await internalCreateSchema(className, req.body, req.config);
91+
return await internalCreateSchema(className, req.body || {}, req.config);
9292
}
9393

9494
function modifySchema(req) {
@@ -99,12 +99,12 @@ function modifySchema(req) {
9999
"read-only masterKey isn't allowed to update a schema."
100100
);
101101
}
102-
if (req.body.className && req.body.className != req.params.className) {
102+
if (req.body?.className && req.body.className != req.params.className) {
103103
return classNameMismatchResponse(req.body.className, req.params.className);
104104
}
105105
const className = req.params.className;
106106

107-
return internalUpdateSchema(className, req.body, req.config);
107+
return internalUpdateSchema(className, req.body || {}, req.config);
108108
}
109109

110110
const deleteSchema = req => {

0 commit comments

Comments
 (0)