diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2a143eed63..6dba5c2d9f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,23 +27,23 @@ jobs:
include:
- name: Node.js 4.0
node-version: "4.0"
- npm-i: mocha@5.2.0 supertest@3.4.2
+ npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 4.x
node-version: "4.9"
- npm-i: mocha@5.2.0 supertest@3.4.2
+ npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 5.x
node-version: "5.12"
- npm-i: mocha@5.2.0 supertest@3.4.2
+ npm-i: mocha@5.2.0 nyc@11.9.0 supertest@3.4.2
- name: Node.js 6.x
node-version: "6.17"
- npm-i: mocha@6.2.2
+ npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6
- name: Node.js 7.x
node-version: "7.10"
- npm-i: mocha@6.2.2
+ npm-i: mocha@6.2.2 nyc@14.1.1 supertest@6.1.6
- name: Node.js 8.x
node-version: "8.17"
@@ -68,7 +68,7 @@ jobs:
node-version: "13.14"
- name: Node.js 14.x
- node-version: "14.18"
+ node-version: "14.19"
steps:
- uses: actions/checkout@v2
@@ -113,6 +113,7 @@ jobs:
echo "node@$(node -v)"
echo "npm@$(npm -v)"
npm -s ls ||:
+ (npm -s ls --depth=0 ||:) | awk -F'[ @]' 'NR>1 && $2 { print "::set-output name=" $2 "::" $3 }'
- name: Run tests
shell: bash
diff --git a/.gitignore b/.gitignore
index 5fee6a2dc9..3a673d9cc0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,27 +1,15 @@
-# OS X
-.DS_Store*
-Icon?
-._*
-
-# Windows
-Thumbs.db
-ehthumbs.db
-Desktop.ini
-
-# Linux
-.directory
-*~
-
-
# npm
node_modules
package-lock.json
*.log
*.gz
-
# Coveralls
+.nyc_output
coverage
# Benchmarking
benchmarks/graphs
+
+# ignore additional files using core.excludesFile
+# https://git-scm.com/docs/gitignore
diff --git a/History.md b/History.md
index d89efef4e6..5380daf09c 100644
--- a/History.md
+++ b/History.md
@@ -1,3 +1,8 @@
+5.x
+===
+
+This incorporates all changes after 4.17.2 up to 4.17.3.
+
5.0.0-beta.1 / 2022-02-14
=========================
@@ -157,6 +162,21 @@ This is the first Express 5.0 alpha release, based off 4.10.1.
* add:
- `app.router` is a reference to the base router
+4.17.3 / 2022-02-16
+===================
+
+ * deps: accepts@~1.3.8
+ - deps: mime-types@~2.1.34
+ - deps: negotiator@0.6.3
+ * deps: body-parser@1.19.2
+ - deps: bytes@3.1.2
+ - deps: qs@6.9.7
+ - deps: raw-body@2.4.3
+ * deps: cookie@0.4.2
+ * deps: qs@6.9.7
+ * Fix handling of `__proto__` keys
+ * pref: remove unnecessary regexp for trust proxy
+
4.17.2 / 2021-12-16
===================
diff --git a/appveyor.yml b/appveyor.yml
index 433729652b..7f7a3717e7 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,7 +10,7 @@ environment:
- nodejs_version: "11.15"
- nodejs_version: "12.22"
- nodejs_version: "13.14"
- - nodejs_version: "14.18"
+ - nodejs_version: "14.19"
cache:
- node_modules
install:
@@ -46,11 +46,25 @@ install:
} elseif ([int]$env:nodejs_version.split(".")[0] -lt 12) {
npm install --silent --save-dev mocha@8.4.0
}
+ - ps: |
+ # nyc for test coverage
+ # - use 10.3.2 for Node.js < 4
+ # - use 11.9.0 for Node.js < 6
+ # - use 14.1.1 for Node.js < 8
+ if ([int]$env:nodejs_version.split(".")[0] -lt 4) {
+ npm install --silent --save-dev nyc@10.3.2
+ } elseif ([int]$env:nodejs_version.split(".")[0] -lt 6) {
+ npm install --silent --save-dev nyc@11.9.0
+ } elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) {
+ npm install --silent --save-dev nyc@14.1.1
+ }
- ps: |
# supertest for http calls
# - use 3.4.2 for Node.js < 6
if ([int]$env:nodejs_version.split(".")[0] -lt 6) {
npm install --silent --save-dev supertest@3.4.2
+ } elseif ([int]$env:nodejs_version.split(".")[0] -lt 8) {
+ npm install --silent --save-dev supertest@6.1.6
}
# Update Node.js modules
- ps: |
diff --git a/examples/auth/index.js b/examples/auth/index.js
index 2f05d5ff8d..2859545c54 100644
--- a/examples/auth/index.js
+++ b/examples/auth/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
@@ -59,14 +61,14 @@ function authenticate(name, pass, fn) {
if (!module.parent) console.log('authenticating %s:%s', name, pass);
var user = users[name];
// query the db for the given username
- if (!user) return fn(new Error('cannot find user'));
+ if (!user) return fn(null, null)
// apply the same algorithm to the POSTed password, applying
// the hash against the pass / salt, if there is a match we
// found the user
hash({ password: pass, salt: user.salt }, function (err, pass, salt, hash) {
if (err) return fn(err);
if (hash === user.hash) return fn(null, user)
- fn(new Error('invalid password'));
+ fn(null, null)
});
}
@@ -99,9 +101,10 @@ app.get('/login', function(req, res){
res.render('login');
});
-app.post('/login', function(req, res){
+app.post('/login', function (req, res, next) {
if (!req.body) return res.sendStatus(400)
authenticate(req.body.username, req.body.password, function(err, user){
+ if (err) return next(err)
if (user) {
// Regenerate session when signing in
// to prevent fixation
diff --git a/examples/content-negotiation/db.js b/examples/content-negotiation/db.js
index 43fb04baa1..f59b23bf18 100644
--- a/examples/content-negotiation/db.js
+++ b/examples/content-negotiation/db.js
@@ -1,3 +1,5 @@
+'use strict'
+
var users = [];
users.push({ name: 'Tobi' });
diff --git a/examples/content-negotiation/index.js b/examples/content-negotiation/index.js
index 348929e852..280a4e2299 100644
--- a/examples/content-negotiation/index.js
+++ b/examples/content-negotiation/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
var express = require('../../');
var app = module.exports = express();
var users = require('./db');
diff --git a/examples/content-negotiation/users.js b/examples/content-negotiation/users.js
index fe511072ec..fe703e73a9 100644
--- a/examples/content-negotiation/users.js
+++ b/examples/content-negotiation/users.js
@@ -1,3 +1,4 @@
+'use strict'
var users = require('./db');
diff --git a/examples/cookie-sessions/index.js b/examples/cookie-sessions/index.js
index 1dda15de61..01c731c1c8 100644
--- a/examples/cookie-sessions/index.js
+++ b/examples/cookie-sessions/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/cookies/index.js b/examples/cookies/index.js
index 7d6264a143..8bca73ff97 100644
--- a/examples/cookies/index.js
+++ b/examples/cookies/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/downloads/index.js b/examples/downloads/index.js
index dc59532c40..0d8118591f 100644
--- a/examples/downloads/index.js
+++ b/examples/downloads/index.js
@@ -1,11 +1,18 @@
+'use strict'
+
/**
* Module dependencies.
*/
var express = require('../../');
var path = require('path');
+var resolvePath = require('resolve-path')
+
var app = module.exports = express();
+// path to where the files are stored on disk
+var FILES_DIR = path.join(__dirname, 'files')
+
app.get('/', function(req, res){
res.send('
' +
'- Download notes/groceries.txt.
' +
@@ -18,7 +25,7 @@ app.get('/', function(req, res){
// /files/* is accessed via req.params[0]
// but here we name it :file
app.get('/files/:file+', function (req, res, next) {
- var filePath = path.join(__dirname, 'files', req.params.file);
+ var filePath = resolvePath(FILES_DIR, req.params.file)
res.download(filePath, function (err) {
if (!err) return; // file sent
diff --git a/examples/ejs/index.js b/examples/ejs/index.js
index 7278091293..a39d805a16 100644
--- a/examples/ejs/index.js
+++ b/examples/ejs/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/error-pages/index.js b/examples/error-pages/index.js
index 44333cb08f..efa815c474 100644
--- a/examples/error-pages/index.js
+++ b/examples/error-pages/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/error/index.js b/examples/error/index.js
index 07814d8520..d922de06cc 100644
--- a/examples/error/index.js
+++ b/examples/error/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/hello-world/index.js b/examples/hello-world/index.js
index 04382ac3d0..8c1855c2eb 100644
--- a/examples/hello-world/index.js
+++ b/examples/hello-world/index.js
@@ -1,6 +1,8 @@
+'use strict'
+
var express = require('../../');
-var app = express();
+var app = module.exports = express()
app.get('/', function(req, res){
res.send('Hello World');
diff --git a/examples/markdown/index.js b/examples/markdown/index.js
index df8c195fb4..74ac05e77f 100644
--- a/examples/markdown/index.js
+++ b/examples/markdown/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/multi-router/controllers/api_v1.js b/examples/multi-router/controllers/api_v1.js
index 08b7b5e6fd..a301e3ee72 100644
--- a/examples/multi-router/controllers/api_v1.js
+++ b/examples/multi-router/controllers/api_v1.js
@@ -1,3 +1,5 @@
+'use strict'
+
var express = require('../../..');
var apiv1 = express.Router();
diff --git a/examples/multi-router/controllers/api_v2.js b/examples/multi-router/controllers/api_v2.js
index 4dd708281c..e997fb1f88 100644
--- a/examples/multi-router/controllers/api_v2.js
+++ b/examples/multi-router/controllers/api_v2.js
@@ -1,3 +1,5 @@
+'use strict'
+
var express = require('../../..');
var apiv2 = express.Router();
diff --git a/examples/multi-router/index.js b/examples/multi-router/index.js
index 78bae9d6e3..dbfd284126 100644
--- a/examples/multi-router/index.js
+++ b/examples/multi-router/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
var express = require('../..');
var app = module.exports = express();
diff --git a/examples/multipart/index.js b/examples/multipart/index.js
index 42c2af23f7..ea7b86e0c9 100644
--- a/examples/multipart/index.js
+++ b/examples/multipart/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/mvc/controllers/main/index.js b/examples/mvc/controllers/main/index.js
index 031862d345..74cde191cd 100644
--- a/examples/mvc/controllers/main/index.js
+++ b/examples/mvc/controllers/main/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
exports.index = function(req, res){
res.redirect('/users');
};
diff --git a/examples/mvc/controllers/pet/index.js b/examples/mvc/controllers/pet/index.js
index 157a98e84e..214160f9a4 100644
--- a/examples/mvc/controllers/pet/index.js
+++ b/examples/mvc/controllers/pet/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/mvc/controllers/user-pet/index.js b/examples/mvc/controllers/user-pet/index.js
index 416b00741a..42a29adebe 100644
--- a/examples/mvc/controllers/user-pet/index.js
+++ b/examples/mvc/controllers/user-pet/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/mvc/controllers/user/index.js b/examples/mvc/controllers/user/index.js
index a7b0208c8e..ec3ae4c811 100644
--- a/examples/mvc/controllers/user/index.js
+++ b/examples/mvc/controllers/user/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/mvc/db.js b/examples/mvc/db.js
index c992afcfd7..94d1480f9b 100644
--- a/examples/mvc/db.js
+++ b/examples/mvc/db.js
@@ -1,3 +1,5 @@
+'use strict'
+
// faux database
var pets = exports.pets = [];
diff --git a/examples/mvc/index.js b/examples/mvc/index.js
index 77885a60ca..da4727b282 100644
--- a/examples/mvc/index.js
+++ b/examples/mvc/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/mvc/lib/boot.js b/examples/mvc/lib/boot.js
index 422330dc06..0216e5d76d 100644
--- a/examples/mvc/lib/boot.js
+++ b/examples/mvc/lib/boot.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/online/index.js b/examples/online/index.js
index f14474c08d..0b5fdffc86 100644
--- a/examples/online/index.js
+++ b/examples/online/index.js
@@ -1,3 +1,4 @@
+'use strict'
// install redis first:
// https://redis.io/
diff --git a/examples/params/index.js b/examples/params/index.js
index 5b57573d1e..b153b93b98 100644
--- a/examples/params/index.js
+++ b/examples/params/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/resource/index.js b/examples/resource/index.js
index b79ad923d2..ff1f6fe11f 100644
--- a/examples/resource/index.js
+++ b/examples/resource/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/route-map/index.js b/examples/route-map/index.js
index e7adf5fcb4..2bc28bd4b2 100644
--- a/examples/route-map/index.js
+++ b/examples/route-map/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/route-middleware/index.js b/examples/route-middleware/index.js
index e7a0901fa8..44ec13a95b 100644
--- a/examples/route-middleware/index.js
+++ b/examples/route-middleware/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/route-separation/index.js b/examples/route-separation/index.js
index 6512109134..5d48381111 100644
--- a/examples/route-separation/index.js
+++ b/examples/route-separation/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/route-separation/post.js b/examples/route-separation/post.js
index e3f12e7884..3a8e3a2d22 100644
--- a/examples/route-separation/post.js
+++ b/examples/route-separation/post.js
@@ -1,3 +1,5 @@
+'use strict'
+
// Fake posts database
var posts = [
diff --git a/examples/route-separation/site.js b/examples/route-separation/site.js
index a3d20bc8a1..aee36d1bd7 100644
--- a/examples/route-separation/site.js
+++ b/examples/route-separation/site.js
@@ -1,3 +1,5 @@
+'use strict'
+
exports.index = function(req, res){
res.render('index', { title: 'Route Separation Example' });
};
diff --git a/examples/route-separation/user.js b/examples/route-separation/user.js
index ef79b343a2..1c2aec7cd2 100644
--- a/examples/route-separation/user.js
+++ b/examples/route-separation/user.js
@@ -1,3 +1,5 @@
+'use strict'
+
// Fake user database
var users = [
diff --git a/examples/search/index.js b/examples/search/index.js
index add16d5248..4b57168987 100644
--- a/examples/search/index.js
+++ b/examples/search/index.js
@@ -1,3 +1,4 @@
+'use strict'
// install redis first:
// https://redis.io/
diff --git a/examples/search/public/client.js b/examples/search/public/client.js
index 75c37d8e00..cd43faf71e 100644
--- a/examples/search/public/client.js
+++ b/examples/search/public/client.js
@@ -1,3 +1,5 @@
+'use strict'
+
var search = document.querySelector('[type=search]');
var code = document.querySelector('pre');
diff --git a/examples/session/index.js b/examples/session/index.js
index 9bae48b8d3..2bb2b109c8 100644
--- a/examples/session/index.js
+++ b/examples/session/index.js
@@ -1,3 +1,4 @@
+'use strict'
// install redis first:
// https://redis.io/
diff --git a/examples/session/redis.js b/examples/session/redis.js
index 1338d6e95e..bbbdc7fd3e 100644
--- a/examples/session/redis.js
+++ b/examples/session/redis.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/static-files/index.js b/examples/static-files/index.js
index 0e44313d15..609c546b47 100644
--- a/examples/static-files/index.js
+++ b/examples/static-files/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/vhost/index.js b/examples/vhost/index.js
index 4a0c17b850..a9499356b4 100644
--- a/examples/vhost/index.js
+++ b/examples/vhost/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/view-constructor/github-view.js b/examples/view-constructor/github-view.js
index 0a98a90843..43d29336ca 100644
--- a/examples/view-constructor/github-view.js
+++ b/examples/view-constructor/github-view.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/view-constructor/index.js b/examples/view-constructor/index.js
index 175a254e4e..3d673670e3 100644
--- a/examples/view-constructor/index.js
+++ b/examples/view-constructor/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/view-locals/index.js b/examples/view-locals/index.js
index cb41509606..bf52d2a85a 100644
--- a/examples/view-locals/index.js
+++ b/examples/view-locals/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
diff --git a/examples/view-locals/user.js b/examples/view-locals/user.js
index 90ab1f389d..aaa6f85ff0 100644
--- a/examples/view-locals/user.js
+++ b/examples/view-locals/user.js
@@ -1,3 +1,5 @@
+'use strict'
+
module.exports = User;
// faux model
diff --git a/examples/web-service/index.js b/examples/web-service/index.js
index 3685619d10..a2cd2cb7f9 100644
--- a/examples/web-service/index.js
+++ b/examples/web-service/index.js
@@ -1,3 +1,5 @@
+'use strict'
+
/**
* Module dependencies.
*/
@@ -32,7 +34,7 @@ app.use('/api', function(req, res, next){
if (!key) return next(error(400, 'api key required'));
// key is invalid
- if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key'));
+ if (apiKeys.indexOf(key) === -1) return next(error(401, 'invalid api key'))
// all good, store req.key for route access
req.key = key;
diff --git a/lib/response.js b/lib/response.js
index d3c8a45b5c..e6f3cce13e 100644
--- a/lib/response.js
+++ b/lib/response.js
@@ -389,7 +389,7 @@ res.sendFile = function sendFile(path, options, callback) {
* Optionally providing an alternate attachment `filename`,
* and optional callback `callback(err)`. The callback is invoked
* when the data transfer is complete, or when an error has
- * ocurred. Be sure to check `res.headersSent` if you plan to respond.
+ * occurred. Be sure to check `res.headersSent` if you plan to respond.
*
* Optionally providing an `options` object to use with `res.sendFile()`.
* This function will set the `Content-Disposition` header, overriding
diff --git a/lib/utils.js b/lib/utils.js
index 43cf47ada8..df3335bee2 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -187,7 +187,8 @@ exports.compileTrust = function(val) {
if (typeof val === 'string') {
// Support comma-separated values
- val = val.split(/ *, */);
+ val = val.split(',')
+ .map(function (v) { return v.trim() })
}
return proxyaddr.compile(val || []);
diff --git a/package.json b/package.json
index e22f640d57..302cdfa050 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,7 @@
"body-parser": "2.0.0-beta.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.4.1",
+ "cookie": "0.4.2",
"cookie-signature": "1.0.6",
"debug": "3.1.0",
"depd": "~1.1.2",
@@ -49,7 +49,7 @@
"parseurl": "~1.3.3",
"path-is-absolute": "1.0.1",
"proxy-addr": "~2.0.7",
- "qs": "6.9.6",
+ "qs": "6.9.7",
"range-parser": "~1.2.1",
"router": "2.0.0-beta.1",
"safe-buffer": "5.2.1",
@@ -70,15 +70,16 @@
"eslint": "7.32.0",
"express-session": "1.17.2",
"hbs": "4.2.0",
- "istanbul": "0.4.5",
"marked": "0.7.0",
"method-override": "3.0.0",
- "mocha": "9.1.3",
+ "mocha": "9.2.0",
"morgan": "1.10.0",
- "multiparty": "4.2.2",
+ "multiparty": "4.2.3",
+ "nyc": "15.1.0",
"pbkdf2-password": "1.2.1",
+ "resolve-path": "1.4.0",
"should": "13.2.3",
- "supertest": "6.1.6",
+ "supertest": "6.2.2",
"vhost": "~3.0.2"
},
"engines": {
@@ -94,8 +95,8 @@
"scripts": {
"lint": "eslint .",
"test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/",
- "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/",
- "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
+ "test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
+ "test-cov": "nyc --reporter=html --reporter=text npm test",
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
}
}
diff --git a/test/Route.js b/test/Route.js
index 8f90152d8c..005b4634e9 100644
--- a/test/Route.js
+++ b/test/Route.js
@@ -1,3 +1,4 @@
+'use strict'
var after = require('after');
var should = require('should');
diff --git a/test/Router.js b/test/Router.js
index 30837ff123..233a907a74 100644
--- a/test/Router.js
+++ b/test/Router.js
@@ -1,3 +1,4 @@
+'use strict'
var after = require('after');
var express = require('../')
diff --git a/test/acceptance/auth.js b/test/acceptance/auth.js
index 9a36ea45fe..d7838755a0 100644
--- a/test/acceptance/auth.js
+++ b/test/acceptance/auth.js
@@ -22,7 +22,7 @@ describe('auth', function(){
.expect(200, /