Conversation
ashwin31
commented
Aug 13, 2026
Member
- Introduced an email-based one-time code factor for MFA, allowing users to receive codes via email as a fallback option.
- Updated documentation to reflect the new email factor, including its usage, security considerations, and configuration settings.
- Implemented enforcement settings to require MFA for specific users or views, enhancing security policies.
- Added new system checks to validate the configuration of MFA requirements.
- Bumped version to 4.1.0 to reflect the new features and changes.
- Introduced an email-based one-time code factor for MFA, allowing users to receive codes via email as a fallback option. - Updated documentation to reflect the new email factor, including its usage, security considerations, and configuration settings. - Implemented enforcement settings to require MFA for specific users or views, enhancing security policies. - Added new system checks to validate the configuration of MFA requirements. - Bumped version to 4.1.0 to reflect the new features and changes.
There was a problem hiding this comment.
Pull request overview
This PR extends django-mfa with an opt-in email one-time-code factor, adds configurable MFA enforcement (site-wide via MFA_REQUIRED and per-view via decorators/mixins), and introduces signals + optional notification emails to support auditing and user-facing change alerts.
Changes:
- Added
"email"adapter (emailed OTP) with new settings + templates and rate limiting for send attempts. - Implemented MFA enforcement controls (
MFA_REQUIRED, middleware enrollment wall,@mfa_required/MfaRequiredMixin) plus a new system check (django_mfa.E004). - Added event signals and optional notification emails (
MFA_NOTIFY_ON_CHANGE), plus supporting docs/tests and version bump to 4.1.0.
Reviewed changes
Copilot reviewed 60 out of 61 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Bumps package version metadata to 4.1.0. |
| README.md | Documents emailed codes + enforcement and adds E004 to system checks list. |
| pyproject.toml | Bumps project version to 4.1.0. |
| docs/upgrading.md | Notes email as an opt-in Authenticator.type and constraint coverage. |
| docs/settings.md | Adds MFA_REQUIRED, email-factor settings, notification setting, and clarifies exempt-path behavior across walls. |
| docs/security.md | Adds security guidance for emailed codes and notifications. |
| docs/recipes.md | Updates enforcement guidance to use MFA_REQUIRED / enforcement docs. |
| docs/mfa_flow.md | Documents emailed-code flows and the new enrollment-required wall. |
| docs/index.md | Adds enforcement page to docs TOC. |
| docs/enforcement.md | New enforcement guide covering MFA_REQUIRED and per-view enforcement. |
| docs/customizing.md | Documents new email templates and new mfa_enrollment_required context flag. |
| docs/custom_factors.md | Updates worked example to non-email factor and references built-in email adapter. |
| docs/contributing.md | Updates release process to include changelog updates. |
| docs/api.md | Documents Registry.has_primary_factor() and new emitted signals. |
| django_mfa/views/verify.py | Emits mfa_verified / mfa_verification_failed signals from verification flows (including passkey UV). |
| django_mfa/views/manage.py | Adds enrollment-required context, emits factor-added/removed events for recovery codes and deletions. |
| django_mfa/views/enroll.py | Emits factor_added event on successful enroll. |
| django_mfa/utils.py | Adds user_email() and mask_email() helpers to support email factor UX safely. |
| django_mfa/tests/test_registry.py | Adds correctness + query-count coverage for has_primary_factor(). |
| django_mfa/tests/test_ratelimit.py | Adds alternate rate-limit scope tests for email send throttling. |
| django_mfa/tests/test_policy.py | New tests for MFA_REQUIRED resolution, supplied predicates, and E004 check behavior. |
| django_mfa/tests/test_passwordless.py | Adds signal emission coverage for UV vs UP-only passkey assertions. |
| django_mfa/tests/test_notifications.py | New tests for opt-in notification email behavior and robustness. |
| django_mfa/tests/test_models.py | Adds DB constraint tests for email singleton behavior and choice presence. |
| django_mfa/tests/test_migrations.py | Extends migration-chain test and adds makemigrations “no changes” guard. |
| django_mfa/tests/test_events.py | New tests for event signals (added/removed/verified/failed/recovery-code-used) and robustness. |
| django_mfa/tests/test_enforcement.py | Adds enforcement wall + query-cost tests and pending/enroll isolation coverage. |
| django_mfa/tests/test_decorators.py | New tests for @mfa_required and MfaRequiredMixin behavior. |
| django_mfa/tests/test_adapter_email.py | New comprehensive tests for email adapter ceremony state, security properties, throttling, and view integration. |
| django_mfa/templatetags/otp_tags.py | Adds mask_email template filter for masked address display. |
| django_mfa/templates/django_mfa/verify_email.html | New verify template for emailed OTP factor. |
| django_mfa/templates/django_mfa/security.html | Displays masked enrolled email address and shows enrollment-required warning notice. |
| django_mfa/templates/django_mfa/enroll_email.html | New enrollment template for emailed OTP factor. |
| django_mfa/templates/django_mfa/email/recovery_code_used.txt | New notification email template (recovery code used). |
| django_mfa/templates/django_mfa/email/recovery_code_used_subject.txt | New subject template for recovery code notification. |
| django_mfa/templates/django_mfa/email/otp_code.txt | New OTP email body template for emailed codes. |
| django_mfa/templates/django_mfa/email/otp_code_subject.txt | New OTP email subject template for emailed codes. |
| django_mfa/templates/django_mfa/email/mfa_disabled.txt | New notification email template (MFA disabled). |
| django_mfa/templates/django_mfa/email/mfa_disabled_subject.txt | New subject template for MFA disabled notification. |
| django_mfa/templates/django_mfa/email/factor_removed.txt | New notification email template (factor removed). |
| django_mfa/templates/django_mfa/email/factor_removed_subject.txt | New subject template for factor removed notification. |
| django_mfa/templates/django_mfa/email/factor_added.txt | New notification email template (factor added). |
| django_mfa/templates/django_mfa/email/factor_added_subject.txt | New subject template for factor added notification. |
| django_mfa/static/django_mfa/style.css | Adds styling for enrollment-required warning notice. |
| django_mfa/signals.py | Re-exports new event signals from django_mfa.events. |
| django_mfa/registry.py | Adds has_primary_factor() and clarifies complete_enroll() return contract. |
| django_mfa/ratelimit.py | Generalizes rate limiting to support multiple scopes/settings and adds record alias. |
| django_mfa/policy.py | New policy module implementing MFA_REQUIRED resolution and supplied predicates. |
| django_mfa/notifications.py | New opt-in notification email module wired to event signals. |
| django_mfa/models.py | Adds email factor type choice and extends singleton constraint to include it. |
| django_mfa/migrations/0008_email_factor.py | New migration adding email choice and extending singleton constraint condition. |
| django_mfa/middleware.py | Adds enrollment-required wall (separate exempt set) driven by MFA_REQUIRED + has_primary_factor(). |
| django_mfa/events.py | New events module defining signals emitted by django-mfa. |
| django_mfa/decorators.py | New per-view enforcement decorator and CBV mixin. |
| django_mfa/conf.py | Adds defaults for new settings (email factor, enforcement, notifications). |
| django_mfa/checks.py | Adds system check django_mfa.E004 for validating MFA_REQUIRED. |
| django_mfa/apps.py | Registers new check and imports notifications module to connect receivers. |
| django_mfa/adapters/recovery_codes.py | Emits recovery_code_used event on successful spend. |
| django_mfa/adapters/email.py | New email OTP adapter with ceremony state, throttled sending, and secure code hashing. |
| django_mfa/adapters/init.py | Registers email adapter as an optional built-in. |
| CHANGELOG.md | New changelog starting at 4.1.0 documenting features and upgrade notes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+58
to
+64
| @receiver(events.factor_added) | ||
| def notify_factor_added(sender, user, authenticator, request=None, **kwargs): | ||
| _notify(user, "factor_added", { | ||
| "user": user, | ||
| "factor": authenticator.get_type_display(), | ||
| "name": authenticator.name, | ||
| }) |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.