UNPKG

@strongnguyen/oidc-provider

Version:

OAuth 2.0 Authorization Server implementation for Node.js with OpenID Connect

64 lines (55 loc) 1.99 kB
const querystring = require('querystring'); const raw = require('raw-body'); const attention = require('../helpers/attention'); const { InvalidRequest } = require('../helpers/errors'); let warned; async function selectiveBody(cty, ctx, next) { if (ctx.is(cty)) { try { let usedFallback; const body = await (() => { if (ctx.req.readable) { return raw(ctx.req, { length: ctx.request.length, limit: '56kb', encoding: ctx.charset, }); } if (!warned) { warned = true; /* eslint-disable no-multi-str */ attention.warn('already parsed request body detected, having upstream middleware parser \ is not recommended, resolving to use req.body or request.body instead'); /* eslint-enable */ } usedFallback = true; return ctx.req.body || ctx.request.body; })(); if (body instanceof Buffer || typeof body === 'string') { if (cty === 'application/json') { ctx.oidc.body = JSON.parse(body); } else { ctx.oidc.body = querystring.parse(body.toString()); } } else if (usedFallback && cty === 'application/x-www-form-urlencoded') { // get rid of possible upstream parsers that parse querystring with objects, arrays, etc ctx.oidc.body = querystring.parse(querystring.stringify(body)); } else { ctx.oidc.body = body; } } catch (err) { throw new InvalidRequest('failed to parse the request body'); } await next(); } else if (ctx.get('content-type')) { throw new InvalidRequest(`only ${cty} content-type bodies are supported on ${ctx.method} ${ctx.path}`); } else { ctx.oidc.body = {}; await next(); } } Object.assign(selectiveBody, { json: selectiveBody.bind(undefined, 'application/json'), urlencoded: selectiveBody.bind(undefined, 'application/x-www-form-urlencoded'), }); module.exports = selectiveBody;