Conversation
ashwin31
commented
Aug 14, 2026
- Refactor passkey verification logic to streamline user authentication.
- Implement conditional mediation for passkey autofill in login forms.
- Add a new JSON API for MFA operations, allowing SPA and mobile clients to interact with MFA features.
- Enhance documentation to cover new API endpoints and passkey autofill functionality.
- Update translation handling with a new script for managing catalogs.
- Bump version to 4.4.0 to reflect new features and improvements.
- Refactor passkey verification logic to streamline user authentication. - Implement conditional mediation for passkey autofill in login forms. - Add a new JSON API for MFA operations, allowing SPA and mobile clients to interact with MFA features. - Enhance documentation to cover new API endpoints and passkey autofill functionality. - Update translation handling with a new script for managing catalogs. - Bump version to 4.4.0 to reflect new features and improvements.
| // a browser without it still gets the button, unchanged. | ||
| if (wantsConditional | ||
| && typeof PublicKeyCredential.isConditionalMediationAvailable | ||
| === "function") { |
There was a problem hiding this comment.
Misleading line break before '==='; readers may interpret this as an expression boundary.
| // so its absence means "no autofill here" rather than an error -- | ||
| // a browser without it still gets the button, unchanged. | ||
| if (wantsConditional | ||
| && typeof PublicKeyCredential.isConditionalMediationAvailable |
There was a problem hiding this comment.
Misleading line break before '&&'; readers may interpret this as an expression boundary.
| // get() slot, and hands it back if its own ceremony fails, so a user | ||
| // who opens the modal and presses Escape still has working autofill | ||
| // afterwards instead of a dropdown that has quietly gone dead. | ||
| function startConditional() { |
There was a problem hiding this comment.
Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.
There was a problem hiding this comment.
Pull request overview
This PR expands django-mfa with an opt-in JSON API for MFA operations (SPA/mobile clients), refactors shared MFA “flow” logic to avoid drift between HTML and API layers, improves passkey UX with conditional mediation (autofill), and makes shipped translations live by adding a pure-Python catalog refresh/compile workflow.
Changes:
- Add
django_mfa.api(URLs/auth/views) plus docs and tests for a JSON MFA API surface. - Refactor enrollment/verification/remove-factor sequencing into
django_mfa.flowsand extract enforcement “rungs” into reusable predicates. - Introduce
tools/compile_catalogs.pyand ship compiled.mocatalogs; update i18n tooling/tests/docs accordingly; update sandbox login to demonstrate passkeys + autofill.
Reviewed changes
Copilot reviewed 38 out of 45 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Bumps locked project version to 4.4.0. |
| tools/compile_catalogs.py | Adds script to refresh PO references and compile MO catalogs without gettext binaries. |
| sandbox/templates/login.html | Demonstrates passkey sign-in UI + conditional mediation wiring; includes webauthn.js. |
| sandbox/sample/forms.py | Adds autocomplete="username webauthn" for passkey autofill demonstration. |
| README.md | Documents new JSON API and live translations. |
| pyproject.toml | Bumps package version to 4.4.0. |
| docs/translations.md | Updates translation model (live catalogs) and workflow (compile script). |
| docs/settings.md | Documents new MFA_API_AUTHENTICATION setting and adds E006 to checks list. |
| docs/rest_api.md | Adds JSON API documentation (endpoints, auth, errors, constraints). |
| docs/recipes.md | Adds recipe for conditional mediation passkey autofill; clarifies API vs middleware behavior. |
| docs/index.md | Adds rest_api to docs toctree. |
| django_mfa/views/verify.py | Refactors verify and passkey completion; shares passkey assertion resolution with API. |
| django_mfa/views/manage.py | Reuses shared flows.remove_factor; wraps enterprise message for translation. |
| django_mfa/views/enroll.py | Uses flows.attempt_enroll and normalizes adapter rejection handling. |
| django_mfa/tests/test_packaging.py | Updates packaging test to assert .mo files ship alongside .po. |
| django_mfa/tests/test_i18n.py | Replaces “drafts inert” checks with “live catalogs complete + compiled + served” checks. |
| django_mfa/tests/test_api.py | Adds comprehensive JSON API tests focused on refusals and invariants. |
| django_mfa/tests/support/i18n.py | Extends PO parsing for msgctxt; adds MO compiler and PO writer helpers. |
| django_mfa/tests/support/api_urls.py | Adds URLConf for API tests mounting the API under a prefix. |
| django_mfa/templates/django_mfa/security.html | Adds translation context to avoid msgid collisions for “Remove”. |
| django_mfa/static/django_mfa/webauthn.js | Adds conditional mediation flow + abort handling; documents required markup. |
| django_mfa/middleware.py | Detects API requests by resolved namespace to avoid redirecting API clients. |
| django_mfa/locale/zh_Hans/LC_MESSAGES/django.po | Makes translations live; updates references; adds msgctxt entry for “Remove”. |
| django_mfa/locale/pt_BR/LC_MESSAGES/django.po | Same: live translations + updated references/context. |
| django_mfa/locale/ja/LC_MESSAGES/django.po | Same: live translations + updated references/context. |
| django_mfa/locale/fr/LC_MESSAGES/django.po | Same: live translations + updated references/context. |
| django_mfa/locale/es/LC_MESSAGES/django.po | Same: live translations + updated references/context. |
| django_mfa/locale/de/LC_MESSAGES/django.po | Same: live translations + updated references/context. |
| django_mfa/locale/django.pot | Updates template references and adds msgctxt entry for “Remove”. |
| django_mfa/flows.py | Introduces shared enrollment/verification/remove-factor sequencing. |
| django_mfa/decorators.py | Extracts enforcement-state predicates and re-renders them for redirects. |
| django_mfa/conf.py | Adds MFA_API_AUTHENTICATION default setting. |
| django_mfa/checks.py | Adds system check E006 validating MFA_API_AUTHENTICATION. |
| django_mfa/apps.py | Registers new E006 system check. |
| django_mfa/api/views.py | Implements JSON endpoints + shared gating/CSRF/error envelope. |
| django_mfa/api/urls.py | Adds API URL patterns and fixed namespace. |
| django_mfa/api/auth.py | Adds resolver for MFA_API_AUTHENTICATION to identify API callers. |
| django_mfa/api/init.py | Documents opt-in JSON API module purpose and layering constraints. |
| CHANGELOG.md | Documents 4.4.0 features, behavior changes, and fixes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| @endpoint("POST", require_verified=False) | ||
| def verify_begin(request, factor_type): |
| @endpoint("POST", require_verified=False) | ||
| def verify_complete(request, factor_type): |
| class VerifyTests(ApiTestCase): | ||
| def setUp(self): | ||
| super().setUp() | ||
| self.enroll_totp() | ||
| self.set_session_mfa(verified=False) | ||
|
|