web/flows: fix helper form not being removed from identification stage (improve password manager compatibility)
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
		| @ -131,7 +131,7 @@ export class FlowExecutor extends LitElement implements StageHost { | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|     submit(payload?: FlowChallengeResponseRequest): Promise<void> { | ||||
|     submit(payload?: FlowChallengeResponseRequest): Promise<boolean> { | ||||
|         if (!payload) return Promise.reject(); | ||||
|         if (!this.challenge) return Promise.reject(); | ||||
|         // @ts-ignore | ||||
| @ -153,12 +153,18 @@ export class FlowExecutor extends LitElement implements StageHost { | ||||
|                     ); | ||||
|                 } | ||||
|                 this.challenge = data; | ||||
|                 if (this.challenge.responseErrors) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 return true; | ||||
|             }) | ||||
|             .catch((e: Error | Response) => { | ||||
|                 this.errorMessage(e); | ||||
|                 return false; | ||||
|             }) | ||||
|             .finally(() => { | ||||
|                 this.loading = false; | ||||
|                 return false; | ||||
|             }); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -7,7 +7,7 @@ export interface StageHost { | ||||
|     challenge?: unknown; | ||||
|     flowSlug: string; | ||||
|     loading: boolean; | ||||
|     submit(payload: unknown): Promise<void>; | ||||
|     submit(payload: unknown): Promise<boolean>; | ||||
| } | ||||
|  | ||||
| export class BaseStage<Tin, Tout> extends LitElement { | ||||
| @ -16,14 +16,19 @@ export class BaseStage<Tin, Tout> extends LitElement { | ||||
|     @property({ attribute: false }) | ||||
|     challenge!: Tin; | ||||
|  | ||||
|     submitForm(e: Event): void { | ||||
|     async submitForm(e: Event): Promise<boolean> { | ||||
|         e.preventDefault(); | ||||
|         const object: { | ||||
|             [key: string]: unknown; | ||||
|         } = {}; | ||||
|         const form = new FormData(this.shadowRoot?.querySelector("form") || undefined); | ||||
|         form.forEach((value, key) => (object[key] = value)); | ||||
|         this.host?.submit(object as unknown as Tout); | ||||
|         return this.host?.submit(object as unknown as Tout).then((successful) => { | ||||
|             if (successful) { | ||||
|                 this.cleanup(); | ||||
|             } | ||||
|             return successful; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     renderNonFieldErrors(errors: ErrorDetail[]): TemplateResult { | ||||
| @ -41,4 +46,9 @@ export class BaseStage<Tin, Tout> extends LitElement { | ||||
|             })} | ||||
|         </div>`; | ||||
|     } | ||||
|  | ||||
|     cleanup(): void { | ||||
|         // Method that can be overridden by stages | ||||
|         return; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -41,6 +41,8 @@ export class IdentificationStage extends BaseStage< | ||||
|     IdentificationChallenge, | ||||
|     IdentificationChallengeResponseRequest | ||||
| > { | ||||
|     form?: HTMLFormElement; | ||||
|  | ||||
|     static get styles(): CSSResult[] { | ||||
|         return [ | ||||
|             PFBase, | ||||
| @ -72,8 +74,8 @@ export class IdentificationStage extends BaseStage< | ||||
|     } | ||||
|  | ||||
|     firstUpdated(): void { | ||||
|         const wrapperForm = document.createElement("form"); | ||||
|         document.documentElement.appendChild(wrapperForm); | ||||
|         this.form = document.createElement("form"); | ||||
|         document.documentElement.appendChild(this.form); | ||||
|         // This is a workaround for the fact that we're in a shadow dom | ||||
|         // adapted from https://github.com/home-assistant/frontend/issues/3133 | ||||
|         const username = document.createElement("input"); | ||||
| @ -91,7 +93,7 @@ export class IdentificationStage extends BaseStage< | ||||
|                     input.focus(); | ||||
|                 }); | ||||
|         }; | ||||
|         wrapperForm.appendChild(username); | ||||
|         this.form.appendChild(username); | ||||
|         const password = document.createElement("input"); | ||||
|         password.setAttribute("type", "password"); | ||||
|         password.setAttribute("name", "password"); | ||||
| @ -115,7 +117,7 @@ export class IdentificationStage extends BaseStage< | ||||
|                     input.focus(); | ||||
|                 }); | ||||
|         }; | ||||
|         wrapperForm.appendChild(password); | ||||
|         this.form.appendChild(password); | ||||
|         const totp = document.createElement("input"); | ||||
|         totp.setAttribute("type", "text"); | ||||
|         totp.setAttribute("name", "code"); | ||||
| @ -139,7 +141,13 @@ export class IdentificationStage extends BaseStage< | ||||
|                     input.focus(); | ||||
|                 }); | ||||
|         }; | ||||
|         wrapperForm.appendChild(totp); | ||||
|         this.form.appendChild(totp); | ||||
|     } | ||||
|  | ||||
|     cleanup(): void { | ||||
|         if (this.form) { | ||||
|             document.documentElement.removeChild(this.form); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     renderSource(source: LoginSource): TemplateResult { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer