separate the default modal with the disable modal

This commit is contained in:
Jacob Overgaard
2024-03-26 16:21:53 +01:00
parent 76c8b2016f
commit 5ff0892697
2 changed files with 130 additions and 29 deletions

View File

@@ -10,7 +10,6 @@ import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
/**
* A default MFA provider configuration element.
* @element umb-mfa-provider-default
* @slot description - The description of the action that is about to be taken.
*/
@customElement('umb-mfa-provider-default')
export class UmbMfaProviderDefaultElement extends UmbLitElement implements UmbMfaProviderConfigurationElementProps {
@@ -23,12 +22,6 @@ export class UmbMfaProviderDefaultElement extends UmbLitElement implements UmbMf
@property({ attribute: false })
close = () => {};
@property({ attribute: 'success-message' })
successMessage = 'This two-factor provider is enabled';
@property({ attribute: 'success-message' })
successMessageKey = 'user_2faProviderIsEnabled';
@state()
protected _loading = true;
@@ -96,7 +89,11 @@ export class UmbMfaProviderDefaultElement extends UmbLitElement implements UmbMf
<div id="main">
<uui-box .headline=${this.localize.term('member_2fa')}>
<div class="text-center">
<slot name="description"></slot>
<p>
<umb-localize key="user_2faQrCodeDescription">
Scan this QR code with your authenticator app to enable two-factor authentication
</umb-localize>
</p>
<img
.src=${this._qrCodeSetupImageUrl}
alt=${this.localize.term('user_2faQrCodeAlt')}
@@ -175,8 +172,7 @@ export class UmbMfaProviderDefaultElement extends UmbLitElement implements UmbMf
const successful = await this.callback(this.providerName, code, this._secret);
if (successful) {
const message = this.localize.term(this.successMessageKey) || this.successMessage;
this.peek(message);
this.peek(this.localize.term('user_2faProviderIsEnabled'));
this._buttonState = 'success';
this.close();
} else {

View File

@@ -1,9 +1,10 @@
import { UmbCurrentUserRepository } from '../../repository/index.js';
import type { UmbCurrentUserMfaDisableProviderModalConfig } from './current-user-mfa-disable-provider-modal.token.js';
import { customElement, html } from '@umbraco-cms/backoffice/external/lit';
import { UMB_NOTIFICATION_CONTEXT, type UmbNotificationColor } from '@umbraco-cms/backoffice/notification';
import { css, customElement, html, query, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
import '../../components/mfa-provider-default.element.js';
import type { UUIButtonState } from '@umbraco-cms/backoffice/external/uui';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@customElement('umb-current-user-mfa-disable-provider-modal')
export class UmbCurrentUserMfaDisableProviderModalElement extends UmbModalBaseElement<
@@ -11,6 +12,20 @@ export class UmbCurrentUserMfaDisableProviderModalElement extends UmbModalBaseEl
never
> {
#currentUserRepository = new UmbCurrentUserRepository(this);
#notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE;
@state()
_buttonState?: UUIButtonState;
@query('#code')
_codeInput!: HTMLInputElement;
constructor() {
super();
this.consumeContext(UMB_NOTIFICATION_CONTEXT, (context) => {
this.#notificationContext = context;
});
}
render() {
if (!this.data) {
@@ -18,25 +33,115 @@ export class UmbCurrentUserMfaDisableProviderModalElement extends UmbModalBaseEl
}
return html`
<umb-mfa-provider-default
.providerName=${this.data.providerName}
.callback=${this.#disableProvider}
.close=${() => this.modalContext?.submit()}
success-message="This two-factor provider is now disabled"
success-message-key="user_2faProviderIsDisabledMsg">
<p slot="description">
<umb-localize key="user_2faDisableText">
If you wish to disable this two-factor provider, then you must enter the code shown on your authentication
device:
</umb-localize>
</p>
</umb-mfa-provider-default>
<uui-form>
<form id="authForm" name="authForm" @submit=${this.#onSubmit} novalidate>
<umb-body-layout headline=${this.data.providerName}>
<div id="main">
<p>
<umb-localize key="user_2faDisableText">
If you wish to disable this two-factor provider, then you must enter the code shown on your
authentication device:
</umb-localize>
</p>
<uui-form-layout-item class="text-center">
<uui-label for="code" slot="label" required>
<umb-localize key="user_2faCodeInput"></umb-localize>
</uui-label>
<uui-input
id="code"
name="code"
type="text"
inputmode="numeric"
autocomplete="one-time-code"
required
required-message=${this.localize.term('general_required')}
label=${this.localize.term('user_2faCodeInputHelp')}
placeholder=${this.localize.term('user_2faCodeInputHelp')}></uui-input>
</uui-form-layout-item>
</div>
<div slot="actions">
<uui-button
type="button"
look="secondary"
.label=${this.localize.term('general_close')}
@click=${this.#close}>
${this.localize.term('general_close')}
</uui-button>
<uui-button
.state=${this._buttonState}
type="submit"
look="primary"
.label=${this.localize.term('buttons_save')}>
${this.localize.term('general_submit')}
</uui-button>
</div>
</umb-body-layout>
</form>
</uui-form>
`;
}
#disableProvider = (providerName: string, code: string): Promise<boolean> => {
return this.#currentUserRepository.disableMfaProvider(providerName, code);
};
async #onSubmit(e: SubmitEvent) {
e.preventDefault();
this._codeInput.setCustomValidity('');
if (!this.data) throw new Error('No data provided');
const form = e.target as HTMLFormElement;
if (!form.checkValidity()) return;
const formData = new FormData(form);
const code = formData.get('code') as string;
if (!code) return;
this._buttonState = 'waiting';
const success = await this.#currentUserRepository.disableMfaProvider(this.data.providerName, code);
if (success) {
this.#peek(this.localize.term('user_2faProviderIsDisabledMsg'));
this.modalContext?.submit();
this._buttonState = 'success';
} else {
this._codeInput.setCustomValidity(this.localize.term('user_2faInvalidCode'));
this._codeInput.focus();
this._buttonState = 'failed';
}
}
async #close() {
this.modalContext?.submit();
}
async #peek(message: string, color?: UmbNotificationColor) {
this.#notificationContext?.peek(color ?? 'positive', {
data: {
headline: this.localize.term('member_2fa'),
message,
},
});
}
static styles = [
UmbTextStyles,
css`
#authForm {
height: 100%;
}
#code {
width: 100%;
max-width: 300px;
}
.text-center {
text-align: center;
}
`,
];
}
export default UmbCurrentUserMfaDisableProviderModalElement;