docs(website): §7 rewritten for SMTP, plus an upgrade-notes home
Engagement Phase 1's documentation (ENGAGEMENT.md §6.0b, row 1). BACKEND_DESIGN.md §7 is REWRITTEN rather than amended, as the plan requires: it documented Gmail OAuth2 as the mechanism. It now covers the transport registry and why credentialFields is a single declaration three consumers read, the credential blob and its fail-safe decrypt, the no-phone-home rule and its CI guardrail, the three SMTP postures, why Send test is the only verification left, the five failure contracts, and the silent upgrade. The §2 tree, the PR-4 route-count note, the contact row and the dashboard row are corrected alongside it — the dashboard now returns warnings[]. UPGRADE_NOTES.md is new, and is the home for every later phase's operator note as well (1b, 6, 10 and 13 each owe one). Newest first, and scoped deliberately: an upgrade that needs nothing does not get an entry. The entries worth writing are the ones that fail QUIETLY, which is exactly what the Gmail removal does — mail stops, nothing errors, and the only signal is a dashboard warning. ENGAGEMENT.md records Phase 1 as built, with the four things that are not what the plan says: only the transport half of §3.1 was built (a channel nothing calls is a shape frozen too early), `enabled` now gates every sender where it used to gate none of the direct ones, the G22 warning reads the deprecated column on purpose, and `npm run swagger` had to be fixed first — the "per-file route limit" phases 8 and 9 recorded does not exist, and the real rule matters to every later phase here, all of which add routes. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
74
website/UPGRADE_NOTES.md
Normal file
74
website/UPGRADE_NOTES.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Upgrade notes — website
|
||||
|
||||
**Operator-facing. Newest first.** One entry per change that requires an operator to *do* something,
|
||||
or that changes behaviour they would otherwise discover by accident.
|
||||
|
||||
Most upgrades need nothing: the schema is replayed on every boot with `IF NOT EXISTS` migrations, and
|
||||
a deployment that pulls a new image and restarts is done. This file exists for the exceptions — and
|
||||
the exceptions worth writing down are almost always the ones that **fail quietly**, because a loud
|
||||
failure announces itself and a quiet one does not.
|
||||
|
||||
**Read the entries between the version you are on and the version you are moving to.** Each names the
|
||||
action, whether it is required, and what happens if you do nothing.
|
||||
|
||||
---
|
||||
|
||||
## Outbound email: the Gmail connect flow is gone; configure SMTP
|
||||
|
||||
**Required, if this deployment currently sends email.** Engagement Phase 1.
|
||||
|
||||
### What changed
|
||||
|
||||
The "Connect Gmail" consent flow has been **removed**. Email now sends through an ordinary mail
|
||||
transport whose credentials an admin types in — SMTP is the baseline and the only transport shipped.
|
||||
|
||||
Removed with it: `GET /api/v1/admin/email/connect/start`, `GET /api/v1/admin/email/connect/callback`,
|
||||
and email's reuse of the `google` authentication provider's client id and secret. That reuse is worth
|
||||
a sentence of its own, because it was a coupling nobody could see: rotating the Google **SSO** secret
|
||||
silently broke outbound **mail**, with nothing on either screen relating the two. Single sign-on is
|
||||
otherwise unaffected — the `google` provider row exists for SSO in its own right and is untouched.
|
||||
|
||||
### What you must do
|
||||
|
||||
On the first boot after the upgrade, `email_config.transport` backfills to `smtp` with **no
|
||||
credentials**. Until you supply some, **no mail is sent** — and nothing errors, because every sender
|
||||
is written to degrade politely:
|
||||
|
||||
- the contact form falls back to a `mailto:` link,
|
||||
- an invite returns the accept link for you to send by hand,
|
||||
- a password reset still answers its usual generic success,
|
||||
- Team notifications are logged and dropped.
|
||||
|
||||
That is the risk this note exists for: **email stops and nothing complains.** The admin dashboard
|
||||
shows a warning while it is true, and the warning goes away by itself once a credential is saved.
|
||||
|
||||
Go to **Admin → Settings → Email**, choose the posture that fits, then use **Send test** — which is
|
||||
now the real verification of the whole configuration, not a formality.
|
||||
|
||||
| Posture | Settings | Notes |
|
||||
| --- | --- | --- |
|
||||
| **A relay** — recommended | The relay's host, port `587`, *Implicit TLS* **off**, your API key as the password | Mailgun, SES, Postmark and equivalents. Reputation, DKIM and bounce handling are the relay's problem. The right answer for anything with volume |
|
||||
| **Gmail over SMTP** — the shortest migration | `smtp.gmail.com`, port `587`, *Implicit TLS* **off**, your Google address as the username, and an **app password** | This is the direct replacement for the removed connect flow. It needs an [app password](https://support.google.com/accounts/answer/185833) — 2-Step Verification must be on, and your ordinary account password will not work. Google's per-day send caps apply |
|
||||
| **Your own MTA** | Its host, port `25`, *Implicit TLS* **off**, username and password left blank | For an operator already running mail on the same host |
|
||||
|
||||
Two fields cause most failures:
|
||||
|
||||
- **Implicit TLS** is *on* only for port **465**. On port 587 leave it **off** — the connection still
|
||||
upgrades to TLS, via STARTTLS. Port 587 with it on does not error; it hangs.
|
||||
- **Send from** is now typed by you rather than read back from Google, so nothing guarantees the
|
||||
server will accept it. It must be an address the account is allowed to send as, or the mail is
|
||||
refused for SPF/DMARC reasons that look like nothing at all. Send test names this specifically when
|
||||
it happens.
|
||||
|
||||
### If you do nothing
|
||||
|
||||
Mail stays off. Nothing breaks and no data is lost — the site, the admin panel, logins, SSO and the
|
||||
shard integration all behave exactly as before. The dashboard warning stays up until you either
|
||||
configure a transport or press **Clear credentials**, which is how you say "this deployment
|
||||
deliberately sends no mail".
|
||||
|
||||
### Data
|
||||
|
||||
Nothing is dropped. `email_config` gains `transport`, `credential_enc` and `reply_to`; the old
|
||||
`provider` and `refresh_token_enc` columns are kept but no longer read. Your stored Gmail refresh
|
||||
token is not used again and is cleared the first time you press **Clear credentials**.
|
||||
Reference in New Issue
Block a user