Implement email change

This commit is contained in:
adilallo
2026-04-26 07:47:25 -06:00
parent 68517796a9
commit 0ce05372bf
15 changed files with 1072 additions and 13 deletions
@@ -0,0 +1,23 @@
-- CreateTable
CREATE TABLE "EmailChangeToken" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"newEmail" TEXT NOT NULL,
"tokenHash" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3) NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "EmailChangeToken_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "EmailChangeToken_userId_key" ON "EmailChangeToken"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "EmailChangeToken_tokenHash_key" ON "EmailChangeToken"("tokenHash");
-- CreateIndex
CREATE INDEX "EmailChangeToken_newEmail_idx" ON "EmailChangeToken"("newEmail");
-- AddForeignKey
ALTER TABLE "EmailChangeToken" ADD CONSTRAINT "EmailChangeToken_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+19 -3
View File
@@ -13,9 +13,25 @@ model User {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
sessions Session[]
draft RuleDraft?
rules PublishedRule[]
sessions Session[]
draft RuleDraft?
rules PublishedRule[]
/// At most one pending verified email change (CR-103).
emailChangeToken EmailChangeToken?
}
/// Pending email change: user must open verify link sent to `newEmail` (CR-103).
/// Separate from `MagicLinkToken` so sign-in and email-change flows cannot be confused.
model EmailChangeToken {
id String @id @default(cuid())
userId String @unique
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
newEmail String
tokenHash String @unique
expiresAt DateTime
createdAt DateTime @default(now())
@@index([newEmail])
}
model Session {