Transactional email (Microsoft Graph)
Django's EMAIL_BACKEND is EMAW.backends.graph_email.GraphEmailBackend: it authenticates with MSAL (client credentials) and sends through the Microsoft Graph API as a Microsoft 365 mailbox. There is no SMTP anywhere.
| Code | EMAW/backends/graph_email.py |
| Env | MS_TENANT_ID, MS_CLIENT_ID, MS_CLIENT_SECRET, MS_SENDER_UPN (the mailbox, DEFAULT_FROM_EMAIL falls back to support@emaw-app.com), CONTACT_FORM_RECIPIENTS, STORE_ORDER_NOTIFY_RECIPIENTS, EVENTS_NOTIFY_RECIPIENTS, DONATIONS_NOTIFY_RECIPIENTS |
| Test | manage.py test_graph_email |
What goes through it
| Sent from | |
|---|---|
| Sign-up verification code, resend, change-email code | EMAW/views/auth.py |
| Password reset code | EMAW/views/auth.py |
| Website contact form | rest/contact/ → CONTACT_FORM_RECIPIENTS |
| Store order confirmation, shipped notice, staff order notification | store/tasks.py |
| Event registration confirmation (buyer and guests), leader emails, overbooked staff alert | events/tasks.py |
| Donation receipt, staff notification, failed-payment and cancelled-recurring notices | donations/tasks.py |
| Deposco problem notifications | deposco/tasks.py |
Marketing campaigns do not use Graph; see Marketing email (ACS).
Entra app registration
A single app registration in the everymanawarrior.com tenant with the application permission Mail.Send, restricted (by an Exchange application access policy) to the sender mailbox. The client secret expires; when verification emails stop arriving, check its expiry first. Rotate by creating a new secret in Entra and updating MS_CLIENT_SECRET in both environments' .env.
Test settings
EMAW_BACKEND.settings.test swaps in the locmem email backend, so tests assert on django.core.mail.outbox.