add handlers to get configuration of a mfa provider

This commit is contained in:
Jacob Overgaard
2024-03-26 10:11:56 +01:00
parent 2a5fa7ff03
commit 4c3a16774d
2 changed files with 116 additions and 12 deletions

View File

@@ -12,6 +12,27 @@ export const handlers = [
const mfaLoginProviders = umbUserMockDb.getMfaLoginProviders();
return res(ctx.status(200), ctx.json(mfaLoginProviders));
}),
rest.get(umbracoPath(`${UMB_SLUG}/current/2fa/:providerName`), (req, res, ctx) => {
if (!req.params.providerName) {
return res(ctx.status(400));
}
const mfaProviders = umbUserMockDb.getMfaLoginProviders();
const mfaProvider = mfaProviders.find((p) => p.providerName === req.params.providerName.toString());
if (!mfaProvider) {
return res(ctx.status(404));
}
return res(
ctx.status(200),
ctx.json({
$type: 'TwoFactorAuthInfo',
qrCodeSetupImageUrl: 'https://placekitten.com/200/200',
secret: '8b713fc7-8f17-4f5d-b2ac-b53879c75953',
}),
);
}),
rest.post<{ code: string; secret: string }>(
umbracoPath(`${UMB_SLUG}/current/2fa/:providerName`),
async (req, res, ctx) => {

View File

@@ -1,6 +1,10 @@
import type { UmbMfaProviderConfigurationElementProps } from '../types.js';
import { customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
import { UserResource } from '@umbraco-cms/backoffice/external/backend-api';
import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@customElement('umb-mfa-provider-default')
export class UmbMfaProviderDefaultElement extends UmbLitElement implements UmbMfaProviderConfigurationElementProps {
@@ -16,24 +20,103 @@ export class UmbMfaProviderDefaultElement extends UmbLitElement implements UmbMf
@property({ attribute: false })
onClose = () => {};
@state()
_loading = true;
@state()
_secret = '';
@state()
_qrCodeSetupImageUrl = '';
#notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE;
constructor() {
super();
this.consumeContext(UMB_NOTIFICATION_CONTEXT, (context) => {
this.#notificationContext = context;
});
}
async firstUpdated() {
await this.#load();
this._loading = false;
}
async #load() {
if (!this.providerName) {
this.#peek('Provider name is required');
throw new Error('Provider name is required');
}
const { data } = await tryExecuteAndNotify(
this,
UserResource.getUserCurrent2FaByProviderName({ providerName: this.providerName }),
);
if (!data) {
this.#peek('No data returned');
throw new Error('No data returned');
}
// Verify that there is a secret
if (!data.secret) {
this.#peek('The provider did not return a secret.');
throw new Error('No secret returned');
}
this._secret = data.secret;
this._qrCodeSetupImageUrl = data.qrCodeSetupImageUrl;
}
render() {
if (this._loading) {
return html`<uui-loader-bar></uui-loader-bar>`;
}
return html`
<umb-body-layout headline=${this.providerName}>
<div slot="actions">
<uui-button look="secondary" .label=${this.localize.term('general_close')} @click=${this.onClose}>
${this.localize.term('general_close')}
</uui-button>
<uui-button look="primary" .label=${this.localize.term('general_submit')} @click=${this.#onSubmit}>
${this.localize.term('general_submit')}
</uui-button>
</div>
</umb-body-layout>
<form id="authForm" name="authForm" @submit=${this.#onSubmit}>
<umb-body-layout headline=${this.providerName}>
<div id="main"></div>
<div slot="actions">
<uui-button
type="button"
look="secondary"
.label=${this.localize.term('general_close')}
@click=${this.onClose}>
${this.localize.term('general_close')}
</uui-button>
<uui-button type="submit" look="primary" .label=${this.localize.term('buttons_save')}>
${this.localize.term('general_submit')}
</uui-button>
</div>
</umb-body-layout>
</form>
`;
}
#onSubmit() {
#peek(message: string) {
this.#notificationContext?.peek('danger', {
data: {
headline: this.localize.term('member_2fa'),
message,
},
});
}
#onSubmit(e: SubmitEvent) {
e.preventDefault();
this.onSubmit({ code: '123456', secret: '123' });
}
static styles = [
UmbTextStyles,
css`
#authForm {
height: 100%;
}
`,
];
}
export default UmbMfaProviderDefaultElement;