From ced70fd9a189a5622f8709a62d47d94a219105ee Mon Sep 17 00:00:00 2001
From: Wendelin <12148533+wendevlin@users.noreply.github.com>
Date: Mon, 18 Nov 2024 14:25:51 +0100
Subject: [PATCH] Fix 2fa login validation, add autofocus to login (#22856)
---
build-scripts/webpack.cjs | 1 +
src/auth/ha-auth-flow.ts | 24 ++++++++++++++----------
src/auth/ha-auth-form-string.ts | 1 +
src/auth/ha-auth-textfield.ts | 9 +++++++++
src/components/ha-form/types.ts | 1 +
src/data/auth.ts | 4 ++--
6 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs
index 94ca35b8f5..83f54fb584 100644
--- a/build-scripts/webpack.cjs
+++ b/build-scripts/webpack.cjs
@@ -188,6 +188,7 @@ const createWebpackConfig = ({
"lit/directives/cache$": "lit/directives/cache.js",
"lit/directives/repeat$": "lit/directives/repeat.js",
"lit/directives/live$": "lit/directives/live.js",
+ "lit/directives/keyed$": "lit/directives/keyed.js",
"lit/polyfill-support$": "lit/polyfill-support.js",
"@lit-labs/virtualizer/layouts/grid":
"@lit-labs/virtualizer/layouts/grid.js",
diff --git a/src/auth/ha-auth-flow.ts b/src/auth/ha-auth-flow.ts
index 668beb4685..b860d9e426 100644
--- a/src/auth/ha-auth-flow.ts
+++ b/src/auth/ha-auth-flow.ts
@@ -3,6 +3,7 @@ import "@material/mwc-button";
import { genClientId } from "home-assistant-js-websocket";
import type { PropertyValues } from "lit";
import { html, LitElement, nothing } from "lit";
+import { keyed } from "lit/directives/keyed";
import { customElement, property, state } from "lit/decorators";
import type { LocalizeFunc } from "../common/translations/localize";
import "../components/ha-alert";
@@ -224,16 +225,19 @@ export class HaAuthFlow extends LitElement {
: this.localize("ui.panel.page-authorize.just_checking")}
${this._computeStepDescription(step)}
-
+ ${keyed(
+ step.step_id,
+ html``
+ )}
${this.clientId === genClientId() &&
!["select_mfa_module", "mfa"].includes(step.step_id)
? html`
diff --git a/src/auth/ha-auth-form-string.ts b/src/auth/ha-auth-form-string.ts
index 77de5c495a..4502513f7d 100644
--- a/src/auth/ha-auth-form-string.ts
+++ b/src/auth/ha-auth-form-string.ts
@@ -54,6 +54,7 @@ export class HaAuthFormString extends HaFormString {
.autoValidate=${this.schema.required}
.name=${this.schema.name}
.autocomplete=${this.schema.autocomplete}
+ ?autofocus=${this.schema.autofocus}
.suffix=${
this.isPassword
? // reserve some space for the icon.
diff --git a/src/auth/ha-auth-textfield.ts b/src/auth/ha-auth-textfield.ts
index ca4f8e1f19..b13e661c56 100644
--- a/src/auth/ha-auth-textfield.ts
+++ b/src/auth/ha-auth-textfield.ts
@@ -69,6 +69,7 @@ export class HaAuthTextField extends HaTextField {
name=${ifDefined(this.name === "" ? undefined : this.name)}
inputmode=${ifDefined(this.inputMode)}
autocapitalize=${ifDefined(autocapitalizeOrUndef)}
+ ?autofocus=${this.autofocus}
@input=${this.handleInputChange}
@focus=${this.onInputFocus}
@blur=${this.onInputBlur}
@@ -246,6 +247,14 @@ export class HaAuthTextField extends HaTextField {
this.append(style);
return this;
}
+
+ public firstUpdated() {
+ super.firstUpdated();
+
+ if (this.autofocus) {
+ this.focus();
+ }
+ }
}
declare global {
diff --git a/src/components/ha-form/types.ts b/src/components/ha-form/types.ts
index 437ffd17ea..5c5ab10643 100644
--- a/src/components/ha-form/types.ts
+++ b/src/components/ha-form/types.ts
@@ -85,6 +85,7 @@ export interface HaFormStringSchema extends HaFormBaseSchema {
type: "string";
format?: string;
autocomplete?: string;
+ autofocus?: boolean;
}
export interface HaFormBooleanSchema extends HaFormBaseSchema {
diff --git a/src/data/auth.ts b/src/data/auth.ts
index 29c647fe15..45fd8db37d 100644
--- a/src/data/auth.ts
+++ b/src/data/auth.ts
@@ -30,11 +30,11 @@ export const autocompleteLoginFields = (schema: HaFormSchema[]) =>
if (field.type !== "string") return field;
switch (field.name) {
case "username":
- return { ...field, autocomplete: "username" };
+ return { ...field, autocomplete: "username", autofocus: true };
case "password":
return { ...field, autocomplete: "current-password" };
case "code":
- return { ...field, autocomplete: "one-time-code" };
+ return { ...field, autocomplete: "one-time-code", autofocus: true };
default:
return field;
}