fix(auth): sync profile email verification with auth user (#726)

* fix(auth): sync profile email verification with auth user

Repair stale profile rows where user.email_verified is true but
profile.is_email_verified is false, which blocked the LMS with the
verify-email modal while send-verification-email returned
EMAIL_IS_ALREADY_VERIFIED.

Sync on session login, account fetch, and user update; update the
modal to respect session emailVerified and self-heal on that error.

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* chore(db): add backfill script for stale profile email verification

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* docs(db): document profile email verification backfill command

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* fix(auth): never demote profile email verification on sync

Greptile: self-hosted first signup can verify profile before
user.email_verified is set. Sync now only promotes verification.

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* fix(auth): promote user.email_verified when profile is verified

Self-hosted bootstrap and other flows can set profile.is_email_verified
before user.email_verified. Sync and createProfileHook now update both
tables when promoting verification.

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
This commit is contained in:
Rotimi Best
2026-07-11 06:38:28 +01:00
committed by GitHub
co-authored by Rotimi Best Cursor Agent
parent 2fb6b1c477
commit c0f82d9573
10 changed files with 289 additions and 34 deletions
+20
View File
@@ -66,6 +66,26 @@ Requires `DATABASE_URL` or `PRIVATE_DATABASE_URL` in the environment. The script
cp .env.example .env # then set DATABASE_URL for your DB
```
#### db:backfill-profile-email-verification
Repairs stale `profile.is_email_verified` rows where the auth user is already verified (`user.email_verified = true`) or has a linked OAuth/SSO account, but the profile flag was never synced. Use after the auth/profile verification mismatch fix, or when users are blocked by the verify-email modal while `send-verification-email` returns `EMAIL_IS_ALREADY_VERIFIED`.
Dry run (lists affected count and a sample; makes no changes):
```bash
pnpm db:backfill-profile-email-verification
# or from repo root:
pnpm --filter @cio/db db:backfill-profile-email-verification
```
Apply updates:
```bash
pnpm db:backfill-profile-email-verification -- --execute
```
The script prints how many profiles were updated and verifies zero mismatches remain.
## Seeding
The seed script populates the database with demo data for local development. It is idempotent — running it multiple times is safe; existing records are skipped.