Accounts

The accounts app is the identity and authentication layer. It is a shared app — it lives in the public schema, so a User is a single identity that spans every tenant. A user’s per-tenant role is tracked separately (see tenantMembership).

What it does

  • Email-based authenticationUser.USERNAME_FIELD = 'email'. There is no username; the email is the login identifier.

  • Magic-link (passwordless) loginMagicLink records power one-time sign-in links.

  • Multi-factor authenticationMultifactor supports TOTP and email-based 2FA. Whether 2FA is required is configurable per tenant/event.

  • Personnel filesPersonnelFile holds extended profile data for staff (legal name, emergency contact, etc.).

  • Password reset — dedicated reset flow.

  • OIDC / OAuth2 — Midsummer can act as both an OAuth consumer (SSO) and an OAuth provider. The OAuthDomainMiddleware routes /o/* to oauth2_provider on the configured global domain only.

Key models

User (email = USERNAME_FIELD)
  └─ PersonnelFile
MagicLink              # one-time passwordless sign-in
Multifactor            # TOTP / email 2FA enrollment
AuthenticationState    # tracks an in-progress login transaction (used by the login flow)
PasswordReset

How a login flows

The login views live in midsummer/login/. A typical email + password (or magic link) login creates an AuthenticationState that carries the user through to session/token establishment. After login, the UI is returned to the page it came from via a sanitized ?next= parameter (see the request-resolution concept).

Note

The ui/ SPA login page is Django-served (there is no Angular /login route in ui/). The tenantui/ SPA has both a Django-served /login/ and an Angular /login route guarded by tenant-admin.guard.ts.

Where to look

  • Models/auth views: accounts/models.py, accounts/views.py

  • Login flow + URL safe-redirect: midsummer/login/

  • OAuth wiring + global domain routing: midsummer/oauthurls.py, midsummer/middleware.py (OAuthDomainMiddleware)