From 5b56570b4118ff3104a1af8149956ac3fff43810 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 7 Dec 2024 22:06:02 +0000 Subject: [PATCH] Support external step for Authentication providers in login flow --- src/auth/ha-auth-external.ts | 65 ++++++++++++++++++++++++++++++++++++ src/auth/ha-auth-flow.ts | 44 ++++++++++++++++-------- src/translations/en.json | 4 +++ 3 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 src/auth/ha-auth-external.ts diff --git a/src/auth/ha-auth-external.ts b/src/auth/ha-auth-external.ts new file mode 100644 index 000000000000..7e8d8215ec0c --- /dev/null +++ b/src/auth/ha-auth-external.ts @@ -0,0 +1,65 @@ +import type { CSSResultGroup, TemplateResult } from "lit"; +import { css, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import type { DataEntryFlowStepExternal } from "../../data/data_entry_flow"; +import { fireEvent } from "../common/dom/fire_event"; +import type { LocalizeFunc } from "../common/translations/localize"; +import { HaForm } from "../components/ha-form/ha-form"; + +@customElement("ha-auth-external") +export class HaAuthExternal extends HaForm { + @property({ attribute: false }) public localize?: LocalizeFunc; + + @property({ attribute: false }) public stepTitle?: string; + + @property({ attribute: false }) public step!: DataEntryFlowStepExternal; + + protected render(): TemplateResult { + return html` +

${this.stepTitle}

+
+ ${this.localize("ui.panel.page-authorize.external.description")} + +
+ `; + } + + protected firstUpdated(changedProps) { + super.firstUpdated(changedProps); + window.open(this.step.url); + window.addEventListener("message", async (message: MessageEvent) => { + if (message.data.type === "externalCallback") { + fireEvent(this, "step-finished"); + } + }); + } + + static get styles(): CSSResultGroup { + return [ + css` + .open-button { + text-align: center; + padding: 24px 0; + } + .open-button a { + text-decoration: none; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-auth-external": HaAuthExternal; + } + interface HASSDomEvents { + "step-finished": undefined; + } +} diff --git a/src/auth/ha-auth-flow.ts b/src/auth/ha-auth-flow.ts index 2adce4d34786..b86c39bc6f16 100644 --- a/src/auth/ha-auth-flow.ts +++ b/src/auth/ha-auth-flow.ts @@ -23,6 +23,7 @@ import type { DataEntryFlowStepForm, } from "../data/data_entry_flow"; import "./ha-auth-form"; +import "./ha-auth-external"; type State = "loading" | "error" | "step"; @@ -171,18 +172,7 @@ export class HaAuthFlow extends LitElement { } return html` - ${this._renderStep(this.step)} -
- - ${this.step.type === "form" - ? this.localize("ui.panel.page-authorize.form.next") - : this.localize("ui.panel.page-authorize.form.start_over")} - -
+ ${this._renderStep(this.step)} ${this._renderAction(this.step)} `; case "error": return html` @@ -266,11 +256,35 @@ export class HaAuthFlow extends LitElement { ` : ""} `; + case "external": + return html``; default: return nothing; } } + private _renderAction(step: DataEntryFlowStep) { + if (step.type === "external") { + return nothing; + } + return html`
+ + ${step.type === "form" + ? this.localize("ui.panel.page-authorize.form.next") + : this.localize("ui.panel.page-authorize.form.start_over")} + +
`; + } + private _storeTokenChanged(e: CustomEvent) { this._storeToken = (e.currentTarget as HTMLInputElement).checked; } @@ -364,7 +378,7 @@ export class HaAuthFlow extends LitElement { if (this.step == null) { return; } - if (this.step.type !== "form") { + if (this.step.type !== "form" && this.step.type !== "external") { this._providerChanged(this.authProvider); return; } @@ -403,6 +417,10 @@ export class HaAuthFlow extends LitElement { this._submitting = false; } } + + private _externalStepFinished(ev: CustomEvent) { + this._handleSubmit(ev); + } } declare global { diff --git a/src/translations/en.json b/src/translations/en.json index e8bfe80a397a..be0d8662a5f1 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -7144,6 +7144,10 @@ } } } + }, + "external": { + "description": "This step requires you to visit an external website to be completed.", + "open_site": "Open website" } }, "page-demo": {