UNPKG

@strongnguyen/oidc-provider

Version:

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

90 lines (73 loc) 2.49 kB
const { strict: assert } = require('assert'); const { InvalidClient, InvalidRequestObject, } = require('../../helpers/errors'); const presence = require('../../helpers/validate_presence'); const base64url = require('../../helpers/base64url'); const instance = require('../../helpers/weak_cache'); const { PUSHED_REQUEST_URN } = require('../../consts'); const rejectRequestAndUri = require('./reject_request_and_uri'); const loadPushedAuthorizationRequest = require('./load_pushed_authorization_request'); /* * Checks client_id * - value presence in provided params * - value being resolved as a client * * @throws: invalid_request * @throws: invalid_client */ module.exports = async function checkClient(ctx, next) { const { oidc: { params } } = ctx; const { pushedAuthorizationRequests } = instance(ctx.oidc.provider).configuration('features'); try { presence(ctx, 'client_id'); } catch (err) { const { request_uri: requestUri } = params; let { request } = params; if ( !( pushedAuthorizationRequests.enabled && requestUri && requestUri.startsWith(PUSHED_REQUEST_URN) ) && request === undefined ) { throw err; } rejectRequestAndUri(ctx, () => {}); if (requestUri) { const loadedRequestObject = await loadPushedAuthorizationRequest(ctx); ({ request } = loadedRequestObject); } const parts = request.split('.'); let decoded; let clientId; try { assert(parts.length === 3 || parts.length === 5); parts.forEach((part, i, { length }) => { if (length === 3 && i === 1) { // JWT Payload decoded = JSON.parse(base64url.decodeToBuffer(part)); } else if (length === 5 && i === 0) { // JWE Header decoded = JSON.parse(base64url.decodeToBuffer(part)); } }); } catch (error) { throw new InvalidRequestObject(`Request Object is not a valid ${parts.length === 5 ? 'JWE' : 'JWT'}`); } if (decoded) { clientId = decoded.iss; } if (typeof clientId !== 'string' || !clientId) { throw err; } params.client_id = clientId; } const client = await ctx.oidc.provider.Client.find(ctx.oidc.params.client_id); if (!client) { // there's no point in checking again in authorization error handler ctx.oidc.noclient = true; throw new InvalidClient('client is invalid', 'client not found'); } ctx.oidc.entity('Client', client); return next(); };