import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { EVENT_FLOW_ADVANCE } from "@goauthentik/common/constants"; import { AKElement } from "@goauthentik/elements/Base"; import "@goauthentik/elements/Expand"; import { t } from "@lingui/macro"; import { CSSResult, TemplateResult, css, html } from "lit"; import { customElement, property } from "lit/decorators.js"; import AKGlobal from "@goauthentik/common/styles/authentik.css"; import PFCard from "@patternfly/patternfly/components/Card/card.css"; import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; import PFNotificationDrawer from "@patternfly/patternfly/components/NotificationDrawer/notification-drawer.css"; import PFProgressStepper from "@patternfly/patternfly/components/ProgressStepper/progress-stepper.css"; import PFStack from "@patternfly/patternfly/layouts/Stack/stack.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css"; import { FlowInspection, FlowsApi, Stage } from "@goauthentik/api"; @customElement("ak-flow-inspector") export class FlowInspector extends AKElement { flowSlug: string; @property({ attribute: false }) state?: FlowInspection; @property({ attribute: false }) error?: Response; static get styles(): CSSResult[] { return [ PFBase, PFStack, PFCard, PFNotificationDrawer, PFDescriptionList, PFProgressStepper, AKGlobal, css` code.break { word-break: break-all; } `, ]; } constructor() { super(); this.flowSlug = window.location.pathname.split("/")[3]; window.addEventListener(EVENT_FLOW_ADVANCE, this.advanceHandler as EventListener); } disconnectedCallback(): void { super.disconnectedCallback(); window.removeEventListener(EVENT_FLOW_ADVANCE, this.advanceHandler as EventListener); } advanceHandler = (): void => { new FlowsApi(DEFAULT_CONFIG) .flowsInspectorGet({ flowSlug: this.flowSlug, }) .then((state) => { this.state = state; }) .catch((exc) => { this.error = exc; }); }; // getStage return a stage without flowSet, for brevity getStage(stage?: Stage): unknown { if (!stage) { return stage; } delete stage.flowSet; return stage; } renderAccessDenied(): TemplateResult { return html`

${t`Flow inspector`}

${this.error?.statusText}
`; } render(): TemplateResult { if (this.error) { return this.renderAccessDenied(); } if (!this.state) { return html` `; } return html`

${t`Flow inspector`}

${t`Next stage`}
${t`Stage name`}
${this.state.currentPlan?.nextPlannedStage ?.stageObj?.name || "-"}
${t`Stage kind`}
${this.state.currentPlan?.nextPlannedStage ?.stageObj?.verboseName || "-"}
${t`Stage object`}
${this.state.isCompleted ? html`
${t`This flow is completed.`}
` : html`
${JSON.stringify(this.getStage(this.state.currentPlan?.nextPlannedStage?.stageObj), null, 4)}
`}
${t`Plan history`}
    ${this.state.plans.map((plan) => { return html`
  1. ${plan.currentStage.stageObj?.name}
    ${plan.currentStage.stageObj?.verboseName}
  2. `; })} ${this.state.currentPlan?.currentStage && !this.state.isCompleted ? html`
  3. ${this.state.currentPlan?.currentStage ?.stageObj?.name}
    ${this.state.currentPlan?.currentStage ?.stageObj?.verboseName}
  4. ` : html``} ${this.state.currentPlan?.nextPlannedStage && !this.state.isCompleted ? html`
  5. ${this.state.currentPlan.nextPlannedStage .stageObj?.name}
    ${this.state.currentPlan?.nextPlannedStage ?.stageObj?.verboseName}
  6. ` : html``}
${t`Current plan context`}
${JSON.stringify(this.state.currentPlan?.planContext, null, 4)}
${t`Session ID`}
${this.state.currentPlan?.sessionId}
`; } }