web: remove more until (#5057)

* more cleanup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* don't dynamically import duo form

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate more

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix import

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* properly send evens when tab isn't switched

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix loop on tabs

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate more

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* don't bubble tab events

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* remove most other uses of until()

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* cleanup user settings

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* only use stale for issues

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L
2023-03-23 23:16:26 +01:00
committed by GitHub
parent af7189953c
commit b3dd87bbab
26 changed files with 699 additions and 744 deletions

View File

@ -1,10 +1,10 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { me } from "@goauthentik/common/users";
import { AKElement } from "@goauthentik/elements/Base";
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
import "@goauthentik/elements/Tabs";
import "@goauthentik/elements/user/SessionList";
import "@goauthentik/elements/user/UserConsentList";
import { UserInterface } from "@goauthentik/user/UserInterface";
import "@goauthentik/user/user-settings/details/UserPassword";
import "@goauthentik/user/user-settings/details/UserSettingsFlowExecutor";
import "@goauthentik/user/user-settings/mfa/MFADevicesPage";
@ -16,7 +16,6 @@ import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js";
import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
@ -62,7 +61,7 @@ export class UserSettingsPage extends AKElement {
}
@state()
userSettings!: Promise<UserSetting[]>;
userSettings?: UserSetting[];
constructor() {
super();
@ -71,11 +70,14 @@ export class UserSettingsPage extends AKElement {
});
}
firstUpdated(): void {
this.userSettings = new StagesApi(DEFAULT_CONFIG).stagesAllUserSettingsList();
async firstUpdated(): Promise<void> {
this.userSettings = await new StagesApi(DEFAULT_CONFIG).stagesAllUserSettingsList();
}
render(): TemplateResult {
const pwStage = this.userSettings?.filter(
(stage) => stage.component === "ak-user-settings-password",
);
return html`<div class="pf-c-page">
<main role="main" class="pf-c-page__main" tabindex="-1">
<ak-tabs ?vertical="${true}">
@ -89,20 +91,11 @@ export class UserSettingsPage extends AKElement {
<ak-user-settings-flow-executor></ak-user-settings-flow-executor>
</div>
<div class="pf-l-stack__item">
${until(
this.userSettings?.then((settings) => {
const pwStage = settings.filter(
(stage) =>
stage.component === "ak-user-settings-password",
);
if (pwStage.length > 0) {
return html`<ak-user-settings-password
configureUrl=${ifDefined(pwStage[0].configureUrl)}
></ak-user-settings-password>`;
}
return html``;
}),
)}
${pwStage
? html`<ak-user-settings-password
configureUrl=${ifDefined(pwStage[0].configureUrl)}
></ak-user-settings-password>`
: html``}
</div>
</div>
</section>
@ -111,26 +104,20 @@ export class UserSettingsPage extends AKElement {
data-tab-title="${t`Sessions`}"
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
${until(
me().then((u) => {
return html`<ak-user-session-list
targetUser=${u.user.username}
></ak-user-session-list>`;
}),
)}
<ak-user-session-list
targetUser=${ifDefined(
rootInterface<UserInterface>()?.me?.user.username,
)}
></ak-user-session-list>
</section>
<section
slot="page-consents"
data-tab-title="${t`Consent`}"
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
${until(
me().then((u) => {
return html`<ak-user-consent-list
userId=${u.user.pk}
></ak-user-consent-list>`;
}),
)}
<ak-user-consent-list
userId=${ifDefined(rootInterface<UserInterface>()?.me?.user.pk)}
></ak-user-consent-list>
</section>
<section
slot="page-mfa"

View File

@ -1,8 +1,8 @@
import { DEFAULT_CONFIG, tenant } from "@goauthentik/common/api/config";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { MessageLevel } from "@goauthentik/common/messages";
import { refreshMe } from "@goauthentik/common/users";
import { AKElement } from "@goauthentik/elements/Base";
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { StageHost } from "@goauthentik/flow/stages/base";
import "@goauthentik/user/user-settings/details/stages/prompt/PromptStage";
@ -22,7 +22,6 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import {
ChallengeChoices,
ChallengeTypes,
CurrentTenant,
FlowChallengeResponseRequest,
FlowErrorChallenge,
FlowsApi,
@ -51,18 +50,10 @@ export class UserSettingsFlowExecutor extends AKElement implements StageHost {
@property({ type: Boolean })
loading = false;
@property({ attribute: false })
tenant!: CurrentTenant;
static get styles(): CSSResult[] {
return [PFBase, PFCard, PFPage, PFButton, PFContent];
}
constructor() {
super();
tenant().then((tenant) => (this.tenant = tenant));
}
submit(payload?: FlowChallengeResponseRequest): Promise<boolean> {
if (!payload) return Promise.reject();
if (!this.challenge) return Promise.reject();
@ -93,13 +84,12 @@ export class UserSettingsFlowExecutor extends AKElement implements StageHost {
}
firstUpdated(): void {
tenant().then((tenant) => {
this.flowSlug = tenant.flowUserSettings;
if (!this.flowSlug) {
return;
}
this.nextChallenge();
});
const tenant = rootInterface()?.tenant;
this.flowSlug = tenant?.flowUserSettings;
if (!this.flowSlug) {
return;
}
this.nextChallenge();
}
async nextChallenge(): Promise<void> {

View File

@ -13,7 +13,6 @@ import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js";
import { AuthenticatorsApi, Device, UserSetting } from "@goauthentik/api";
@ -47,7 +46,7 @@ export function deviceTypeName(device: Device): string {
@customElement("ak-user-settings-mfa")
export class MFADevicesPage extends Table<Device> {
@property({ attribute: false })
userSettings?: Promise<UserSetting[]>;
userSettings?: UserSetting[];
checkbox = true;
@ -70,41 +69,32 @@ export class MFADevicesPage extends Table<Device> {
}
renderToolbar(): TemplateResult {
const settings = (this.userSettings || []).filter((stage) => {
if (stage.component === "ak-user-settings-password") {
return false;
}
return stage.configureUrl;
});
return html`<ak-dropdown class="pf-c-dropdown">
<button class="pf-m-primary pf-c-dropdown__toggle" type="button">
<span class="pf-c-dropdown__toggle-text">${t`Enroll`}</span>
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
</button>
<ul class="pf-c-dropdown__menu" hidden>
${until(
this.userSettings?.then((stages) => {
return stages
.filter((stage) => {
if (stage.component === "ak-user-settings-password") {
return false;
}
return stage.configureUrl;
})
.map((stage) => {
return html`<li>
<a
href="${ifDefined(stage.configureUrl)}${AndNext(
`/if/user/#/settings;${JSON.stringify({
page: "page-mfa",
})}`,
)}"
class="pf-c-dropdown__menu-item"
>
${stageToAuthenticatorName(stage)}
</a>
</li>`;
});
}),
html`<ak-empty-state
?loading="${true}"
header=${t`Loading`}
></ak-empty-state>`,
)}
${settings.map((stage) => {
return html`<li>
<a
href="${ifDefined(stage.configureUrl)}${AndNext(
`/if/user/#/settings;${JSON.stringify({
page: "page-mfa",
})}`,
)}"
class="pf-c-dropdown__menu-item"
>
${stageToAuthenticatorName(stage)}
</a>
</li>`;
})}
</ul>
</ak-dropdown>
${super.renderToolbar()}`;

View File

@ -12,7 +12,6 @@ import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css";
@ -22,7 +21,7 @@ import { PaginatedUserSourceConnectionList, SourcesApi, UserSetting } from "@goa
@customElement("ak-user-settings-source")
export class UserSourceSettingsPage extends AKElement {
@property({ attribute: false })
sourceSettings?: Promise<UserSetting[]>;
sourceSettings?: UserSetting[];
@property({ attribute: false })
connections?: PaginatedUserSourceConnectionList;
@ -57,7 +56,7 @@ export class UserSourceSettingsPage extends AKElement {
async firstUpdated(): Promise<void> {
const user = await me();
this.sourceSettings = new SourcesApi(DEFAULT_CONFIG).sourcesAllUserSettingsList();
this.sourceSettings = await new SourcesApi(DEFAULT_CONFIG).sourcesAllUserSettingsList();
this.connections = await new SourcesApi(DEFAULT_CONFIG).sourcesUserConnectionsAllList({
user: user.user.pk,
});
@ -115,30 +114,33 @@ export class UserSourceSettingsPage extends AKElement {
</p>
</div>
<ul class="pf-c-data-list" role="list">
${until(
this.sourceSettings?.then((source) => {
if (source.length < 1) {
return html`<ak-empty-state
header=${t`No services available.`}
></ak-empty-state>`;
}
return source.map((source) => {
return html`<li class="pf-c-data-list__item">
<div class="pf-c-data-list__item-content">
<div class="pf-c-data-list__cell">
${renderSourceIcon(source.title, source.iconUrl)}
${source.title}
</div>
<div class="pf-c-data-list__cell">
${this.renderSourceSettings(source)}
</div>
</div>
</li>`;
});
}),
html`<ak-empty-state ?loading="${true}" header=${t`Loading`}>
</ak-empty-state>`,
)}
${this.sourceSettings
? html`
${this.sourceSettings.length < 1
? html`<ak-empty-state
header=${t`No services available.`}
></ak-empty-state>`
: html`
${this.sourceSettings.map((source) => {
return html`<li class="pf-c-data-list__item">
<div class="pf-c-data-list__item-content">
<div class="pf-c-data-list__cell">
${renderSourceIcon(
source.title,
source.iconUrl,
)}
${source.title}
</div>
<div class="pf-c-data-list__cell">
${this.renderSourceSettings(source)}
</div>
</div>
</li>`;
})}
`}
`
: html`<ak-empty-state ?loading="${true}" header=${t`Loading`}>
</ak-empty-state>`}
</ul>`;
}
}