diff --git a/src/identity/configuration/IdentityProviderFactory.ts b/src/identity/configuration/IdentityProviderFactory.ts index 3f094e459c..93b5545ac6 100644 --- a/src/identity/configuration/IdentityProviderFactory.ts +++ b/src/identity/configuration/IdentityProviderFactory.ts @@ -314,6 +314,12 @@ export class IdentityProviderFactory implements ProviderFactory { config.renderError = async(ctx: KoaContextWithOIDC, out: ErrorOut, error: Error): Promise => { // This allows us to stream directly to the response object, see https://github.com/koajs/koa/issues/944 ctx.respond = false; + + // OIDC library hides extra details in this field + if (out.error_description) { + error.message += ` - ${out.error_description}`; + } + const result = await this.errorHandler.handleSafe({ error, preferences: { type: { 'text/plain': 1 }}}); await this.responseWriter.handleSafe({ response: ctx.res, result }); }; diff --git a/test/unit/identity/configuration/IdentityProviderFactory.test.ts b/test/unit/identity/configuration/IdentityProviderFactory.test.ts index ceffb5a6d7..10b4aa10fd 100644 --- a/test/unit/identity/configuration/IdentityProviderFactory.test.ts +++ b/test/unit/identity/configuration/IdentityProviderFactory.test.ts @@ -129,7 +129,7 @@ describe('An IdentityProviderFactory', (): void => { // Test the renderError function const response = { } as HttpResponse; - await expect((config.renderError as any)({ res: response }, null, 'error!')).resolves.toBeUndefined(); + await expect((config.renderError as any)({ res: response }, {}, 'error!')).resolves.toBeUndefined(); expect(errorHandler.handleSafe).toHaveBeenCalledTimes(1); expect(errorHandler.handleSafe) .toHaveBeenLastCalledWith({ error: 'error!', preferences: { type: { 'text/plain': 1 }}}); @@ -191,4 +191,22 @@ describe('An IdentityProviderFactory', (): void => { expect(storage.set).toHaveBeenCalledWith('jwks', result1.config.jwks); expect(storage.set).toHaveBeenCalledWith('cookie-secret', result1.config.cookies?.keys); }); + + it('updates errors if there is more information.', async(): Promise => { + const provider = await factory.getProvider() as any; + const { config } = provider as { config: Configuration }; + const response = { } as HttpResponse; + + const error = new Error('bad data'); + const out = { error_description: 'more info' }; + + await expect((config.renderError as any)({ res: response }, out, error)).resolves.toBeUndefined(); + expect(errorHandler.handleSafe).toHaveBeenCalledTimes(1); + expect(errorHandler.handleSafe) + .toHaveBeenLastCalledWith({ error, preferences: { type: { 'text/plain': 1 }}}); + expect(responseWriter.handleSafe).toHaveBeenCalledTimes(1); + expect(responseWriter.handleSafe).toHaveBeenLastCalledWith({ response, result: { statusCode: 500 }}); + expect(error.message).toBe('bad data - more info'); + expect(error.stack).toContain('Error: bad data - more info'); + }); });