mirror of
https://github.com/overleaf/overleaf.git
synced 2025-02-17 07:01:03 +00:00
Merge pull request #2620 from overleaf/ta-body-parser-errors
Convert Errors with Status Code To HTTP Errors GitOrigin-RevId: 4c7abf4f9164c1a907fbf38c6e440409a616e047
This commit is contained in:
parent
a53174a4d6
commit
fbbb39b0c0
3 changed files with 121 additions and 1 deletions
33
services/web/app/src/infrastructure/BodyParserWrapper.js
Normal file
33
services/web/app/src/infrastructure/BodyParserWrapper.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
const HttpErrors = require('@overleaf/o-error/http')
|
||||||
|
const bodyParser = require('body-parser')
|
||||||
|
|
||||||
|
const convertToHTTPError = error => {
|
||||||
|
if (!error.statusCode || error.statusCode < 400 || error.statusCode >= 600) {
|
||||||
|
// cannot be converted to a HttpError
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HttpErrors.HttpError({
|
||||||
|
message: error.message,
|
||||||
|
statusCode: error.statusCode
|
||||||
|
}).withCause(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wraps a parser and attempt to wrap its error (if any) into a HTTPError so the
|
||||||
|
// response code is forwarded to the client
|
||||||
|
const wrapBodyParser = method => opts => {
|
||||||
|
const middleware = bodyParser[method](opts)
|
||||||
|
return (req, res, next) => {
|
||||||
|
middleware(req, res, nextArg => {
|
||||||
|
if (nextArg instanceof Error) {
|
||||||
|
return next(convertToHTTPError(nextArg))
|
||||||
|
}
|
||||||
|
next(nextArg)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
urlencoded: wrapBodyParser('urlencoded'),
|
||||||
|
json: wrapBodyParser('json')
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ const SessionAutostartMiddleware = require('./SessionAutostartMiddleware')
|
||||||
const SessionStoreManager = require('./SessionStoreManager')
|
const SessionStoreManager = require('./SessionStoreManager')
|
||||||
const session = require('express-session')
|
const session = require('express-session')
|
||||||
const RedisStore = require('connect-redis')(session)
|
const RedisStore = require('connect-redis')(session)
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('./BodyParserWrapper')
|
||||||
const methodOverride = require('method-override')
|
const methodOverride = require('method-override')
|
||||||
const cookieParser = require('cookie-parser')
|
const cookieParser = require('cookie-parser')
|
||||||
const bearerToken = require('express-bearer-token')
|
const bearerToken = require('express-bearer-token')
|
||||||
|
|
87
services/web/test/acceptance/src/BodyParserErrorsTest.js
Normal file
87
services/web/test/acceptance/src/BodyParserErrorsTest.js
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
const Settings = require('settings-sharelatex')
|
||||||
|
const request = require('./helpers/request')
|
||||||
|
|
||||||
|
// create a string that is longer than the max allowed (as defined in Server.js)
|
||||||
|
const wayTooLongString = 'a'.repeat(2 * Settings.max_doc_length + 64 * 1024 + 1)
|
||||||
|
|
||||||
|
describe('BodyParserErrors', function() {
|
||||||
|
describe('when request is too large', function() {
|
||||||
|
describe('json', function() {
|
||||||
|
it('return 413', function(done) {
|
||||||
|
request.post(
|
||||||
|
{
|
||||||
|
url: '/login',
|
||||||
|
body: { password: wayTooLongString },
|
||||||
|
json: true
|
||||||
|
},
|
||||||
|
(error, response, body) => {
|
||||||
|
if (error) {
|
||||||
|
return done(error)
|
||||||
|
}
|
||||||
|
response.statusCode.should.equal(413)
|
||||||
|
body.should.deep.equal({})
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('urlencoded', function() {
|
||||||
|
it('return 413', function(done) {
|
||||||
|
request.post(
|
||||||
|
{
|
||||||
|
url: '/login',
|
||||||
|
form: { password: wayTooLongString }
|
||||||
|
},
|
||||||
|
(error, response, body) => {
|
||||||
|
if (error) {
|
||||||
|
return done(error)
|
||||||
|
}
|
||||||
|
response.statusCode.should.equal(413)
|
||||||
|
body.should.match(/Something went wrong, sorry/)
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when request is not too large', function() {
|
||||||
|
describe('json', function() {
|
||||||
|
it('return normal status code', function(done) {
|
||||||
|
request.post(
|
||||||
|
{
|
||||||
|
url: '/login',
|
||||||
|
body: { password: 'foo' },
|
||||||
|
json: true
|
||||||
|
},
|
||||||
|
(error, response, body) => {
|
||||||
|
if (error) {
|
||||||
|
return done(error)
|
||||||
|
}
|
||||||
|
response.statusCode.should.equal(403)
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('urlencoded', function() {
|
||||||
|
it('return normal status code', function(done) {
|
||||||
|
request.post(
|
||||||
|
{
|
||||||
|
url: '/login',
|
||||||
|
form: { password: 'foo' }
|
||||||
|
},
|
||||||
|
(error, response, body) => {
|
||||||
|
if (error) {
|
||||||
|
return done(error)
|
||||||
|
}
|
||||||
|
response.statusCode.should.equal(403)
|
||||||
|
done()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in a new issue