From 47b3a2d77f4a5b3fa5bab364ac19dc32d79a89c1 Mon Sep 17 00:00:00 2001 From: Joachim Van Herwegen Date: Tue, 17 Aug 2021 15:55:03 +0200 Subject: [PATCH] fix: Allow clients to be remembered in the SessionHttpHandler --- src/identity/interaction/SessionHttpHandler.ts | 7 +++++-- .../identity/email-password/confirm.html.ejs | 15 ++++++++++++++- .../email-password/forgot-password.html.ejs | 2 +- templates/identity/email-password/login.html.ejs | 2 +- .../email-password/reset-password.html.ejs | 2 +- test/integration/Identity.test.ts | 3 +-- .../interaction/SessionHttpHandler.test.ts | 10 +++++----- 7 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/identity/interaction/SessionHttpHandler.ts b/src/identity/interaction/SessionHttpHandler.ts index 7980ea2ee..d049b8bf6 100644 --- a/src/identity/interaction/SessionHttpHandler.ts +++ b/src/identity/interaction/SessionHttpHandler.ts @@ -1,18 +1,21 @@ import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpError'; import { InteractionHandler } from './email-password/handler/InteractionHandler'; import type { InteractionCompleteResult, InteractionHandlerInput } from './email-password/handler/InteractionHandler'; +import { getFormDataRequestBody } from './util/FormDataUtil'; /** * Simple InteractionHttpHandler that sends the session accountId to the InteractionCompleter as webId. */ export class SessionHttpHandler extends InteractionHandler { - public async handle({ oidcInteraction }: InteractionHandlerInput): Promise { + public async handle({ request, oidcInteraction }: InteractionHandlerInput): Promise { if (!oidcInteraction?.session) { throw new NotImplementedHttpError('Only interactions with a valid session are supported.'); } + + const { remember } = await getFormDataRequestBody(request); return { type: 'complete', - details: { webId: oidcInteraction.session.accountId }, + details: { webId: oidcInteraction.session.accountId, shouldRemember: Boolean(remember) }, }; } } diff --git a/templates/identity/email-password/confirm.html.ejs b/templates/identity/email-password/confirm.html.ejs index 8d8617afe..adb56e929 100644 --- a/templates/identity/email-password/confirm.html.ejs +++ b/templates/identity/email-password/confirm.html.ejs @@ -1,4 +1,17 @@

Authorize

+

You are authorizing an application to access your Pod.

-

+ <% if (errorMessage) { %> +

<%= errorMessage %>

+ <% } %> + +
+
    +
  1. + +
  2. +
+
+ +

diff --git a/templates/identity/email-password/forgot-password.html.ejs b/templates/identity/email-password/forgot-password.html.ejs index c21282de3..91a5c357f 100644 --- a/templates/identity/email-password/forgot-password.html.ejs +++ b/templates/identity/email-password/forgot-password.html.ejs @@ -1,6 +1,6 @@

Forgot password

- <%if (errorMessage) { %> + <% if (errorMessage) { %>

<%= errorMessage %>

<% } %> diff --git a/templates/identity/email-password/login.html.ejs b/templates/identity/email-password/login.html.ejs index 16752f15d..a1b8174a5 100644 --- a/templates/identity/email-password/login.html.ejs +++ b/templates/identity/email-password/login.html.ejs @@ -1,6 +1,6 @@

Log in

- <%if (errorMessage) { %> + <% if (errorMessage) { %>

<%= errorMessage %>

<% } %> diff --git a/templates/identity/email-password/reset-password.html.ejs b/templates/identity/email-password/reset-password.html.ejs index 53daac5dc..0fb1d5a69 100644 --- a/templates/identity/email-password/reset-password.html.ejs +++ b/templates/identity/email-password/reset-password.html.ejs @@ -1,6 +1,6 @@

Reset password

- <%if (errorMessage) { %> + <% if (errorMessage) { %>

<%= errorMessage %>

<% } %> diff --git a/test/integration/Identity.test.ts b/test/integration/Identity.test.ts index 9d758f532..3e6da6405 100644 --- a/test/integration/Identity.test.ts +++ b/test/integration/Identity.test.ts @@ -168,11 +168,10 @@ describe('A Solid server with IDP', (): void => { it('can log in again.', async(): Promise => { const url = await state.startSession(); - // For the following part it is debatable if this is correct but this might be a consequence of the authn client const form = await state.extractFormUrl(url); expect(form.url.endsWith('/confirm')).toBe(true); - const res = await state.fetchIdp(form.url, 'POST'); + const res = await state.fetchIdp(form.url, 'POST', '', APPLICATION_X_WWW_FORM_URLENCODED); const nextUrl = res.headers.get('location'); expect(typeof nextUrl).toBe('string'); diff --git a/test/unit/identity/interaction/SessionHttpHandler.test.ts b/test/unit/identity/interaction/SessionHttpHandler.test.ts index 41b300205..5696b849c 100644 --- a/test/unit/identity/interaction/SessionHttpHandler.test.ts +++ b/test/unit/identity/interaction/SessionHttpHandler.test.ts @@ -1,10 +1,9 @@ import type { Interaction } from '../../../../src/identity/interaction/email-password/handler/InteractionHandler'; import { SessionHttpHandler } from '../../../../src/identity/interaction/SessionHttpHandler'; -import type { HttpRequest } from '../../../../src/server/HttpRequest'; import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError'; +import { createPostFormRequest } from './email-password/handler/Util'; describe('A SessionHttpHandler', (): void => { - const request: HttpRequest = {} as any; const webId = 'http://test.com/id#me'; let oidcInteraction: Interaction; let handler: SessionHttpHandler; @@ -17,14 +16,15 @@ describe('A SessionHttpHandler', (): void => { it('requires a defined oidcInteraction with a session.', async(): Promise => { oidcInteraction!.session = undefined; - await expect(handler.handle({ request, oidcInteraction })).rejects.toThrow(NotImplementedHttpError); + await expect(handler.handle({ request: {} as any, oidcInteraction })).rejects.toThrow(NotImplementedHttpError); - await expect(handler.handle({ request })).rejects.toThrow(NotImplementedHttpError); + await expect(handler.handle({ request: {} as any })).rejects.toThrow(NotImplementedHttpError); }); it('returns an InteractionCompleteResult when done.', async(): Promise => { + const request = createPostFormRequest({ remember: true }); await expect(handler.handle({ request, oidcInteraction })).resolves.toEqual({ - details: { webId }, + details: { webId, shouldRemember: true }, type: 'complete', }); });