From f71f8683fc0f4e40de2e1c64547397f32c0b6472 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Fri, 13 Aug 2021 12:05:22 +0200 Subject: [PATCH] feat: Indicate to templates if this is part of an auth request --- src/identity/IdentityProviderHttpHandler.ts | 19 ++++++++++------- .../email-password/register-response.html.ejs | 6 +++++- .../IdentityProviderHttpHandler.test.ts | 21 +++++++++++-------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/identity/IdentityProviderHttpHandler.ts b/src/identity/IdentityProviderHttpHandler.ts index 93b72ad32..dfc65da0f 100644 --- a/src/identity/IdentityProviderHttpHandler.ts +++ b/src/identity/IdentityProviderHttpHandler.ts @@ -167,8 +167,9 @@ export class IdentityProviderHttpHandler extends HttpHandler { private async resolveRoute(request: HttpRequest, response: HttpResponse, route: InteractionRoute, oidcInteraction?: Interaction): Promise { if (request.method === 'GET') { - // .ejs templates errors on undefined variables - return await this.handleTemplateResponse(response, route.viewTemplate, { errorMessage: '', prefilled: {}}); + return await this.handleTemplateResponse( + response, route.viewTemplate, { errorMessage: '', prefilled: {}}, oidcInteraction, + ); } if (request.method === 'POST') { @@ -179,7 +180,9 @@ export class IdentityProviderHttpHandler extends HttpHandler { // Render error in the view const prefilled = IdpInteractionError.isInstance(error) ? error.prefilled : {}; const errorMessage = createErrorMessage(error); - return await this.handleTemplateResponse(response, route.viewTemplate, { errorMessage, prefilled }); + return await this.handleTemplateResponse( + response, route.viewTemplate, { errorMessage, prefilled }, oidcInteraction, + ); } if (result.type === 'complete') { @@ -193,15 +196,17 @@ export class IdentityProviderHttpHandler extends HttpHandler { return await this.interactionCompleter.handleSafe({ ...result.details, request, response }); } if (result.type === 'response' && route.responseTemplate) { - return await this.handleTemplateResponse(response, route.responseTemplate, result.details); + return await this.handleTemplateResponse(response, route.responseTemplate, result.details, oidcInteraction); } } throw new BadRequestHttpError(`Unsupported request: ${request.method} ${request.url}`); } - private async handleTemplateResponse(response: HttpResponse, templateFile: string, contents?: NodeJS.Dict): - Promise { - await this.templateHandler.handleSafe({ response, templateFile, contents: contents ?? {}}); + private async handleTemplateResponse(response: HttpResponse, templateFile: string, data?: NodeJS.Dict, + oidcInteraction?: Interaction): Promise { + const contents = data ?? {}; + contents.authenticating = Boolean(oidcInteraction); + await this.templateHandler.handleSafe({ response, templateFile, contents }); } /** diff --git a/templates/identity/email-password/register-response.html.ejs b/templates/identity/email-password/register-response.html.ejs index bf5246af4..b9ce94f1b 100644 --- a/templates/identity/email-password/register-response.html.ejs +++ b/templates/identity/email-password/register-response.html.ejs @@ -26,7 +26,11 @@

Your new account

Via your email address <%= email %>, - this server lets you log in to Solid apps + <% if (authenticating) { %> + you can now log in + <% } else { %> + this server lets you log in to Solid apps + <% } %> with your WebID <%= webId %>

<% if (!createWebId) { %> diff --git a/test/unit/identity/IdentityProviderHttpHandler.test.ts b/test/unit/identity/IdentityProviderHttpHandler.test.ts index 45f12c7e2..a3f3be418 100644 --- a/test/unit/identity/IdentityProviderHttpHandler.test.ts +++ b/test/unit/identity/IdentityProviderHttpHandler.test.ts @@ -83,9 +83,9 @@ describe('An IdentityProviderHttpHandler', (): void => { request.url = '/idp/routeResponse'; await expect(handler.handle({ request, response })).resolves.toBeUndefined(); expect(templateHandler.handleSafe).toHaveBeenCalledTimes(1); - expect(templateHandler.handleSafe).toHaveBeenLastCalledWith( - { response, templateFile: routes.response.viewTemplate, contents: { errorMessage: '', prefilled: {}}}, - ); + expect(templateHandler.handleSafe).toHaveBeenLastCalledWith({ response, + templateFile: routes.response.viewTemplate, + contents: { errorMessage: '', prefilled: {}, authenticating: false }}); }); it('calls the templateHandler for InteractionResponseResults.', async(): Promise => { @@ -96,20 +96,22 @@ describe('An IdentityProviderHttpHandler', (): void => { expect(routes.response.handler.handleSafe).toHaveBeenLastCalledWith({ request }); expect(templateHandler.handleSafe).toHaveBeenCalledTimes(1); expect(templateHandler.handleSafe).toHaveBeenLastCalledWith( - { response, templateFile: routes.response.responseTemplate, contents: { key: 'val' }}, + { response, templateFile: routes.response.responseTemplate, contents: { key: 'val', authenticating: false }}, ); }); - it('supports InteractionResponseResults without details.', async(): Promise => { + it('indicates to the templates if the request is part of an auth flow.', async(): Promise => { request.url = '/idp/routeResponse'; request.method = 'POST'; + const oidcInteraction = { session: { accountId: 'account' }} as any; + provider.interactionDetails.mockResolvedValueOnce(oidcInteraction); (routes.response.handler as jest.Mocked).handleSafe.mockResolvedValueOnce({ type: 'response' }); await expect(handler.handle({ request, response })).resolves.toBeUndefined(); expect(routes.response.handler.handleSafe).toHaveBeenCalledTimes(1); - expect(routes.response.handler.handleSafe).toHaveBeenLastCalledWith({ request }); + expect(routes.response.handler.handleSafe).toHaveBeenLastCalledWith({ request, oidcInteraction }); expect(templateHandler.handleSafe).toHaveBeenCalledTimes(1); expect(templateHandler.handleSafe).toHaveBeenLastCalledWith( - { response, templateFile: routes.response.responseTemplate, contents: {}}, + { response, templateFile: routes.response.responseTemplate, contents: { authenticating: true }}, ); }); @@ -175,7 +177,8 @@ describe('An IdentityProviderHttpHandler', (): void => { expect(templateHandler.handleSafe).toHaveBeenLastCalledWith({ response, templateFile: routes.response.viewTemplate, - contents: { errorMessage: 'handle error', prefilled: { name: 'name' }}, + contents: { errorMessage: 'handle error', prefilled: { name: 'name' }, authenticating: false }, + }); }); @@ -188,7 +191,7 @@ describe('An IdentityProviderHttpHandler', (): void => { expect(templateHandler.handleSafe).toHaveBeenLastCalledWith({ response, templateFile: routes.response.viewTemplate, - contents: { errorMessage: 'handle error', prefilled: { }}, + contents: { errorMessage: 'handle error', prefilled: {}, authenticating: false }, }); });