accounts app
User accounts, password management, email verification, passkey (WebAuthn) sign-in, and GDPR-compliant data export / account deletion.
Models (6)
User— extended Django user with UUID PK, email-as-username, encrypted phoneUserEmail— secondary verified emails for one user; SSO uses these for matchingUserConsent— captures consent template acceptances (privacy / terms / marketing / analytics)DataExport— async data-export job state (status, S3 URL, expires_at)WebAuthnCredential— stored passkey credential (credential_id, public_key, sign_count, friendly name, last_used_at)PasskeyEnrollmentDismissal— tracks "remind me later" for the post-login passkey enrollment prompt
Key endpoints
| URL | Purpose |
|---|---|
POST /api/auth/register/ | Self-signup with email + password |
POST /api/auth/login/ | Email + password → sets JWT cookies |
POST /api/auth/logout/ | Clears cookies, blacklists refresh token |
GET /api/auth/me/ | Current user profile |
PATCH /api/auth/me/ | Update first/last name, phone |
POST /api/auth/me/password/ | Change password |
POST /api/auth/me/emails/add/ | Add a secondary email |
POST /api/auth/me/emails/verify/ | Verify a secondary email via token |
POST /api/auth/password-reset/request/ | Request reset email |
POST /api/auth/password-reset/confirm/ | Submit new password with token |
POST /api/auth/me/export/ | Trigger GDPR data export (Celery → S3) |
POST /api/auth/me/delete/ | Request account deletion (30-day grace period) |
POST /api/auth/admin/password-reset/ | Admin-initiated password reset (org admin only) |
POST /api/auth/passkey/register/begin/ | Build WebAuthn registration options (signed-in user) |
POST /api/auth/passkey/register/complete/ | Verify attestation, persist WebAuthnCredential |
POST /api/auth/passkey/authenticate/begin/ | Build discoverable WebAuthn assertion options (no auth required) |
POST /api/auth/passkey/authenticate/complete/ | Verify assertion, look up credential, issue JWT |
GET /api/auth/passkey/credentials/ | List the current user's passkeys |
PATCH /api/auth/passkey/credentials/<id>/ | Rename a passkey |
DELETE /api/auth/passkey/credentials/<id>/ | Revoke a passkey |
GET /api/auth/passkey/prompt-status/ | Should the post-login enrollment prompt show? |
POST /api/auth/passkey/dismiss-prompt/ | "Remind me later" — sets 30-day cooldown |
Permissions
IsAuthenticated— most endpointsAllowAny— register, login, password reset request (rate-throttled)IsNationalAdmin— admin password reset
Background tasks
send_email_verification(user_email_id)— sends verification emailsend_temporary_password_notification(user_id, temp_password)— admin reset flowexport_user_data(data_export_id)— bundles all user data, gzips, uploads to S3, generates presigned URL valid for 7 days
External integrations
- AWS S3 (data export storage via boto3)
- Email backend (configured at
apps.platform.PlatformEmailConfig)
Signals
post_saveonUser— auto-createsUserEmailrow from primary email
Notable patterns
Account deletion grace period
POST /api/auth/me/delete/ doesn't immediately delete. It:
- Sets
User.deletion_requested_at = now() - Sends confirmation email with a "cancel" link
- After 30 days,
prune_pending_deletionstask scrubs the account
Cancelling: signing in within 30 days clears deletion_requested_at.
Password hashing
Production uses Django's default PBKDF2 with 870K iterations. Tests override to MD5 via PASSWORD_HASHERS to keep tests fast.
Throttling
| Endpoint | Throttle |
|---|---|
register/ | account_request (3/hour prod) |
login/, logout/ | auth (10/min prod) |
password-reset/request/ | password_reset (5/hour prod) |
admin/password-reset/ | admin_password_reset_target (10/hour prod) |
passkey/*/begin/ | passkey_begin (10/min prod) |
passkey/*/complete/ | passkey_complete (5/min prod) |
Code paths
- Models:
backend/apps/accounts/models.py - Views:
backend/apps/accounts/views.py,backend/apps/accounts/webauthn_views.py - Serializers:
backend/apps/accounts/serializers.py - URLs:
backend/apps/accounts/urls.py - Tasks:
backend/apps/accounts/tasks.py - Tests:
backend/apps/accounts/tests/+backend/apps/accounts/tests_webauthn.py