diff --git a/src/auth/ha-auth-external.ts b/src/auth/ha-auth-external.ts
new file mode 100644
index 000000000000..fdb8c9c16286
--- /dev/null
+++ b/src/auth/ha-auth-external.ts
@@ -0,0 +1,82 @@
+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;
+
+ @property({ attribute: false }) public blocked = false;
+
+ protected render(): TemplateResult {
+ return html`
+
+ ${this.localize("ui.panel.page-authorize.external.description")}
+ ${this.blocked
+ ? html`
+ ${this.localize("ui.panel.page-authorize.external.popup_blocked")}
+ `
+ : ""}
+
+
+ ${this.localize("ui.panel.page-authorize.external.open_site")}
+
+
+
+ `;
+ }
+
+ protected firstUpdated(changedProps) {
+ super.firstUpdated(changedProps);
+ this._openExternalStep();
+ }
+
+ private _openExternalStep() {
+ const externalWindow = window.open(this.step.url);
+ this.blocked = externalWindow == null;
+ if (this.blocked) {
+ return;
+ }
+ window.addEventListener("message", async (message: MessageEvent) => {
+ if (
+ message.origin === window.location.origin &&
+ message.source === externalWindow &&
+ 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..6fd50df55973 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)}
-