web/flow: render prompt inputs without unsafeHTML (#5404)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
af7cc8d42d
commit
a8332eced6
|
@ -50,147 +50,151 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
|
|||
];
|
||||
}
|
||||
|
||||
renderPromptInner(prompt: StagePrompt): string {
|
||||
renderPromptInner(prompt: StagePrompt): TemplateResult {
|
||||
switch (prompt.type) {
|
||||
case PromptTypeEnum.Text:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="text"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
autocomplete="off"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.TextArea:
|
||||
return `<textarea
|
||||
return html`<textarea
|
||||
type="text"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
autocomplete="off"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}"">`;
|
||||
value="${prompt.initialValue}"
|
||||
></textarea>`;
|
||||
case PromptTypeEnum.TextReadOnly:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="text"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
class="pf-c-form-control"
|
||||
readonly
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.TextAreaReadOnly:
|
||||
return `<textarea
|
||||
return html`<textarea
|
||||
type="text"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
class="pf-c-form-control"
|
||||
readonly
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
></textarea>`;
|
||||
case PromptTypeEnum.Username:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="text"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
autocomplete="username"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.Email:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="email"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.Password:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="password"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
autocomplete="new-password"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}>`;
|
||||
?required=${prompt.required}
|
||||
/>`;
|
||||
case PromptTypeEnum.Number:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="number"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.Date:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="date"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.DateTime:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="datetime"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.File:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="file"
|
||||
name="${prompt.fieldKey}"
|
||||
placeholder="${prompt.placeholder}"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}
|
||||
value="${prompt.initialValue}">`;
|
||||
value="${prompt.initialValue}"
|
||||
/>`;
|
||||
case PromptTypeEnum.Separator:
|
||||
return `<ak-divider>${prompt.placeholder}</ak-divider>`;
|
||||
return html`<ak-divider>${prompt.placeholder}</ak-divider>`;
|
||||
case PromptTypeEnum.Hidden:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="hidden"
|
||||
name="${prompt.fieldKey}"
|
||||
value="${prompt.initialValue}"
|
||||
class="pf-c-form-control"
|
||||
?required=${prompt.required}>`;
|
||||
?required=${prompt.required}
|
||||
/>`;
|
||||
case PromptTypeEnum.Static:
|
||||
return `<p>${prompt.initialValue}</p>`;
|
||||
return html`<p>${unsafeHTML(prompt.initialValue)}</p>`;
|
||||
case PromptTypeEnum.Dropdown:
|
||||
return `<select class="pf-c-form-control" name="${prompt.fieldKey}">
|
||||
${prompt.choices
|
||||
?.map((choice) => {
|
||||
return `<option
|
||||
return html`<select class="pf-c-form-control" name="${prompt.fieldKey}">
|
||||
${prompt.choices?.map((choice) => {
|
||||
return html`<option
|
||||
value="${choice}"
|
||||
?selected=${prompt.initialValue === choice}
|
||||
>
|
||||
${choice}
|
||||
</option>`;
|
||||
})
|
||||
.join("")}
|
||||
})}
|
||||
</select>`;
|
||||
case PromptTypeEnum.RadioButtonGroup:
|
||||
return (
|
||||
prompt.choices
|
||||
?.map((choice) => {
|
||||
return ` <div class="pf-c-check">
|
||||
<input
|
||||
type="radio"
|
||||
class="pf-c-check__input"
|
||||
id="${prompt.fieldKey}"
|
||||
name="${prompt.fieldKey}"
|
||||
checked="${prompt.initialValue === choice}"
|
||||
required="${prompt.required}"
|
||||
value="${choice}"
|
||||
/>
|
||||
<label class="pf-c-check__label" for="${
|
||||
prompt.fieldKey
|
||||
}">${choice}</label>
|
||||
</div>
|
||||
`;
|
||||
})
|
||||
.join("") || ""
|
||||
);
|
||||
return html`${(prompt.choices || []).map((choice) => {
|
||||
const id = `${prompt.fieldKey}-${choice}`;
|
||||
return html`<div class="pf-c-check">
|
||||
<input
|
||||
type="radio"
|
||||
class="pf-c-check__input"
|
||||
name="${prompt.fieldKey}"
|
||||
id="${id}"
|
||||
checked="${prompt.initialValue === choice}"
|
||||
required="${prompt.required}"
|
||||
value="${choice}"
|
||||
/>
|
||||
<label class="pf-c-check__label" for=${id}>${choice}</label>
|
||||
</div> `;
|
||||
})}`;
|
||||
case PromptTypeEnum.AkLocale:
|
||||
return `<select class="pf-c-form-control" name="${prompt.fieldKey}">
|
||||
return html`<select class="pf-c-form-control" name="${prompt.fieldKey}">
|
||||
<option value="" ${prompt.initialValue === "" ? "selected" : ""}>
|
||||
${t`Auto-detect (based on your browser)`}
|
||||
</option>
|
||||
|
@ -202,19 +206,17 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
|
|||
);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((locale) => {
|
||||
return `<option
|
||||
}).map((locale) => {
|
||||
return html`<option
|
||||
value=${locale.code}
|
||||
${prompt.initialValue === locale.code ? "selected" : ""}
|
||||
>
|
||||
${locale.code.toUpperCase()} - ${locale.label}
|
||||
</option>`;
|
||||
})
|
||||
.join("")}
|
||||
})}
|
||||
</select>`;
|
||||
default:
|
||||
return `<p>invalid type '${prompt.type}'</p>`;
|
||||
return html`<p>invalid type '${prompt.type}'</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,11 +265,10 @@ export class PromptStage extends BaseStage<PromptChallenge, PromptChallengeRespo
|
|||
class="pf-c-form__group"
|
||||
.errors=${(this.challenge?.responseErrors || {})[prompt.fieldKey]}
|
||||
>
|
||||
${unsafeHTML(this.renderPromptInner(prompt))} ${this.renderPromptHelpText(prompt)}
|
||||
${this.renderPromptInner(prompt)} ${this.renderPromptHelpText(prompt)}
|
||||
</ak-form-element>`;
|
||||
}
|
||||
return html` ${unsafeHTML(this.renderPromptInner(prompt))}
|
||||
${this.renderPromptHelpText(prompt)}`;
|
||||
return html` ${this.renderPromptInner(prompt)} ${this.renderPromptHelpText(prompt)}`;
|
||||
}
|
||||
|
||||
renderContinue(): TemplateResult {
|
||||
|
|
|
@ -5,17 +5,16 @@ import { t } from "@lingui/macro";
|
|||
|
||||
import { TemplateResult, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
||||
|
||||
import { PromptTypeEnum, StagePrompt } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-user-stage-prompt")
|
||||
export class UserSettingsPromptStage extends PromptStage {
|
||||
renderPromptInner(prompt: StagePrompt): string {
|
||||
renderPromptInner(prompt: StagePrompt): TemplateResult {
|
||||
switch (prompt.type) {
|
||||
// Checkbox requires slightly different rendering here due to the use of horizontal form elements
|
||||
case PromptTypeEnum.Checkbox:
|
||||
return `<input
|
||||
return html`<input
|
||||
type="checkbox"
|
||||
class="pf-c-check__input"
|
||||
name="${prompt.fieldKey}"
|
||||
|
@ -41,14 +40,11 @@ export class UserSettingsPromptStage extends PromptStage {
|
|||
return error.string;
|
||||
})}
|
||||
>
|
||||
${unsafeHTML(this.renderPromptInner(prompt))}
|
||||
${this.renderPromptHelpText(prompt)}
|
||||
${this.renderPromptInner(prompt)} ${this.renderPromptHelpText(prompt)}
|
||||
</ak-form-element-horizontal>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
${unsafeHTML(this.renderPromptInner(prompt))} ${this.renderPromptHelpText(prompt)}
|
||||
`;
|
||||
return html` ${this.renderPromptInner(prompt)} ${this.renderPromptHelpText(prompt)} `;
|
||||
}
|
||||
|
||||
renderContinue(): TemplateResult {
|
||||
|
|
Reference in New Issue