From d261a3b247047af0ebe6422bfe5152edbf5f1044 Mon Sep 17 00:00:00 2001 From: Evert Pot Date: Thu, 9 Jan 2025 14:42:26 -0500 Subject: [PATCH] Expose the 'verify-response' action as a form on the identity resource. --- changelog.md | 3 +++ schemas/principal-identity-verify-response.json | 4 ++++ src/api-types.ts | 4 ++++ src/login/service.ts | 2 +- .../controller/verify-response.ts | 4 ++++ src/principal-identity/formats/hal.ts | 13 +++++++++++++ 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 5bcdab0a..50fddc71 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,9 @@ Changelog * Add a new privilege for managing user identities. Before this change it was required to have the 'admin' privilege to do this. +* Verify response endpoint is now exposed as a form on the identity resource. +* It's now possible to mark an identity as an MFA identity when verifying using + the 'enableMfa' property. 0.28.1 (2025-01-08) diff --git a/schemas/principal-identity-verify-response.json b/schemas/principal-identity-verify-response.json index b51cdb71..ecf44794 100644 --- a/schemas/principal-identity-verify-response.json +++ b/schemas/principal-identity-verify-response.json @@ -13,6 +13,10 @@ "type": "string", "description": "The verification code", "pattern": "^[0-9]{6}$" + }, + "enableMfa": { + "type": "boolean", + "description": "If verification was successful, turn on MFA for this identity." } } } diff --git a/src/api-types.ts b/src/api-types.ts index d62f210f..a116e585 100644 --- a/src/api-types.ts +++ b/src/api-types.ts @@ -310,6 +310,10 @@ export interface PrincipalIdentityVerifyForm { * The verification code */ code: string; + /** + * If verification was successful, turn on MFA for this identity. + */ + enableMfa?: boolean; } /* eslint-disable */ /** diff --git a/src/login/service.ts b/src/login/service.ts index bbe5d4a2..77e45e3a 100644 --- a/src/login/service.ts +++ b/src/login/service.ts @@ -123,7 +123,7 @@ export async function challenge(client: AppClient, session: LoginSession, parame const completedChallenges = new Set(session.challengesCompleted); - if (completedChallenges.size < 2 && challenges.length > 1) { + if ((completedChallenges.size < 2 && challenges.length > 1) || completedChallenges.size < 1) { // If there are 2 or more auth factors set up, we want at least 2 successful // passes. If this is not the case we're going to emit a challenge error. for(const challenge of challenges) { diff --git a/src/principal-identity/controller/verify-response.ts b/src/principal-identity/controller/verify-response.ts index d54638c5..0495b5ff 100644 --- a/src/principal-identity/controller/verify-response.ts +++ b/src/principal-identity/controller/verify-response.ts @@ -35,6 +35,10 @@ class PrincipalIdentityVerify extends Controller { try { await services.principalIdentity.verifyIdentity(identity, ctx.request.body.code); + if (ctx.request.body.enableMfa && !identity.isMfa) { + identity.isMfa = true; + await services.principalIdentity.update(identity); + } ctx.response.body = hal.verifySuccess(identity); } catch (err) { if (isHttpError(err)) { diff --git a/src/principal-identity/formats/hal.ts b/src/principal-identity/formats/hal.ts index d6c25db9..7741ac9c 100644 --- a/src/principal-identity/formats/hal.ts +++ b/src/principal-identity/formats/hal.ts @@ -70,6 +70,19 @@ export function item(principal: Principal, identity: PrincipalIdentity): HalReso method: 'POST', title: identity.verifiedAt ? 'Re-verify' : 'Verify', target: `${identity.href}/verify`, + }, + 'verify-response': { + method: 'POST', + title: 'Submit verification code', + target: `${identity.href}/verify-response`, + properties: [ + { + name: 'code', + type: 'text', + prompt: 'Code', + regex: '^[0-9]{6}$' + } + ], } }; if (identity.verifiedAt) {