Style every MFA screen through the element system
The MFA pages (manage, TOTP activate/deactivate, recovery codes, security keys,
reauthenticate) are built almost entirely from allauth's `element` primitives, so
they are styled by overriding the elements rather than by rewriting eight page
templates. New allauth pages then inherit the look for free.
- field + img elements were missing entirely, so allauth fell back to bare HTML:
the TOTP secret and recovery-code list rendered as unstyled inputs. The QR now
sits on a white plate -- it is dark modules on a transparent ground, so on the
dark theme it was dark-on-dark and phones could not scan it.
- button now honours the tags allauth sets. They were all flattened to
btn-primary, which made "Deactivate" look exactly as safe as "View".
- the `code` field renders as a daisyUI otp wherever it appears, so the
reauthenticate and activate pages get the same input as the login challenge.
The boxes step aside past six characters: allauth accepts a TOTP code (6) or a
recovery code (8) in that one field.
Fixes a crash: the security-key list does {% load humanize %}, which raised
TemplateSyntaxError because django.contrib.humanize was not installed. That page
500'd on every request; it is now installed and covered by a test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
42
templates/allauth/elements/field.html
Normal file
42
templates/allauth/elements/field.html
Normal file
@@ -0,0 +1,42 @@
|
||||
{% load allauth %}
|
||||
|
||||
{% comment %}
|
||||
A standalone field that isn't part of a Django form — allauth uses it for the TOTP
|
||||
secret and the recovery-code list. Mono, because both are strings people copy
|
||||
character by character and must not misread.
|
||||
{% endcomment %}
|
||||
{{ attrs.errors }}
|
||||
<div class="form-control my-3 w-full">
|
||||
{% if slots.label %}
|
||||
<label class="label" for="{{ attrs.id }}">
|
||||
<span class="label-text">{% slot label %}{% endslot %}</span>
|
||||
</label>
|
||||
{% endif %}
|
||||
|
||||
{% if attrs.type == "textarea" %}
|
||||
<textarea class="textarea textarea-bordered w-full font-mono"
|
||||
{% if attrs.required %}required{% endif %}
|
||||
{% if attrs.rows %}rows="{{ attrs.rows }}"{% endif %}
|
||||
{% if attrs.disabled %}disabled{% endif %}
|
||||
{% if attrs.readonly %}readonly{% endif %}
|
||||
{% if attrs.name %}name="{{ attrs.name }}"{% endif %}
|
||||
{% if attrs.id %}id="{{ attrs.id }}"{% endif %}
|
||||
{% if attrs.placeholder %}placeholder="{{ attrs.placeholder }}"{% endif %}>{% slot value %}{% endslot %}</textarea>
|
||||
{% else %}
|
||||
<input class="input input-bordered w-full font-mono"
|
||||
{% if attrs.required %}required{% endif %}
|
||||
{% if attrs.disabled %}disabled{% endif %}
|
||||
{% if attrs.readonly %}readonly{% endif %}
|
||||
{% if attrs.checked %}checked{% endif %}
|
||||
{% if attrs.name %}name="{{ attrs.name }}"{% endif %}
|
||||
{% if attrs.id %}id="{{ attrs.id }}"{% endif %}
|
||||
{% if attrs.placeholder %}placeholder="{{ attrs.placeholder }}"{% endif %}
|
||||
{% if attrs.autocomplete %}autocomplete="{{ attrs.autocomplete }}"{% endif %}
|
||||
{% if attrs.value is not None %}value="{{ attrs.value }}"{% endif %}
|
||||
type="{{ attrs.type }}">
|
||||
{% endif %}
|
||||
|
||||
{% if slots.help_text %}
|
||||
<span class="label-text-alt mt-1 block text-base-content/70">{% slot help_text %}{% endslot %}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
Reference in New Issue
Block a user