docs(website): unique, changeable, verifiable email addresses (engagement Phase 1b)
Companion to website#<pr>. Records Phase 1b as built, and corrects two things
the plan got wrong before anyone builds on them.
ENGAGEMENT.md
- Phase 1b step 2 said to pin the index to a case-insensitive collation. Every
_ci collation MariaDB offers here is also accent-insensitive, so that index
would refuse jose@x.com once josé@x.com existed and the de-duplication would
have cleared a legitimate account's address. The as-built block records the
generated-column design that shipped instead, and the second-order version of
the same bug that a seeded fixture caught in the de-dupe query itself.
- §0.6 named two callers of isDuplicateUsername(). There are five, and the
three it omits fail worse than the two it names.
BACKEND_DESIGN.md — the users table (already stale: it predated the player
account work), plus email_verifications and email_dedupe_report, and the five
new routes.
UPGRADE_NOTES.md — an operator entry, because the de-duplication is the kind of
quiet change this file exists for: nothing breaks, and the affected users find
out the next time they try to reset a password.
api-route-inventory.json — regenerated from the manifest; still ungated.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -13,6 +13,71 @@ action, whether it is required, and what happens if you do nothing.
|
||||
|
||||
---
|
||||
|
||||
## Email addresses are now unique, and some accounts may lose theirs
|
||||
|
||||
**Required only if the dashboard says so.** Engagement Phase 1b.
|
||||
|
||||
### What changed
|
||||
|
||||
An account's email address is now the destination for account recovery and, in time, for notification
|
||||
mail, so an address may belong to **one account only**. Until now it could repeat — SSO sign-up wrote
|
||||
whatever address the provider returned, without checking — so a database that has been running with
|
||||
SSO enabled may well hold duplicates.
|
||||
|
||||
Users can now also **set and change their own address**, under *Account → Email address*, confirming
|
||||
it by opening a link. Before this there was no way for anyone to change their own address at all.
|
||||
|
||||
### What the upgrade does on first boot
|
||||
|
||||
Nothing you need to trigger, and **no account is deleted**. Where several accounts share an address:
|
||||
|
||||
- the **earliest-created** account keeps it — not the "verified" one, because SSO used to mark an
|
||||
address verified merely for existing, so that flag cannot arbitrate anything;
|
||||
- every later account has its address **cleared** (set to nothing) and is listed in a report;
|
||||
- the dashboard then shows a warning naming how many accounts were affected.
|
||||
|
||||
Case is folded — `Foo@x.com` and `foo@x.com` are the same mailbox — but **accents are not**:
|
||||
`josé@x.com` and `jose@x.com` are correctly treated as two different addresses.
|
||||
|
||||
### What you have to do
|
||||
|
||||
If the warning appears, open **Admin → Users** and read the report. It names each affected account and
|
||||
the address it lost. **Those users are the reason this warning exists:** they can still sign in
|
||||
normally, but they can no longer receive password-reset or notification email until they set a new
|
||||
address themselves, and nothing tells them that. Contact them, and point them at *Account → Email
|
||||
address*.
|
||||
|
||||
Dismissing the warning keeps the report — it is the record of what the upgrade did, and the only place
|
||||
the lost addresses survive.
|
||||
|
||||
### Verification email
|
||||
|
||||
Confirmation links are sent through the same transport as everything else, so **if outbound email is
|
||||
not configured, nobody can confirm an address.** The screen says so honestly rather than claiming a
|
||||
mail was sent. If you have not configured SMTP yet, see the entry below first.
|
||||
|
||||
### The verification setting
|
||||
|
||||
A new setting, *require a confirmed address before sending notification email*, is seeded **off on an
|
||||
existing deployment** and **on for a fresh install**. The asymmetry is deliberate: switching it on
|
||||
retroactively would silently stop mailing every user who had already opted in, on the day you
|
||||
upgraded. Nothing reads it yet — it takes effect when engagement notifications ship — so there is no
|
||||
hurry to change it.
|
||||
|
||||
### If you do nothing
|
||||
|
||||
The de-duplication has already run; it runs on the first boot whether or not you read this. What you
|
||||
lose by ignoring it is the chance to tell the affected users, who will otherwise discover it the next
|
||||
time they try to reset a password.
|
||||
|
||||
### Data
|
||||
|
||||
Nothing is dropped and no row is deleted. `users` gains `email_norm` (a generated lowercase copy of
|
||||
`email`, which carries the uniqueness index) and `email_pending`. Two tables are added:
|
||||
`email_verifications` and `email_dedupe_report`. Cleared addresses survive in the report.
|
||||
|
||||
---
|
||||
|
||||
## Outbound email: the Gmail connect flow is gone; configure SMTP
|
||||
|
||||
**Required, if this deployment currently sends email.** Engagement Phase 1.
|
||||
|
||||
Reference in New Issue
Block a user