From 76c8b2016fc75b5803e0585c279d07328e8d2f2b Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:07:59 +0100 Subject: [PATCH] merge server and manifest models --- .../src/mocks/handlers/manifests.handlers.ts | 3 -- .../models/mfa-login-provider.model.ts | 3 +- ...-user-mfa-enable-provider-modal.element.ts | 3 +- .../current-user-mfa-modal.element.ts | 41 +++++++++++++++---- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/manifests.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/manifests.handlers.ts index 56de1f81c9..f4faf21546 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/manifests.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/manifests.handlers.ts @@ -84,9 +84,6 @@ export const manifestDevelopmentHandler = rest.get(umbracoPath('/package/manifes alias: 'My.MfaLoginProvider.Custom', name: 'My Custom MFA Provider', forProviderNames: ['email', 'sms'], - meta: { - label: 'My Custom MFA Provider', - }, }, ], }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/mfa-login-provider.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/mfa-login-provider.model.ts index 460260ccfc..98fcfb0962 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/mfa-login-provider.model.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/mfa-login-provider.model.ts @@ -5,8 +5,9 @@ export interface ManifestMfaLoginProvider extends ManifestElement { /** * The provider names that this provider is for. + * @examples 'Umbraco.GoogleAuthenticator' */ - forProviderNames?: Array; + forProviderName: string; meta?: MetaMfaLoginProvider; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa-enable-provider/current-user-mfa-enable-provider-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa-enable-provider/current-user-mfa-enable-provider-modal.element.ts index 27d22d9867..001b6226e3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa-enable-provider/current-user-mfa-enable-provider-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa-enable-provider/current-user-mfa-enable-provider-modal.element.ts @@ -43,8 +43,7 @@ export class UmbCurrentUserMfaEnableProviderModalElement extends UmbModalBaseEle #extensionSlotFilter = (manifest: ManifestMfaLoginProvider): boolean => { if (!this.data) return false; - const providerName = this.data.providerName.toLowerCase(); - return !manifest.forProviderNames || manifest.forProviderNames.includes(providerName); + return manifest.forProviderName.toLowerCase() === this.data.providerName.toLowerCase(); }; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa/current-user-mfa-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa/current-user-mfa-modal.element.ts index cfde55626d..40c57d8d4a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa/current-user-mfa-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/current-user/modals/current-user-mfa/current-user-mfa-modal.element.ts @@ -6,6 +6,12 @@ import { css, customElement, html, property, repeat, state, when } from '@umbrac import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_MODAL_MANAGER_CONTEXT, type UmbModalContext } from '@umbraco-cms/backoffice/modal'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { mergeObservables } from '@umbraco-cms/backoffice/observable-api'; + +type UmbMfaLoginProviderOption = UmbCurrentUserMfaProviderModel & { + displayName: string; +}; @customElement('umb-current-user-mfa-modal') export class UmbCurrentUserMfaModalElement extends UmbLitElement { @@ -13,7 +19,7 @@ export class UmbCurrentUserMfaModalElement extends UmbLitElement { modalContext?: UmbModalContext; @state() - _items: Array = []; + _items: Array = []; #currentUserRepository = new UmbCurrentUserRepository(this); @@ -23,12 +29,33 @@ export class UmbCurrentUserMfaModalElement extends UmbLitElement { } async #loadProviders() { + const serverLoginProviders$ = await this.#currentUserRepository.requestMfaLoginProviders(); + const manifestLoginProviders$ = umbExtensionsRegistry.byType('mfaLoginProvider'); + + // Merge the server and manifest providers to get the final list of providers + const mfaLoginProviders$ = mergeObservables( + [serverLoginProviders$, manifestLoginProviders$], + ([serverLoginProviders, manifestLoginProviders]) => { + return manifestLoginProviders.map((manifestLoginProvider) => { + const serverLoginProvider = serverLoginProviders.find( + (serverLoginProvider) => serverLoginProvider.providerName === manifestLoginProvider.forProviderName, + ); + return { + isEnabledOnUser: serverLoginProvider?.isEnabledOnUser ?? false, + providerName: serverLoginProvider?.providerName ?? manifestLoginProvider.forProviderName, + displayName: + manifestLoginProvider.meta?.label ?? serverLoginProvider?.providerName ?? manifestLoginProvider.name, + } satisfies UmbMfaLoginProviderOption; + }); + }, + ); + this.observe( - await this.#currentUserRepository.requestMfaLoginProviders(), + mfaLoginProviders$, (providers) => { this._items = providers; }, - '_mfaProviders', + '_mfaLoginProviders', ); } @@ -63,9 +90,9 @@ export class UmbCurrentUserMfaModalElement extends UmbLitElement { /** * Render a provider with a toggle to enable/disable it */ - #renderProvider(item: UmbCurrentUserMfaProviderModel) { + #renderProvider(item: UmbMfaLoginProviderOption) { return html` - + ${when( item.isEnabledOnUser, () => html` @@ -97,7 +124,7 @@ export class UmbCurrentUserMfaModalElement extends UmbLitElement { * This will show the QR code and/or other means of validation for the given provider and return the activation code. * The activation code is then used to either enable the provider. */ - async #onProviderEnable(item: UmbCurrentUserMfaProviderModel) { + async #onProviderEnable(item: UmbMfaLoginProviderOption) { const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); await modalManager .open(this, UMB_CURRENT_USER_MFA_ENABLE_PROVIDER_MODAL, { @@ -112,7 +139,7 @@ export class UmbCurrentUserMfaModalElement extends UmbLitElement { * This will show the QR code and/or other means of validation for the given provider and return the activation code. * The activation code is then used to disable the provider. */ - async #onProviderDisable(item: UmbCurrentUserMfaProviderModel) { + async #onProviderDisable(item: UmbMfaLoginProviderOption) { const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); await modalManager .open(this, UMB_CURRENT_USER_MFA_DISABLE_PROVIDER_MODAL, {