{# Shared persona login picker, used by login.html, authorize.html and device.html so the markup (and any future fix to it, e.g. the device flow's implicit-submission fix) exists in one place instead of three. ``users`` is a list of ``(username, description)`` pairs (see ``IdentityResolver.persona_picker_entries()``), so every surface shows the same display-only context next to the name. ``description`` is plain text only - it goes through Jinja's autoescaping like any other value, never raw HTML. js_submit=True renders non-submit buttons with a `persona-user-btn` class instead, for surfaces (device.html) where a text input shares the form and implicit Enter-submission must not silently pick a user; the caller is then responsible for the click handler that actually submits. #} {# The declarative TOTP second factor's code screen (#348) on /login, /saml/sso and /device: the verified password is recorded server-side as a pending second factor (#373), so the form carries only its opaque id and the code. The submit button stays with the caller, since each surface labels and groups it differently. #} {% macro totp_code_fields(pending_second_factor) %} {{ totp_code_input() }} {% endmacro %} {# The code input alone. /authorize uses it directly: its form names the authorization transaction instead (#346). #} {% macro totp_code_input() %}
{% endmacro %} {% macro persona_picker(users, prompt, js_submit=false) %}

{{ prompt }} No password required (local development convenience).

{% if users %}
{% for username, description in users %} {% if js_submit %} {% else %} {% endif %} {% endfor %}
{% else %}

No users configured.

{% endif %} {% endmacro %}