Login identifiers were compared case-sensitively, so "John" and "john" were distinct accounts and a user could not log in unless they matched the exact casing used at registration. Convert users.username and users.email to the citext type (migration 165). citext compares case-insensitively while preserving the originally stored casing for display, so the existing unique constraints become case-insensitive and `WHERE username = $1` / `email = $1` lookups match regardless of case with no change to the query code itself. Also add auth.NormalizeUsername/NormalizeEmail (trim-only; case preserved), applied at the repository chokepoints (Create, Update, GetByUsername, GetByEmail) and before validation in the create paths, so surrounding whitespace no longer defeats matching or creates lookalike accounts. Verified non-destructively against the dev DB: mixed-case lookups resolve to the same row, case-variant inserts are rejected by the unique constraint, and the down migration cleanly reverts to text. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7 lines
312 B
SQL
7 lines
312 B
SQL
-- Revert username/email to case-sensitive text. The citext extension is left
|
|
-- installed: dropping it is unnecessary and would fail if any other object
|
|
-- ever depends on it.
|
|
ALTER TABLE public.users
|
|
ALTER COLUMN username TYPE text USING username::text,
|
|
ALTER COLUMN email TYPE text USING email::text;
|