Skip to content

feat: Add email factor for MFA and enhance enforcement options - #90

Merged
ashwin31 merged 1 commit into
masterfrom
dev
Aug 13, 2026
Merged

feat: Add email factor for MFA and enhance enforcement options#90
ashwin31 merged 1 commit into
masterfrom
dev

Conversation

@ashwin31

Copy link
Copy Markdown
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.
Copilot AI lite review requested due to automatic review settings August 13, 2026 16:53
@ashwin31
ashwin31 merged commit 1aa5997 into master Aug 13, 2026
23 checks passed
@ashwin31
ashwin31 deleted the dev branch August 13, 2026 16:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants