Repository: goauthentik/authentik
File: web/src/flow/stages/identification/IdentificationStage.ts (TypeScript)

Code before:

        // prettier-ignore
        return html`
            ${recovery ? this.renderRecoveryPhase() : nothing}
            ${this.renderIdentityInput(challenge)}
            ${passwordFields ? this.renderPasswordFields(challenge) : nothing}
            ${this.renderNonFieldErrors()}
            ${captchaStage ? this.renderCaptchaStage(captchaStage) : nothing}
            ${this.renderSubmitButton(challenge)}
        `;
    }

    renderPasswordlessUrl(passwordlessUrl: string) {
        return html`<ak-divider>${msg("Or")}</ak-divider>
            <a
                name="passwordless"
                href=${passwordlessUrl}
                class="pf-c-button pf-m-secondary pf-m-block"
            >
                ${msg("Use a security key")}
            </a> `;
    }

    // These have the same type, and can be supplied out-of-order. Passing them in by name prevents
    // mis-ordering.
    renderFooter({ enrollUrl, recoveryUrl }: IdentificationFooter) {
        if (!(enrollUrl || recoveryUrl)) {
            return nothing;
        }

        return html`<fieldset
            slot="footer-band"
            part="additional-actions"
            class="pf-c-login__main-footer-band"
        >
            <legend class="sr-only">${msg("Additional actions")}</legend>
            ${enrollUrl
                ? html`<div class="pf-c-login__main-footer-band-item">
                      ${msg("Need an account?")}
                      <a name="enroll" href="${enrollUrl}">${msg("Sign up.")}</a>
                  </div>`
                : nothing}
            ${recoveryUrl
                ? html`<div class="pf-c-login__main-footer-band-item">
                      <a name="recovery" href="${recoveryUrl}"
                          >${msg("Forgot username or password?")}</a
                      >
                  </div>`
                : nothing}
        </fieldset>`;
    }

Review comment (suggestion):
```suggestion
    protected renderFooter({ enrollUrl, recoveryUrl }: IdentificationFooter): SlottedTemplateResult {
```

Code after:
        return html`<p>${msg(str`Log in to continue to ${prelude}.`)}</p>`;
    }

    protected renderPasswordlessUrl(url: string) {
        return html`<a
            href=${url}
            class="pf-c-button pf-m-secondary pf-m-block"
            ouiaId="passwordless"
        >
            ${msg("Use a security key")}
        </a> `;
    }

    //#region Render
    protected renderDefaultSource(source: LoginSource, showLabels: boolean) {
        const { name, iconUrl, challenge } = source;

        const icon = renderSourceIcon(name, iconUrl);
        return html`<button
            type="button"
            @click=${() => this.#dispatchChallengeToHost(challenge)}
            part="source-item"
            name=${`source-${kebabCase(name)}`}
            class="pf-c-button source-button"
            aria-label=${msg(str`Continue with ${name}`)}
        >
            <span class="pf-c-button__icon pf-m-start">${icon}</span>
            ${showLabels ? name : ""}
        </button>`;
    }

    protected renderPromotedSource(source: LoginSource) {
        const { name, challenge } = source;

        return html`<button
            type="button"
            @click=${() => this.#dispatchChallengeToHost(challenge)}
            part="source-item source-item-promoted"
            name=${`source-${kebabCase(name)}`}
            class="pf-c-button pf-m-primary pf-m-block source-button source-button-promoted"
            aria-label=${msg(str`Continue with ${name}`)}
        >
            ${msg(str`Continue with ${name}`)}
        </button>`;
    }

    protected renderLoginSource(source: LoginSource, showLabels: boolean) {
        return source.promoted
            ? this.renderPromotedSource(source)
            : this.renderDefaultSource(source, showLabels);
    }