validate_responses.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /*
  2. * This file is part of the storage node for the Joystream project.
  3. * Copyright (C) 2019 Joystream Contributors
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. 'use strict'
  19. const debug = require('debug')('joystream:middleware:validate')
  20. // Function taken directly from https://github.com/kogosoftwarellc/open-api/tree/master/packages/express-openapi
  21. module.exports = function (req, res, next) {
  22. const strictValidation = !!req.apiDoc['x-express-openapi-validation-strict']
  23. if (typeof res.validateResponse === 'function') {
  24. const send = res.send
  25. res.send = function expressOpenAPISend(...args) {
  26. const onlyWarn = !strictValidation
  27. if (res.get('x-express-openapi-validation-error-for') !== undefined) {
  28. return send.apply(res, args)
  29. }
  30. if (res.get('x-express-openapi-validation-for') !== undefined) {
  31. return send.apply(res, args)
  32. }
  33. const body = args[0]
  34. let validation = res.validateResponse(res.statusCode, body)
  35. let validationMessage
  36. if (validation === undefined) {
  37. validation = { message: undefined, errors: undefined }
  38. }
  39. if (validation.errors) {
  40. const errorList = Array.from(validation.errors)
  41. .map((_) => _.message)
  42. .join(',')
  43. validationMessage = `Invalid response for status code ${res.statusCode}: ${errorList}`
  44. debug(validationMessage)
  45. // Set to avoid a loop, and to provide the original status code
  46. res.set('x-express-openapi-validation-error-for', res.statusCode.toString())
  47. }
  48. if ((onlyWarn || !validation.errors) && res.statusCode) {
  49. res.set('x-express-openapi-validation-for', res.statusCode.toString())
  50. return send.apply(res, args)
  51. }
  52. res.status(500)
  53. return res.json({ error: validationMessage })
  54. }
  55. }
  56. next()
  57. }