-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for MFA using TOTP and recovery codes
- Loading branch information
1 parent
1ea55b1
commit fa9a651
Showing
15 changed files
with
400 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
{# djlint:off H006 #} | ||
{% load i18n %} | ||
{% load static %} | ||
{% load allauth_ui %} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{% load widget_tweaks %} | ||
<label class="label" for="{{ field.id_for_label }}"> | ||
<span class="label-text">{{ field.label }}</span> | ||
</label> | ||
{% if field.errors %} | ||
{% render_field field placeholder="" class="w-full input input-bordered text-primary input-error" %} | ||
{% else %} | ||
{% render_field field placeholder="" class="w-full input input-bordered text-primary" %} | ||
{% endif %} | ||
{% for error in field.errors %} | ||
<span class="flex items-center max-w-xs mt-1 ml-1 text-xs font-medium tracking-wide text-error">{{ error }}</span> | ||
{% endfor %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
{% extends "mfa/index.html" %} | ||
{% load i18n %} | ||
{% load allauth_ui %} | ||
{% block content %} | ||
{% trans "Two-Factor Authentication" as heading %} | ||
{% #container heading=heading %} | ||
{% if "totp" in MFA_SUPPORTED_TYPES %} | ||
<h2 class="mt-6 mb-3 text-lg">{% translate "Authenticator App" %}</h2> | ||
{% if authenticators.totp %} | ||
<p class="my-2"> | ||
{% translate "Authentication using an authenticator app is active." %} | ||
<div> | ||
<a href="{% url "mfa_activate_totp" %}" | ||
role="button" | ||
class="my-3 btn btn-warning">{% translate "Deactivate" %}</a> | ||
</div> | ||
</p> | ||
{% else %} | ||
<p class="my-2">{% translate "An authenticator app is not active." %}</p> | ||
<a href="{% url "mfa_activate_totp" %}" | ||
role="button" | ||
class="btn btn-neutral">{% translate "Activate" %}</a> | ||
{% endif %} | ||
{% endif %} | ||
{% if "webauthn" in MFA_SUPPORTED_TYPES %} | ||
<div class="divider divider-neutral"></div> | ||
<h2 class="mt-6 mb-3 text-lg">{% translate "Security Keys" %}</h2> | ||
{% if authenticators.webauthn|length %} | ||
<p class="my-2"> | ||
{% blocktranslate count count=authenticators.webauthn|length %}You have added {{ count }} security key.{% plural %}You have added {{ count }} security keys.{% endblocktranslate %} | ||
</p> | ||
<a href="{% url "mfa_list_webauthn" %}" | ||
role="button" | ||
class="btn btn-neutral">{% translate "Manage" %}</a> | ||
{% else %} | ||
<p class="my-2">{% translate "No security keys have been added." %}</p> | ||
<a href="{% url "mfa_add_webauthn" %}" | ||
role="button" | ||
class="btn btn-neutral">{% translate "Add" %}</a> | ||
{% endif %} | ||
{% endif %} | ||
{% if "recovery_codes" in MFA_SUPPORTED_TYPES %} | ||
<div class="divider divider-neutral"></div> | ||
{% with total_count=authenticators.recovery_codes.generate_codes|length unused_count=authenticators.recovery_codes.get_unused_codes|length %} | ||
<h2 class="mt-6 mb-3 text-lg">{% translate "Recovery Codes" %}</h2> | ||
<p> | ||
{% if authenticators.recovery_codes %} | ||
{% blocktranslate count unused_count=unused_count %}There is {{ unused_count }} out of {{ total_count }} recovery codes available.{% plural %}There are {{ unused_count }} out of {{ total_count }} recovery codes available.{% endblocktranslate %} | ||
{% else %} | ||
{% translate "No recovery codes set up." %} | ||
{% endif %} | ||
</p> | ||
{% if is_mfa_enabled %} | ||
<div class="flex flex-col justify-evenly my-3 md:flex-row gap-1"> | ||
{% if authenticators.recovery_codes %} | ||
{% if unused_count > 0 %} | ||
<a href="{% url "mfa_view_recovery_codes" %}" | ||
role="button" | ||
class="btn btn-neutral">{% translate "View" %}</a> | ||
<a href="{% url "mfa_download_recovery_codes" %}" | ||
role="button" | ||
class="btn btn-neutral">{% translate "Download" %}</a> | ||
{% endif %} | ||
{% endif %} | ||
<a href="{% url "mfa_generate_recovery_codes" %}" | ||
role="button" | ||
class="btn btn-neutral">{% translate "Generate" %}</a> | ||
</div> | ||
{% endif %} | ||
{% endwith %} | ||
{% endif %} | ||
{% /container %} | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{% extends "mfa/recovery_codes/index.html" %} | ||
{% load i18n %} | ||
{% load allauth %} | ||
{% load allauth_ui %} | ||
{% block content %} | ||
{% translate "Recovery Codes" as heading %} | ||
{% blocktranslate asvar subheading %}You are about to generate a new set of recovery codes for your account.{% endblocktranslate %} | ||
{% #container heading=heading subheading=subheading %} | ||
<p class="py-3"> | ||
{% if unused_code_count %} | ||
{% blocktranslate %}This action will invalidate your existing codes.{% endblocktranslate %} | ||
{% endif %} | ||
{% blocktranslate %}Are you sure?{% endblocktranslate %} | ||
</p> | ||
{% url 'mfa_generate_recovery_codes' as action_url %} | ||
{% trans "Generate" as button_text %} | ||
{% #form url=action_url form=form button_text=button_text %} | ||
{% csrf_token %} | ||
{% /form %} | ||
{% /container %} | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{% extends "mfa/recovery_codes/index.html" %} | ||
{% load i18n %} | ||
{% load allauth %} | ||
{% load allauth_ui %} | ||
{% block content %} | ||
{% translate "Recovery Codes" as heading %} | ||
{% blocktranslate asvar subheading count unused_count=unused_codes|length %}There is {{ unused_count }} out of {{ total_count }} recovery codes available.{% plural %}There are {{ unused_count }} out of {{ total_count }} recovery codes available.{% endblocktranslate %} | ||
{% #container heading=heading subheading=subheading %} | ||
<div class="my-3"> | ||
<label class="label" for="codes"> | ||
<span class="label-text">{% translate "Unused codes" %}</span> | ||
</label> | ||
<textarea id="codes" class="w-full m-3 mx-auto textarea" rows="{{unused_codes|length}}" disabled readonly> | ||
{% for code in unused_codes %}{{ code }} | ||
{% endfor %} | ||
</textarea> | ||
</div> | ||
<div class="flex flex-col mx-auto sm:w-8/12 xl:w-7/12"> | ||
{% if unused_codes %} | ||
<a href="{% url "mfa_download_recovery_codes" %}" | ||
class="md:w-full btn btn-neutral">{% trans "Download codes" %}</a> | ||
{% endif %} | ||
<a href="{% url "mfa_generate_recovery_codes" %}" | ||
class="mt-4 md:w-full btn btn-neutral">{% trans "Generate new codes" %}</a> | ||
</div> | ||
{% /container %} | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{# djlint:off H006 #} | ||
{% extends "mfa/totp/activate_form.html" %} | ||
{% load allauth %} | ||
{% load allauth_ui %} | ||
{% load i18n %} | ||
{% block content %} | ||
{% translate "Activate Authenticator App" as heading %} | ||
{% blocktranslate asvar subheading %}To protect your account with two-factor authentication, scan the QR code below with your authenticator app. Then, input the verification code generated by the app below.{% endblocktranslate %} | ||
{% #container heading=heading subheading=subheading %} | ||
{% translate "Activate" as button_text %} | ||
{% url 'mfa_activate_totp' as action_url %} | ||
{% #form form=form method="post" url=action_url button_text=button_text render_fields="false" %} | ||
<img src="{{ totp_svg_data_uri }}" | ||
alt="{{ form.secret }}" | ||
class="mx-auto my-5" /> | ||
{% #form_field field=form.code %} | ||
{% /form_field %} | ||
<div class="my-3"> | ||
<label class="label" for="authenticator_secret"> | ||
<span class="label-text">{% translate "Authenticator secret" %}</span> | ||
</label> | ||
<p class="text-xs mb-2"> | ||
{% translate "You can store this secret and use it to reinstall your authenticator app at a later time." %} | ||
</p> | ||
<input type="text" id="authenticator_secret"" value="{{ form.secret }}" disabled | ||
class="w-full input input-bordered text-primary"/> | ||
</div> | ||
{% csrf_token %} | ||
{% /form %} | ||
{% /container %} | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{% extends "mfa/totp/deactivate_form.html" %} | ||
{% load i18n %} | ||
{% load allauth_ui %} | ||
{% block content %} | ||
{% trans "Deactivate Authenticator App" as heading %} | ||
{% blocktranslate asvar subheading %}You are about to deactivate authenticator app based authentication. Are you sure?{% endblocktranslate %} | ||
{% #container heading=heading subheading=subheading %} | ||
{% url 'mfa_deactivate_totp' as action_url %} | ||
{% #form form=form url=action_url button_text=button_text use_default_button="false"%} | ||
{% csrf_token %} | ||
<button type="submit" class="btn btn-warning">{% trans "Deactivate" %}</button> | ||
{% /form %} | ||
{% /container %} | ||
{% endblock content %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.