Skip to content

feat: Update passkey handling and introduce JSON API - #93

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

feat: Update passkey handling and introduce JSON API#93
ashwin31 merged 1 commit into
masterfrom
dev

Conversation

@ashwin31

Copy link
Copy Markdown
Member
  • 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.
Copilot AI lite review requested due to automatic review settings August 14, 2026 04:14
// a browser without it still gets the button, unchanged.
if (wantsConditional
&& typeof PublicKeyCredential.isConditionalMediationAvailable
=== "function") {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.

@ashwin31
ashwin31 merged commit c202850 into master Aug 14, 2026
27 of 28 checks passed
@ashwin31
ashwin31 deleted the dev branch August 14, 2026 04:14

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 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.flows and extract enforcement “rungs” into reusable predicates.
  • Introduce tools/compile_catalogs.py and ship compiled .mo catalogs; 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.

Comment thread django_mfa/api/views.py
Comment on lines +263 to +264
@endpoint("POST", require_verified=False)
def verify_begin(request, factor_type):
Comment thread django_mfa/api/views.py
Comment on lines +276 to +277
@endpoint("POST", require_verified=False)
def verify_complete(request, factor_type):
Comment on lines +197 to +202
class VerifyTests(ApiTestCase):
def setUp(self):
super().setUp()
self.enroll_totp()
self.set_session_mfa(verified=False)

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