mirror of
https://github.com/goauthentik/authentik.git
synced 2026-06-17 19:09:11 +03:00
web/flows: fix bottom padding when loading challenge (#15372)
* web/flows: fix bottom padding when loading challenge Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add base class that does layout for login cards Signed-off-by: Jens Langhammer <jens@goauthentik.io> * ok actually rework the whole thing Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix leftover div Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix other stages Signed-off-by: Jens Langhammer <jens@goauthentik.io> * better declare loading state Signed-off-by: Jens Langhammer <jens@goauthentik.io> * format Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@@ -118,7 +118,8 @@ class TestProviderProxy(SeleniumTestCase):
|
||||
sleep(2)
|
||||
flow_executor = self.get_shadow_root("ak-flow-executor")
|
||||
session_end_stage = self.get_shadow_root("ak-stage-session-end", flow_executor)
|
||||
title = session_end_stage.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
flow_card = self.get_shadow_root("ak-flow-card", session_end_stage)
|
||||
title = flow_card.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
self.assertIn("You've logged out of", title)
|
||||
|
||||
@retry()
|
||||
@@ -195,7 +196,8 @@ class TestProviderProxy(SeleniumTestCase):
|
||||
sleep(2)
|
||||
flow_executor = self.get_shadow_root("ak-flow-executor")
|
||||
session_end_stage = self.get_shadow_root("ak-stage-session-end", flow_executor)
|
||||
title = session_end_stage.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
flow_card = self.get_shadow_root("ak-flow-card", session_end_stage)
|
||||
title = flow_card.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
self.assertIn("You've logged out of", title)
|
||||
|
||||
|
||||
|
||||
@@ -121,7 +121,8 @@ class TestProviderProxyForward(SeleniumTestCase):
|
||||
sleep(2)
|
||||
flow_executor = self.get_shadow_root("ak-flow-executor")
|
||||
session_end_stage = self.get_shadow_root("ak-stage-session-end", flow_executor)
|
||||
title = session_end_stage.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
flow_card = self.get_shadow_root("ak-flow-card", session_end_stage)
|
||||
title = flow_card.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
self.assertIn("You've logged out of", title)
|
||||
|
||||
@skip("Flaky test")
|
||||
@@ -156,7 +157,8 @@ class TestProviderProxyForward(SeleniumTestCase):
|
||||
sleep(2)
|
||||
flow_executor = self.get_shadow_root("ak-flow-executor")
|
||||
session_end_stage = self.get_shadow_root("ak-stage-session-end", flow_executor)
|
||||
title = session_end_stage.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
flow_card = self.get_shadow_root("ak-flow-card", session_end_stage)
|
||||
title = flow_card.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
self.assertIn("You've logged out of", title)
|
||||
|
||||
@retry()
|
||||
@@ -189,7 +191,8 @@ class TestProviderProxyForward(SeleniumTestCase):
|
||||
sleep(2)
|
||||
flow_executor = self.get_shadow_root("ak-flow-executor")
|
||||
session_end_stage = self.get_shadow_root("ak-stage-session-end", flow_executor)
|
||||
title = session_end_stage.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
flow_card = self.get_shadow_root("ak-flow-card", session_end_stage)
|
||||
title = flow_card.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
self.assertIn("You've logged out of", title)
|
||||
|
||||
@retry()
|
||||
@@ -225,5 +228,6 @@ class TestProviderProxyForward(SeleniumTestCase):
|
||||
sleep(2)
|
||||
flow_executor = self.get_shadow_root("ak-flow-executor")
|
||||
session_end_stage = self.get_shadow_root("ak-stage-session-end", flow_executor)
|
||||
title = session_end_stage.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
flow_card = self.get_shadow_root("ak-flow-card", session_end_stage)
|
||||
title = flow_card.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text
|
||||
self.assertIn("You've logged out of", title)
|
||||
|
||||
@@ -10,6 +10,7 @@ import { WithBrandConfig } from "#elements/mixins/branding";
|
||||
import { WithCapabilitiesConfig } from "#elements/mixins/capabilities";
|
||||
import { themeImage } from "#elements/utils/images";
|
||||
import "#flow/components/ak-brand-footer";
|
||||
import "#flow/components/ak-flow-card";
|
||||
import "#flow/sources/apple/AppleLoginInit";
|
||||
import "#flow/sources/plex/PlexLoginInit";
|
||||
import "#flow/stages/FlowErrorStage";
|
||||
@@ -304,7 +305,7 @@ export class FlowExecutor
|
||||
|
||||
async renderChallenge(): Promise<TemplateResult> {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading default-label> </ak-empty-state>`;
|
||||
return html`<ak-flow-card loading></ak-flow-card>`;
|
||||
}
|
||||
switch (this.challenge?.component) {
|
||||
case "ak-stage-access-denied":
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
pluckErrorDetail,
|
||||
} from "@goauthentik/common/errors/network";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/Expand";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import { AKElement } from "#elements/Base";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
|
||||
import { CSSResult, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
|
||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import { ChallengeTypes } from "@goauthentik/api";
|
||||
|
||||
/**
|
||||
* @element ak-flow-card
|
||||
* @class FlowCard
|
||||
* @slot title - Title of the card, optional, when not set uses the flow title
|
||||
* @slot - Main body of the card
|
||||
* @slot footer - Footer links, optional
|
||||
* @slot footer-band - Band in the footer, option
|
||||
*
|
||||
*/
|
||||
@customElement("ak-flow-card")
|
||||
export class FlowCard extends AKElement {
|
||||
@property({ type: Object })
|
||||
challenge?: ChallengeTypes;
|
||||
|
||||
@property({ type: Boolean })
|
||||
loading = false;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
PFBase,
|
||||
PFLogin,
|
||||
PFTitle,
|
||||
css`
|
||||
/* login page's icons */
|
||||
.pf-c-login__main-footer-links-item button {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
.pf-c-login__main-footer-links-item img {
|
||||
fill: var(--pf-c-login__main-footer-links-item-link-svg--Fill);
|
||||
width: 100px;
|
||||
max-width: var(--pf-c-login__main-footer-links-item-link-svg--Width);
|
||||
height: 100%;
|
||||
max-height: var(--pf-c-login__main-footer-links-item-link-svg--Height);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.challenge || this.loading) {
|
||||
return html`<ak-empty-state loading default-label></ak-empty-state>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
}
|
||||
// No title if the challenge doesn't provide a title and no custom title is set
|
||||
let title = undefined;
|
||||
if (this.hasSlotted("title")) {
|
||||
title = html`<h1 class="pf-c-title pf-m-3xl"><slot name="title"></slot></h1>`;
|
||||
} else if (this.challenge.flowInfo?.title) {
|
||||
title = html`<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo.title}</h1>`;
|
||||
}
|
||||
return html`${title
|
||||
? html`<header class="pf-c-login__main-header">${title}</header>`
|
||||
: nothing}
|
||||
<div class="pf-c-login__main-body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<slot name="footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</slot>
|
||||
<slot name="footer-band"></slot>
|
||||
</footer>`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ak-flow-card": FlowCard;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
@@ -23,13 +24,7 @@ export class SessionEnd extends BaseStage<SessionEndChallenge, unknown> {
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state default-label></ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
@@ -50,31 +45,32 @@ export class SessionEnd extends BaseStage<SessionEndChallenge, unknown> {
|
||||
<a href="${globalAK().api.base}" class="pf-c-button pf-m-primary">
|
||||
${msg("Go back to overview")}
|
||||
</a>
|
||||
${this.challenge.invalidationFlowUrl
|
||||
? html`
|
||||
<a
|
||||
href="${this.challenge.invalidationFlowUrl}"
|
||||
class="pf-c-button pf-m-secondary"
|
||||
id="logout"
|
||||
>
|
||||
${msg(str`Log out of ${this.challenge.brandName}`)}
|
||||
</a>
|
||||
`
|
||||
: nothing}
|
||||
${this.challenge.applicationLaunchUrl && this.challenge.applicationName
|
||||
? html`
|
||||
<a
|
||||
href="${this.challenge.applicationLaunchUrl}"
|
||||
class="pf-c-button pf-m-secondary"
|
||||
>
|
||||
${msg(str`Log back into ${this.challenge.applicationName}`)}
|
||||
</a>
|
||||
`
|
||||
: nothing}
|
||||
${
|
||||
this.challenge.invalidationFlowUrl
|
||||
? html`
|
||||
<a
|
||||
href="${this.challenge.invalidationFlowUrl}"
|
||||
class="pf-c-button pf-m-secondary"
|
||||
id="logout"
|
||||
>
|
||||
${msg(str`Log out of ${this.challenge.brandName}`)}
|
||||
</a>
|
||||
`
|
||||
: nothing
|
||||
}
|
||||
${
|
||||
this.challenge.applicationLaunchUrl && this.challenge.applicationName
|
||||
? html`
|
||||
<a
|
||||
href="${this.challenge.applicationLaunchUrl}"
|
||||
class="pf-c-button pf-m-secondary"
|
||||
>
|
||||
${msg(str`Log back into ${this.challenge.applicationName}`)}
|
||||
</a>
|
||||
`
|
||||
: nothing
|
||||
}
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</div></ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -29,13 +29,7 @@ export class OAuth2DeviceCode extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
@@ -70,9 +64,7 @@ export class OAuth2DeviceCode extends BaseStage<
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -14,13 +15,12 @@ export class DeviceCodeFinish extends BaseStage<
|
||||
OAuthDeviceCodeFinishChallenge
|
||||
> {
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<ak-empty-state icon="fas fa-check">
|
||||
<span>${msg("You may close this page now.")}</span>
|
||||
<span slot="body"> ${msg("You've successfully authenticated your device.")} </span>
|
||||
</ak-empty-state>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<ak-empty-state icon="fas fa-check">
|
||||
<span>${msg("You may close this page now.")}</span>
|
||||
<span slot="body"> ${msg("You've successfully authenticated your device.")} </span>
|
||||
</ak-empty-state>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
import { CSSResult, TemplateResult, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
@@ -52,27 +52,22 @@ export class AppleLoginInit extends BaseStage<AppleLoginChallenge, AppleChalleng
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${msg("Authenticating with Apple...")}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
<ak-empty-state loading></ak-empty-state>
|
||||
${!this.isModalShown
|
||||
? html`<button
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
AppleID.auth.signIn();
|
||||
}}
|
||||
>
|
||||
${msg("Retry")}
|
||||
</button>`
|
||||
: html``}
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<span slot="title">${msg("Authenticating with Apple...")}</span>
|
||||
<form class="pf-c-form">
|
||||
<ak-empty-state loading></ak-empty-state>
|
||||
${!this.isModalShown
|
||||
? html`<button
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
AppleID.auth.signIn();
|
||||
}}
|
||||
>
|
||||
${msg("Retry")}
|
||||
</button>`
|
||||
: nothing}
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { parseAPIResponseError } from "@goauthentik/common/errors/network";
|
||||
import { PlexAPIClient, popupCenterScreen } from "@goauthentik/common/helpers/plex";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import { showAPIErrorMessage } from "@goauthentik/elements/messages/MessageContainer";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -64,30 +66,25 @@ export class PlexLoginInit extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${msg("Authenticating with Plex...")}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
<ak-empty-state loading
|
||||
><span>${msg("Waiting for authentication...")}></span>
|
||||
</ak-empty-state>
|
||||
<hr class="pf-c-divider" />
|
||||
<p>${msg("If no Plex popup opens, click the button below.")}</p>
|
||||
<button
|
||||
class="pf-c-button pf-m-block pf-m-primary"
|
||||
type="button"
|
||||
@click=${() => {
|
||||
window.open(this.authUrl, "_blank");
|
||||
}}
|
||||
>
|
||||
${msg("Open login")}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<span slot="title">${msg("Authenticating with Plex...")}</span>
|
||||
<form class="pf-c-form">
|
||||
<ak-empty-state loading
|
||||
><span>${msg("Waiting for authentication...")}></span>
|
||||
</ak-empty-state>
|
||||
<hr class="pf-c-divider" />
|
||||
<p>${msg("If no Plex popup opens, click the button below.")}</p>
|
||||
<button
|
||||
class="pf-c-button pf-m-block pf-m-primary"
|
||||
type="button"
|
||||
@click=${() => {
|
||||
window.open(this.authUrl, "_blank");
|
||||
}}
|
||||
>
|
||||
${msg("Open login")}
|
||||
</button>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -37,39 +38,30 @@ export class FlowErrorStage extends BaseStage<FlowErrorChallenge, FlowChallengeR
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
<ak-empty-state icon="fa-times"
|
||||
><span>
|
||||
${this.challenge.error
|
||||
? this.challenge.error
|
||||
: msg("Something went wrong! Please try again later.")}</span
|
||||
>
|
||||
<div slot="body">
|
||||
${this.challenge?.traceback
|
||||
? html`<div class="pf-c-form__group">
|
||||
<pre class="ak-exception">${this.challenge.traceback}</pre>
|
||||
</div>`
|
||||
: nothing}
|
||||
${this.challenge?.requestId
|
||||
? html`<div class="pf-c-form__group">
|
||||
<p>${msg("Request ID")}</p>
|
||||
<code>${this.challenge.requestId}</code>
|
||||
</div>`
|
||||
: nothing}
|
||||
</div>
|
||||
</ak-empty-state>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form class="pf-c-form">
|
||||
<ak-empty-state icon="fa-times"
|
||||
><span>
|
||||
${this.challenge.error
|
||||
? this.challenge.error
|
||||
: msg("Something went wrong! Please try again later.")}</span
|
||||
>
|
||||
<div slot="body">
|
||||
${this.challenge?.traceback
|
||||
? html`<div class="pf-c-form__group">
|
||||
<pre class="ak-exception">${this.challenge.traceback}</pre>
|
||||
</div>`
|
||||
: nothing}
|
||||
${this.challenge?.requestId
|
||||
? html`<div class="pf-c-form__group">
|
||||
<p>${msg("Request ID")}</p>
|
||||
<code>${this.challenge.requestId}</code>
|
||||
</div>`
|
||||
: nothing}
|
||||
</div>
|
||||
</ak-empty-state>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
|
||||
@@ -20,30 +21,24 @@ export class FlowFrameStage extends BaseStage<FrameChallenge, FrameChallengeResp
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html` <header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
${this.challenge.loadingOverlay
|
||||
? html`<ak-empty-state loading
|
||||
>${this.challenge.loadingText
|
||||
? html`<span>${this.challenge.loadingText}}</span>`
|
||||
: nothing}
|
||||
</ak-empty-state>`
|
||||
: nothing}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
${
|
||||
this.challenge.loadingOverlay
|
||||
? html`<ak-empty-state loading
|
||||
>${this.challenge.loadingText
|
||||
? html`<span>${this.challenge.loadingText}}</span>`
|
||||
: nothing}
|
||||
</ak-empty-state>`
|
||||
: nothing
|
||||
}
|
||||
<iframe
|
||||
style=${this.challenge.loadingOverlay
|
||||
? "width:0;height:0;position:absolute;"
|
||||
: ""}
|
||||
style=${
|
||||
this.challenge.loadingOverlay ? "width:0;height:0;position:absolute;" : ""
|
||||
}
|
||||
src=${this.challenge.url}
|
||||
></iframe>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -69,43 +70,40 @@ export class RedirectStage extends BaseStage<RedirectChallenge, FlowChallengeRes
|
||||
// As this wouldn't really be a redirect, show a message that the page can be closed
|
||||
// and try to close it ourselves
|
||||
if (!url.protocol.startsWith("http")) {
|
||||
return html`<ak-empty-state icon="fas fa-check"
|
||||
><span>${msg("You may close this page now.")}</span>
|
||||
</ak-empty-state>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<ak-empty-state icon="fas fa-check"
|
||||
><span>${msg("You may close this page now.")}</span>
|
||||
</ak-empty-state>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
return html`<ak-empty-state default-label></ak-empty-state>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge} loading></ak-flow-card>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (this.startedRedirect || !this.promptUser) {
|
||||
return this.renderLoading();
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${msg("Redirect")}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
<div class="pf-c-form__group">
|
||||
<p>${msg("You're about to be redirect to the following URL.")}</p>
|
||||
<code>${this.getURL()}</code>
|
||||
</div>
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<a
|
||||
type="submit"
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
href=${this.challenge.to}
|
||||
@click=${() => {
|
||||
this.startedRedirect = true;
|
||||
}}
|
||||
>
|
||||
${msg("Follow redirect")}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer> `;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<span slot="title">${msg("Redirect")}</span>
|
||||
<form class="pf-c-form">
|
||||
<div class="pf-c-form__group">
|
||||
<p>${msg("You're about to be redirect to the following URL.")}</p>
|
||||
<code>${this.getURL()}</code>
|
||||
</div>
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<a
|
||||
type="submit"
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
href=${this.challenge.to}
|
||||
@click=${() => {
|
||||
this.startedRedirect = true;
|
||||
}}
|
||||
>
|
||||
${msg("Follow redirect")}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -25,40 +25,31 @@ export class AccessDeniedStage extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<ak-empty-state icon="fa-times"
|
||||
><span>${msg("Request has been denied.")}</span>
|
||||
${this.challenge.errorMessage
|
||||
? html`
|
||||
<div slot="body">
|
||||
<p>${this.challenge.errorMessage}</p>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
</ak-empty-state>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<ak-empty-state icon="fa-times"
|
||||
><span>${msg("Request has been denied.")}</span>
|
||||
${this.challenge.errorMessage
|
||||
? html`
|
||||
<div slot="body">
|
||||
<p>${this.challenge.errorMessage}</p>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
</ak-empty-state>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -64,57 +64,45 @@ export class AuthenticatorDuoStage extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<img
|
||||
src=${this.challenge.activationBarcode}
|
||||
alt=${msg("Duo activation QR code")}
|
||||
/>
|
||||
<p>
|
||||
${msg(
|
||||
"Alternatively, if your current device has Duo installed, click on this link:",
|
||||
)}
|
||||
</p>
|
||||
<a href=${this.challenge.activationCode}>${msg("Duo activation")}</a>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button
|
||||
type="button"
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
this.checkEnrollStatus();
|
||||
}}
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
${msg("Check status")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-form-static>
|
||||
<img src=${this.challenge.activationBarcode} alt=${msg("Duo activation QR code")} />
|
||||
<p>
|
||||
${msg(
|
||||
"Alternatively, if your current device has Duo installed, click on this link:",
|
||||
)}
|
||||
</p>
|
||||
<a href=${this.challenge.activationCode}>${msg("Duo activation")}</a>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button
|
||||
type="button"
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
this.checkEnrollStatus();
|
||||
}}
|
||||
>
|
||||
${msg("Check status")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -31,61 +31,13 @@ export class AuthenticatorEmailStage extends BaseStage<
|
||||
}
|
||||
|
||||
renderEmailInput(): TemplateResult {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<ak-form-element
|
||||
label="${msg("Configure your email")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).email}
|
||||
>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="${msg("Please enter your email address.")}"
|
||||
autofocus=""
|
||||
autocomplete="email"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
${this.renderNonFieldErrors()}
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
}
|
||||
|
||||
renderEmailOTPInput(): TemplateResult {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
@@ -97,71 +49,85 @@ export class AuthenticatorEmailStage extends BaseStage<
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
A verification token has been sent to your configured email address
|
||||
${ifDefined(this.challenge.email)}
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
<ak-form-element
|
||||
label="${msg("Configure your email")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).email}
|
||||
>
|
||||
<ak-form-element
|
||||
label="${msg("Code")}"
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
placeholder="${msg("Please enter your email address.")}"
|
||||
autofocus=""
|
||||
autocomplete="email"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
/>
|
||||
</ak-form-element>
|
||||
${this.renderNonFieldErrors()}
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
|
||||
renderEmailOTPInput(): TemplateResult {
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
placeholder="${msg("Please enter the code you received via email")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
${this.renderNonFieldErrors()}
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</div>
|
||||
</ak-form-static>
|
||||
A verification token has been sent to your configured email address
|
||||
${ifDefined(this.challenge.email)}
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-element
|
||||
label="${msg("Code")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
placeholder="${msg("Please enter the code you received via email")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
${this.renderNonFieldErrors()}
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
console.debug(
|
||||
"authentik/stages/authenticator_email:",
|
||||
this.challenge ? this.challenge.emailRequired : undefined,
|
||||
);
|
||||
|
||||
if (!this.challenge) {
|
||||
console.debug(
|
||||
"authentik/stages/authenticator_email: AuthenticatorEmailStage.render() called without challenge",
|
||||
);
|
||||
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
if (this.challenge.emailRequired) {
|
||||
console.debug(
|
||||
"authentik/stages/authenticator_email: AuthenticatorEmailStage.render() called with challenge",
|
||||
this.challenge,
|
||||
);
|
||||
|
||||
return this.renderEmailInput();
|
||||
}
|
||||
console.debug(
|
||||
"authentik/stages/authenticator_email: AuthenticatorEmailStage.render() called without emailRequired challenge",
|
||||
this.challenge,
|
||||
);
|
||||
|
||||
return this.renderEmailOTPInput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -31,10 +31,7 @@ export class AuthenticatorSMSStage extends BaseStage<
|
||||
}
|
||||
|
||||
renderPhoneNumber(): TemplateResult {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
@@ -76,68 +73,57 @@ export class AuthenticatorSMSStage extends BaseStage<
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
|
||||
renderCode(): TemplateResult {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<ak-form-element
|
||||
label="${msg("Code")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
placeholder="${msg("Please enter the code you received via SMS")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
${this.renderNonFieldErrors()}
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-form-static>
|
||||
<ak-form-element
|
||||
label="${msg("Code")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
placeholder="${msg("Please enter the code you received via SMS")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
${this.renderNonFieldErrors()}
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
if (this.challenge.phoneNumberRequired) {
|
||||
return this.renderPhoneNumber();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -52,49 +52,40 @@ export class AuthenticatorStaticStage extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<ak-form-element label="" class="pf-c-form__group">
|
||||
<ul>
|
||||
${this.challenge.codes.map((token) => {
|
||||
return html`<li class="pf-m-monospace">${token}</li>`;
|
||||
})}
|
||||
</ul>
|
||||
</ak-form-element>
|
||||
<p>${msg("Make sure to keep these tokens in a safe place.")}</p>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-form-static>
|
||||
<ak-form-element label="" class="pf-c-form__group">
|
||||
<ul>
|
||||
${this.challenge.codes.map((token) => {
|
||||
return html`<li class="pf-m-monospace">${token}</li>`;
|
||||
})}
|
||||
</ul>
|
||||
</ak-form-element>
|
||||
<p>${msg("Make sure to keep these tokens in a safe place.")}</p>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { MessageLevel } from "@goauthentik/common/messages";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
import "webcomponent-qr-code";
|
||||
|
||||
@@ -47,100 +47,89 @@ export class AuthenticatorTOTPStage extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<input type="hidden" name="otp_uri" value=${this.challenge.configUrl} />
|
||||
<ak-form-element>
|
||||
<div class="qr-container">
|
||||
<qr-code data="${this.challenge.configUrl}"></qr-code>
|
||||
<button
|
||||
type="button"
|
||||
class="pf-c-button pf-m-secondary pf-m-progress pf-m-in-progress"
|
||||
@click=${(e: Event) => {
|
||||
e.preventDefault();
|
||||
if (!this.challenge?.configUrl) return;
|
||||
if (!navigator.clipboard) {
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<input type="hidden" name="otp_uri" value=${this.challenge.configUrl} />
|
||||
<ak-form-element>
|
||||
<div class="qr-container">
|
||||
<qr-code data="${this.challenge.configUrl}"></qr-code>
|
||||
<button
|
||||
type="button"
|
||||
class="pf-c-button pf-m-secondary pf-m-progress pf-m-in-progress"
|
||||
@click=${(e: Event) => {
|
||||
e.preventDefault();
|
||||
if (!this.challenge?.configUrl) return;
|
||||
if (!navigator.clipboard) {
|
||||
showMessage({
|
||||
level: MessageLevel.info,
|
||||
message: this.challenge?.configUrl,
|
||||
});
|
||||
return;
|
||||
}
|
||||
navigator.clipboard
|
||||
.writeText(this.challenge?.configUrl)
|
||||
.then(() => {
|
||||
showMessage({
|
||||
level: MessageLevel.info,
|
||||
message: this.challenge?.configUrl,
|
||||
level: MessageLevel.success,
|
||||
message: msg("Successfully copied TOTP Config."),
|
||||
});
|
||||
return;
|
||||
}
|
||||
navigator.clipboard
|
||||
.writeText(this.challenge?.configUrl)
|
||||
.then(() => {
|
||||
showMessage({
|
||||
level: MessageLevel.success,
|
||||
message: msg("Successfully copied TOTP Config."),
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span class="pf-c-button__progress"
|
||||
><i class="fas fa-copy"></i
|
||||
></span>
|
||||
${msg("Copy")}
|
||||
</button>
|
||||
</div>
|
||||
</ak-form-element>
|
||||
<p>
|
||||
${msg(
|
||||
"Please scan the QR code above using the Microsoft Authenticator, Google Authenticator, or other authenticator apps on your device, and enter the code the device displays below to finish setting up the MFA device.",
|
||||
)}
|
||||
</p>
|
||||
<ak-form-element
|
||||
label="${msg("Code")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
>
|
||||
<!-- @ts-ignore -->
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
placeholder="${msg("Please enter your TOTP Code")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control pf-m-monospace"
|
||||
spellcheck="false"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<span class="pf-c-button__progress"><i class="fas fa-copy"></i></span>
|
||||
${msg("Copy")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-form-element>
|
||||
<p>
|
||||
${msg(
|
||||
"Please scan the QR code above using the Microsoft Authenticator, Google Authenticator, or other authenticator apps on your device, and enter the code the device displays below to finish setting up the MFA device.",
|
||||
)}
|
||||
</p>
|
||||
<ak-form-element
|
||||
label="${msg("Code")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
>
|
||||
<!-- @ts-ignore -->
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
placeholder="${msg("Please enter your TOTP Code")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control pf-m-monospace"
|
||||
spellcheck="false"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import "@goauthentik/flow/stages/authenticator_validate/AuthenticatorValidateStageCode";
|
||||
import "@goauthentik/flow/stages/authenticator_validate/AuthenticatorValidateStageDuo";
|
||||
import "@goauthentik/flow/stages/authenticator_validate/AuthenticatorValidateStageWebAuthn";
|
||||
@@ -276,28 +277,20 @@ export class AuthenticatorValidateStage
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return this.challenge
|
||||
? html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
${this.selectedDeviceChallenge
|
||||
? this.renderDeviceChallenge()
|
||||
: html`<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
${this.renderUserInfo()}
|
||||
${this.selectedDeviceChallenge
|
||||
? ""
|
||||
: html`<p>${msg("Select an authentication method.")}</p>`}
|
||||
${this.challenge.configurationStages.length > 0
|
||||
? this.renderStagePicker()
|
||||
: html``}
|
||||
</form>
|
||||
${this.renderDevicePicker()}
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`}`
|
||||
: html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
${this.selectedDeviceChallenge
|
||||
? this.renderDeviceChallenge()
|
||||
: html`<form class="pf-c-form">
|
||||
${this.renderUserInfo()}
|
||||
${this.selectedDeviceChallenge
|
||||
? ""
|
||||
: html`<p>${msg("Select an authentication method.")}</p>`}
|
||||
${this.challenge.configurationStages.length > 0
|
||||
? this.renderStagePicker()
|
||||
: html``}
|
||||
</form>
|
||||
${this.renderDevicePicker()}`}
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseDeviceStage } from "@goauthentik/flow/stages/authenticator_validate/base";
|
||||
import { PasswordManagerPrefill } from "@goauthentik/flow/stages/identification/IdentificationStage";
|
||||
|
||||
@@ -66,61 +66,53 @@ export class AuthenticatorValidateStageWebCode extends BaseDeviceStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
${this.renderUserInfo()}
|
||||
<div class="icon-description">
|
||||
<i class="fa ${this.deviceIcon()}" aria-hidden="true"></i>
|
||||
<p>${this.deviceMessage()}</p>
|
||||
</div>
|
||||
<ak-form-element
|
||||
label="${this.deviceChallenge?.deviceClass === DeviceClassesEnum.Static
|
||||
? msg("Static token")
|
||||
: msg("Authentication code")}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
>
|
||||
${this.renderUserInfo()}
|
||||
<div class="icon-description">
|
||||
<i class="fa ${this.deviceIcon()}" aria-hidden="true"></i>
|
||||
<p>${this.deviceMessage()}</p>
|
||||
</div>
|
||||
<ak-form-element
|
||||
label="${this.deviceChallenge?.deviceClass === DeviceClassesEnum.Static
|
||||
? msg("Static token")
|
||||
: msg("Authentication code")}"
|
||||
<!-- @ts-ignore -->
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="${this.deviceChallenge?.deviceClass === DeviceClassesEnum.Static
|
||||
? "text"
|
||||
: "numeric"}"
|
||||
pattern="${this.deviceChallenge?.deviceClass === DeviceClassesEnum.Static
|
||||
? "[0-9a-zA-Z]*"
|
||||
: "[0-9]*"}"
|
||||
placeholder="${msg("Please enter your code")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control"
|
||||
value="${PasswordManagerPrefill.totp || ""}"
|
||||
required
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).code}
|
||||
>
|
||||
<!-- @ts-ignore -->
|
||||
<input
|
||||
type="text"
|
||||
name="code"
|
||||
inputmode="${this.deviceChallenge?.deviceClass ===
|
||||
DeviceClassesEnum.Static
|
||||
? "text"
|
||||
: "numeric"}"
|
||||
pattern="${this.deviceChallenge?.deviceClass ===
|
||||
DeviceClassesEnum.Static
|
||||
? "[0-9a-zA-Z]*"
|
||||
: "[0-9]*"}"
|
||||
placeholder="${msg("Please enter your code")}"
|
||||
autofocus=""
|
||||
autocomplete="one-time-code"
|
||||
class="pf-c-form-control"
|
||||
value="${PasswordManagerPrefill.totp || ""}"
|
||||
required
|
||||
/>
|
||||
</ak-form-element>
|
||||
/>
|
||||
</ak-form-element>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
${this.renderReturnToDevicePicker()}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
${this.renderReturnToDevicePicker()}
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,24 +51,22 @@ export class AuthenticatorValidateStageWebDuo extends BaseDeviceStage<
|
||||
}
|
||||
const errors = this.challenge.responseErrors?.duo || [];
|
||||
const errorMessage = errors.map((err) => err.string);
|
||||
return html`<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
${this.renderUserInfo()}
|
||||
<ak-empty-state ?loading="${this.authenticating}" icon="fas fa-times"
|
||||
><span
|
||||
>${this.authenticating
|
||||
? msg("Sending Duo push notification...")
|
||||
: errorMessage.join(", ") || msg("Failed to authenticate")}</span
|
||||
>
|
||||
</ak-empty-state>
|
||||
<div class="pf-c-form__group pf-m-action">${this.renderReturnToDevicePicker()}</div>
|
||||
</form>
|
||||
</div>`;
|
||||
return html` <form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
${this.renderUserInfo()}
|
||||
<ak-empty-state ?loading="${this.authenticating}" icon="fas fa-times"
|
||||
><span
|
||||
>${this.authenticating
|
||||
? msg("Sending Duo push notification...")
|
||||
: errorMessage.join(", ") || msg("Failed to authenticate")}</span
|
||||
>
|
||||
</ak-empty-state>
|
||||
<div class="pf-c-form__group pf-m-action">${this.renderReturnToDevicePicker()}</div>
|
||||
</form>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,32 +103,30 @@ export class AuthenticatorValidateStageWebAuthn extends BaseDeviceStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
${this.renderUserInfo()}
|
||||
<ak-empty-state ?loading="${this.authenticating}" icon="fa-times">
|
||||
<span
|
||||
>${this.authenticating
|
||||
? msg("Authenticating...")
|
||||
: this.errorMessage || msg("Loading")}</span
|
||||
>
|
||||
</ak-empty-state>
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
${!this.authenticating
|
||||
? html` <button
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
this.authenticateWrapper();
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
${msg("Retry authentication")}
|
||||
</button>`
|
||||
: nothing}
|
||||
${this.renderReturnToDevicePicker()}
|
||||
</div>
|
||||
</form>
|
||||
</div>`;
|
||||
return html` <form class="pf-c-form">
|
||||
${this.renderUserInfo()}
|
||||
<ak-empty-state ?loading="${this.authenticating}" icon="fa-times">
|
||||
<span
|
||||
>${this.authenticating
|
||||
? msg("Authenticating...")
|
||||
: this.errorMessage || msg("Loading")}</span
|
||||
>
|
||||
</ak-empty-state>
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
${!this.authenticating
|
||||
? html` <button
|
||||
class="pf-c-button pf-m-primary pf-m-block"
|
||||
@click=${() => {
|
||||
this.authenticateWrapper();
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
${msg("Retry authentication")}
|
||||
</button>`
|
||||
: nothing}
|
||||
${this.renderReturnToDevicePicker()}
|
||||
</div>
|
||||
</form>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
transformNewAssertionForServer,
|
||||
} from "@goauthentik/common/helpers/webauthn";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
@@ -129,49 +130,46 @@ 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>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<ak-empty-state ?loading="${this.registerRunning}" icon="fa-times">
|
||||
<span
|
||||
>${this.registerRunning
|
||||
? msg("Registering...")
|
||||
: this.registerMessage || msg("Failed to register")}
|
||||
</span>
|
||||
</ak-empty-state>
|
||||
${this.challenge?.responseErrors
|
||||
? html`<p class="pf-m-block">
|
||||
${this.challenge.responseErrors.response[0].string}
|
||||
</p>`
|
||||
: nothing}
|
||||
<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("Retry registration")}
|
||||
</button>`
|
||||
: nothing}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
</div>`;
|
||||
</ak-form-static>
|
||||
<ak-empty-state ?loading="${this.registerRunning}" icon="fa-times">
|
||||
<span
|
||||
>${this.registerRunning
|
||||
? msg("Registering...")
|
||||
: this.registerMessage || msg("Failed to register")}
|
||||
</span>
|
||||
</ak-empty-state>
|
||||
${this.challenge?.responseErrors
|
||||
? html`<p class="pf-m-block">
|
||||
${this.challenge.responseErrors.response[0].string}
|
||||
</p>`
|
||||
: nothing}
|
||||
<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("Retry registration")}
|
||||
</button>`
|
||||
: nothing}
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -31,9 +32,6 @@ export class AutosubmitStage extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
let title = this.challenge.flowInfo?.title;
|
||||
if (this.challenge.title && this.challenge.title !== "") {
|
||||
title = this.challenge.title;
|
||||
@@ -41,16 +39,18 @@ export class AutosubmitStage extends BaseStage<
|
||||
if (!title) {
|
||||
title = msg("Loading");
|
||||
}
|
||||
return html`<form class="pf-c-form" action="${this.challenge.url}" method="POST">
|
||||
${Object.entries(this.challenge.attrs).map(([key, value]) => {
|
||||
return html`<input
|
||||
type="hidden"
|
||||
name="${key as string}"
|
||||
value="${value as string}"
|
||||
/>`;
|
||||
})}
|
||||
<ak-empty-state loading title=${title}> </ak-empty-state>
|
||||
</form>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form class="pf-c-form" action="${this.challenge.url}" method="POST">
|
||||
${Object.entries(this.challenge.attrs).map(([key, value]) => {
|
||||
return html`<input
|
||||
type="hidden"
|
||||
name="${key as string}"
|
||||
value="${value as string}"
|
||||
/>`;
|
||||
})}
|
||||
<ak-empty-state loading title=${title}> </ak-empty-state>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/// <reference types="@hcaptcha/types"/>
|
||||
/// <reference types="turnstile-types"/>
|
||||
import { renderStaticHTMLUnsafe } from "@goauthentik/common/purify";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import { akEmptyState } from "@goauthentik/elements/EmptyState";
|
||||
import { bound } from "@goauthentik/elements/decorators/bound";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
@@ -9,6 +8,7 @@ import { createIFrameHTMLWrapper } from "@goauthentik/elements/utils/iframe";
|
||||
import { ListenerController } from "@goauthentik/elements/utils/listenerController.js";
|
||||
import { randomId } from "@goauthentik/elements/utils/randomId";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
import { P, match } from "ts-pattern";
|
||||
|
||||
@@ -334,10 +334,7 @@ export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeRe
|
||||
}
|
||||
|
||||
renderMain() {
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
@@ -353,9 +350,7 @@ export class CaptchaStage extends BaseStage<CaptchaChallenge, CaptchaChallengeRe
|
||||
${this.renderBody()}
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -94,13 +94,7 @@ export class ConsentStage extends BaseStage<ConsentChallenge, ConsentChallengeRe
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
@@ -120,9 +114,11 @@ export class ConsentStage extends BaseStage<ConsentChallenge, ConsentChallengeRe
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
${this.challenge.additionalPermissions.length > 0
|
||||
? this.renderAdditional()
|
||||
: this.renderNoPrevious()}
|
||||
${
|
||||
this.challenge.additionalPermissions.length > 0
|
||||
? this.renderAdditional()
|
||||
: this.renderNoPrevious()
|
||||
}
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
@@ -131,9 +127,7 @@ export class ConsentStage extends BaseStage<ConsentChallenge, ConsentChallengeRe
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
@@ -22,30 +22,21 @@ export class DummyStage extends BaseStage<DummyChallenge, DummyChallengeResponse
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<p>${msg(str`Stage name: ${this.challenge.name}`)}</p>
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<p>${msg(str`Stage name: ${this.challenge.name}`)}</p>
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -21,33 +21,24 @@ export class EmailStage extends BaseStage<EmailChallenge, EmailChallengeResponse
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<div class="pf-c-form__group">
|
||||
<p>${msg("Check your Inbox for a verification email.")}</p>
|
||||
</div>
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<div class="pf-c-form__group">
|
||||
<p>${msg("Check your Inbox for a verification email.")}</p>
|
||||
</div>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Send Email again.")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Send Email again.")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { renderSourceIcon } from "@goauthentik/admin/sources/utils";
|
||||
import "@goauthentik/elements/Divider";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/components/ak-flow-card";
|
||||
import "@goauthentik/flow/components/ak-flow-password-input.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
import "@goauthentik/flow/stages/captcha/CaptchaStage";
|
||||
@@ -221,7 +222,7 @@ export class IdentificationStage extends BaseStage<
|
||||
if (!this.challenge?.enrollUrl && !this.challenge?.recoveryUrl) {
|
||||
return nothing;
|
||||
}
|
||||
return html`<div class="pf-c-login__main-footer-band">
|
||||
return html`<div slot="footer-band" class="pf-c-login__main-footer-band">
|
||||
${this.challenge.enrollUrl
|
||||
? html`<p class="pf-c-login__main-footer-band-item">
|
||||
${msg("Need an account?")}
|
||||
@@ -320,47 +321,39 @@ export class IdentificationStage extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
${this.challenge.applicationPre
|
||||
? html`<p>
|
||||
${msg(str`Login to continue to ${this.challenge.applicationPre}.`)}
|
||||
</p>`
|
||||
: nothing}
|
||||
${this.renderInput()}
|
||||
${this.challenge.passwordlessUrl
|
||||
? html`
|
||||
<div>
|
||||
<a
|
||||
href=${this.challenge.passwordlessUrl}
|
||||
class="pf-c-button pf-m-secondary pf-m-block"
|
||||
>
|
||||
${msg("Use a security key")}
|
||||
</a>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links">
|
||||
${(this.challenge.sources || []).map((source) => {
|
||||
return this.renderSource(source);
|
||||
})}
|
||||
</ul>
|
||||
${this.renderFooter()}
|
||||
</footer>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
${this.challenge.applicationPre
|
||||
? html`<p>
|
||||
${msg(str`Login to continue to ${this.challenge.applicationPre}.`)}
|
||||
</p>`
|
||||
: nothing}
|
||||
${this.renderInput()}
|
||||
${this.challenge.passwordlessUrl
|
||||
? html`
|
||||
<div>
|
||||
<a
|
||||
href=${this.challenge.passwordlessUrl}
|
||||
class="pf-c-button pf-m-secondary pf-m-block"
|
||||
>
|
||||
${msg("Use a security key")}
|
||||
</a>
|
||||
</div>
|
||||
`
|
||||
: nothing}
|
||||
</form>
|
||||
<ul slot="footer" class="pf-c-login__main-footer-links">
|
||||
${(this.challenge.sources || []).map((source) => {
|
||||
return this.renderSource(source);
|
||||
})}
|
||||
</ul>
|
||||
${this.renderFooter()}
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import "@goauthentik/flow/components/ak-flow-password-input.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
import { PasswordManagerPrefill } from "@goauthentik/flow/stages/identification/IdentificationStage";
|
||||
@@ -32,63 +32,52 @@ export class PasswordStage extends BaseStage<PasswordChallenge, PasswordChalleng
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<input
|
||||
name="username"
|
||||
autocomplete="username"
|
||||
type="hidden"
|
||||
value="${this.challenge.pendingUser}"
|
||||
/>
|
||||
<ak-flow-input-password
|
||||
label=${msg("Password")}
|
||||
required
|
||||
grab-focus
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).password}
|
||||
?allow-show-password=${this.challenge.allowShowPassword}
|
||||
invalid=${this.hasError("password").toString()}
|
||||
prefill=${PasswordManagerPrefill.password ?? ""}
|
||||
></ak-flow-input-password>
|
||||
|
||||
${this.challenge.recoveryUrl
|
||||
? html`<a href="${this.challenge.recoveryUrl}">
|
||||
${msg("Forgot password?")}</a
|
||||
>`
|
||||
: ""}
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-form-static>
|
||||
<input
|
||||
name="username"
|
||||
autocomplete="username"
|
||||
type="hidden"
|
||||
value="${this.challenge.pendingUser}"
|
||||
/>
|
||||
<ak-flow-input-password
|
||||
label=${msg("Password")}
|
||||
required
|
||||
grab-focus
|
||||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {}).password}
|
||||
?allow-show-password=${this.challenge.allowShowPassword}
|
||||
invalid=${this.hasError("password").toString()}
|
||||
prefill=${PasswordManagerPrefill.password ?? ""}
|
||||
></ak-flow-input-password>
|
||||
|
||||
${this.challenge.recoveryUrl
|
||||
? html`<a href="${this.challenge.recoveryUrl}"> ${msg("Forgot password?")}</a>`
|
||||
: ""}
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
|
||||
${msg("Continue")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { CapabilitiesEnum, WithCapabilitiesConfig } from "#elements/mixins/capabilities";
|
||||
import "@goauthentik/elements/Divider";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import { LOCALES } from "@goauthentik/elements/ak-locale-context/definitions";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -277,28 +277,19 @@ ${prompt.initialValue}</textarea
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
${this.challenge.fields.map((prompt) => {
|
||||
return this.renderField(prompt);
|
||||
})}
|
||||
${this.renderNonFieldErrors()} ${this.renderContinue()}
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
this.submitForm(e);
|
||||
}}
|
||||
>
|
||||
${this.challenge.fields.map((prompt) => {
|
||||
return this.renderField(prompt);
|
||||
})}
|
||||
${this.renderNonFieldErrors()} ${this.renderContinue()}
|
||||
</form>
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import "@goauthentik/elements/forms/FormElement";
|
||||
import "@goauthentik/flow/FormStatic";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@@ -28,13 +28,7 @@ export class PasswordStage extends BaseStage<
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state loading> </ak-empty-state>`;
|
||||
}
|
||||
return html`<header class="pf-c-login__main-header">
|
||||
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
@@ -82,9 +76,7 @@ export class PasswordStage extends BaseStage<
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
import "@goauthentik/flow/components/ak-flow-card.js";
|
||||
import { PromptStage } from "@goauthentik/flow/stages/prompt/PromptStage";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
@@ -63,10 +64,7 @@ export class UserSettingsPromptStage extends PromptStage {
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state default-label></ak-empty-state>`;
|
||||
}
|
||||
return html`<div class="pf-c-login__main-body">
|
||||
return html`<ak-flow-card .challenge=${this.challenge}>
|
||||
<form
|
||||
class="pf-c-form"
|
||||
@submit=${(e: Event) => {
|
||||
@@ -79,9 +77,7 @@ export class UserSettingsPromptStage extends PromptStage {
|
||||
${this.renderNonFieldErrors()} ${this.renderContinue()}
|
||||
</form>
|
||||
</div>
|
||||
<footer class="pf-c-login__main-footer">
|
||||
<ul class="pf-c-login__main-footer-links"></ul>
|
||||
</footer>`;
|
||||
</ak-flow-card>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user