diff --git a/src/lib/oauth2-service.ts b/src/lib/oauth2-service.ts index cd73f24..4aef781 100644 --- a/src/lib/oauth2-service.ts +++ b/src/lib/oauth2-service.ts @@ -172,105 +172,109 @@ export class OAuth2Service extends EventEmitter { res.json({ keys: this.issuer.keys.toJSON() }); }; - private tokenHandler: RequestHandler = async (req, res) => { - const tokenTtl = defaultTokenTtl; - - res.set({ - 'Cache-Control': 'no-store', - Pragma: 'no-cache', - }); - - let xfn: ScopesOrTransform | undefined; - - assertIsValidTokenRequest(req.body); - const reqBody = req.body; + private tokenHandler: RequestHandler = async (req, res, next) => { + try { + const tokenTtl = defaultTokenTtl; + + res.set({ + 'Cache-Control': 'no-store', + Pragma: 'no-cache', + }); + + let xfn: ScopesOrTransform | undefined; + + assertIsValidTokenRequest(req.body); + const reqBody = req.body; + + let { scope } = reqBody; + + switch (req.body.grant_type) { + case 'client_credentials': + xfn = scope; + break; + case 'password': + xfn = (_header, payload) => { + Object.assign(payload, { + sub: reqBody.username, + amr: ['pwd'], + scope, + }); + }; + break; + case 'authorization_code': + scope = 'dummy'; + xfn = (_header, payload) => { + Object.assign(payload, { + sub: 'johndoe', + amr: ['pwd'], + scope, + }); + }; + break; + case 'refresh_token': + scope = 'dummy'; + xfn = (_header, payload) => { + Object.assign(payload, { + sub: 'johndoe', + amr: ['pwd'], + scope, + }); + }; + break; + default: + return res.status(400).json({ + error: 'invalid_grant', + }); + } - let { scope } = reqBody; + const token = await this.buildToken(req, tokenTtl, xfn); + const body: Record = { + access_token: token, + token_type: 'Bearer', + expires_in: tokenTtl, + scope, + }; + if (req.body.grant_type !== 'client_credentials') { + const credentials = basicAuth(req); + const clientId = credentials ? credentials.name : req.body.client_id; - switch (req.body.grant_type) { - case 'client_credentials': - xfn = scope; - break; - case 'password': - xfn = (_header, payload) => { - Object.assign(payload, { - sub: reqBody.username, - amr: ['pwd'], - scope, - }); - }; - break; - case 'authorization_code': - scope = 'dummy'; - xfn = (_header, payload) => { - Object.assign(payload, { - sub: 'johndoe', - amr: ['pwd'], - scope, - }); - }; - break; - case 'refresh_token': - scope = 'dummy'; - xfn = (_header, payload) => { + const xfn: JwtTransform = (_header, payload) => { Object.assign(payload, { sub: 'johndoe', - amr: ['pwd'], - scope, + aud: clientId, }); + if (reqBody.code !== undefined && this.#nonce[reqBody.code]) { + Object.assign(payload, { + nonce: this.#nonce[reqBody.code], + }); + delete this.#nonce[reqBody.code]; + } }; - break; - default: - return res.status(400).json({ - error: 'invalid_grant', - }); - } - const token = await this.buildToken(req, tokenTtl, xfn); - const body: Record = { - access_token: token, - token_type: 'Bearer', - expires_in: tokenTtl, - scope, - }; - if (req.body.grant_type !== 'client_credentials') { - const credentials = basicAuth(req); - const clientId = credentials ? credentials.name : req.body.client_id; - - const xfn: JwtTransform = (_header, payload) => { - Object.assign(payload, { - sub: 'johndoe', - aud: clientId, - }); - if (reqBody.code !== undefined && this.#nonce[reqBody.code]) { - Object.assign(payload, { - nonce: this.#nonce[reqBody.code], - }); - delete this.#nonce[reqBody.code]; - } - }; - - body.id_token = await this.buildToken(req, tokenTtl, xfn); - body.refresh_token = uuidv4(); - } + body.id_token = await this.buildToken(req, tokenTtl, xfn); + body.refresh_token = uuidv4(); + } - const tokenEndpointResponse: MutableResponse = { - body, - statusCode: 200, - }; + const tokenEndpointResponse: MutableResponse = { + body, + statusCode: 200, + }; - /** - * Before token response event. - * - * @event OAuth2Service#beforeResponse - * @param {MutableResponse} response The response body and status code. - * @param {IncomingMessage} req The incoming HTTP request. - */ - this.emit(Events.BeforeResponse, tokenEndpointResponse, req); + /** + * Before token response event. + * + * @event OAuth2Service#beforeResponse + * @param {MutableResponse} response The response body and status code. + * @param {IncomingMessage} req The incoming HTTP request. + */ + this.emit(Events.BeforeResponse, tokenEndpointResponse, req); - return res - .status(tokenEndpointResponse.statusCode) - .json(tokenEndpointResponse.body); + return res + .status(tokenEndpointResponse.statusCode) + .json(tokenEndpointResponse.body); + } catch (e) { + return next(e); + } }; private authorizeHandler: RequestHandler = (req, res) => {