web/flows: fix webauthn retry (#8599)
* web/flows: fix retry button on webauthn device stage Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web/flows: rework webauth register design to match Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -89,8 +89,8 @@ export class AuthenticatorValidateStageWebAuthn extends BaseDeviceStage<
|
||||
this.authenticating = true;
|
||||
this.authenticate()
|
||||
.catch((e: Error) => {
|
||||
console.warn(`authentik/flows/authenticator_validate/webauthn: ${e.toString()}`);
|
||||
this.errorMessage = msg("Authentication failed.");
|
||||
console.warn("authentik/flows/authenticator_validate/webauthn: failed to auth", e);
|
||||
this.errorMessage = msg("Authentication failed. Please try again.");
|
||||
})
|
||||
.finally(() => {
|
||||
this.authenticating = false;
|
||||
@ -110,12 +110,13 @@ export class AuthenticatorValidateStageWebAuthn extends BaseDeviceStage<
|
||||
>
|
||||
</ak-empty-state>
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
${this.errorMessage
|
||||
${!this.authenticating
|
||||
? html` <button
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
this.authenticateWrapper();
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
${msg("Retry authentication")}
|
||||
</button>`
|
||||
|
@ -4,11 +4,11 @@ import {
|
||||
transformCredentialCreateOptions,
|
||||
transformNewAssertionForServer,
|
||||
} from "@goauthentik/common/helpers/webauthn";
|
||||
import { PFSize } from "@goauthentik/elements/Spinner";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
@ -41,7 +41,24 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
|
||||
publicKeyCredentialCreateOptions?: PublicKeyCredentialCreationOptions;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFBase, PFLogin, PFFormControl, PFForm, PFTitle, PFButton];
|
||||
return [
|
||||
PFBase,
|
||||
PFLogin,
|
||||
PFFormControl,
|
||||
PFForm,
|
||||
PFTitle,
|
||||
PFButton,
|
||||
// FIXME: this is technically duplicate with ../authenticator_validate/base.ts
|
||||
css`
|
||||
.pf-c-form__group.pf-m-action {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-top: 0;
|
||||
margin-bottom: calc(var(--pf-c-form__group--m-action--MarginTop) / 2);
|
||||
flex-direction: column;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
async register(): Promise<void> {
|
||||
@ -69,9 +86,14 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
|
||||
// post the transformed credential data to the server for validation
|
||||
// and storing the public key
|
||||
try {
|
||||
await this.host?.submit({
|
||||
response: newAssertionForServer,
|
||||
});
|
||||
await this.host?.submit(
|
||||
{
|
||||
response: newAssertionForServer,
|
||||
},
|
||||
{
|
||||
invisible: true,
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
throw new Error(msg(str`Server validation of credential failed: ${err}`));
|
||||
}
|
||||
@ -84,8 +106,8 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
|
||||
this.registerRunning = true;
|
||||
this.register()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
this.registerMessage = e.toString();
|
||||
console.warn("authentik/flows/authenticator_webauthn: failed to register", e);
|
||||
this.registerMessage = msg("Failed to register. Please try again.");
|
||||
})
|
||||
.finally(() => {
|
||||
this.registerRunning = false;
|
||||
@ -104,42 +126,37 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">
|
||||
${this.challenge?.flowInfo?.title}
|
||||
</h1>
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge?.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
${
|
||||
this.registerRunning
|
||||
? html`<div class="pf-c-empty-state__content">
|
||||
<div class="pf-l-bullseye">
|
||||
<div class="pf-l-bullseye__item">
|
||||
<ak-spinner size="${PFSize.XLarge}"></ak-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
: html` <div class="pf-c-form__group pf-m-action">
|
||||
${this.challenge?.responseErrors
|
||||
? html`<p class="pf-m-block">
|
||||
${this.challenge.responseErrors["response"][0].string}
|
||||
</p>`
|
||||
: html``}
|
||||
<p class="pf-m-block">${this.registerMessage}</p>
|
||||
<button
|
||||
<form class="pf-c-form">
|
||||
<ak-empty-state
|
||||
?loading="${this.registerRunning}"
|
||||
header=${this.registerRunning
|
||||
? msg("Registering...")
|
||||
: this.registerMessage || msg("Failed to register")}
|
||||
icon="fa-times"
|
||||
>
|
||||
</ak-empty-state>
|
||||
${this.challenge?.responseErrors
|
||||
? html`<p class="pf-m-block">
|
||||
${this.challenge.responseErrors["response"][0].string}
|
||||
</p>`
|
||||
: html``}
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
${!this.registerRunning
|
||||
? html` <button
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
this.registerWrapper();
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
${msg("Register device")}
|
||||
</button>
|
||||
</div>`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links">
|
||||
</ul>
|
||||
</footer>`;
|
||||
${msg("Retry registration")}
|
||||
</button>`
|
||||
: nothing}
|
||||
</div>
|
||||
</form>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user