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:
parent
ab17a12184
commit
e72097292c
|
@ -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 a new issue