Users can turn on 2FA from Profile & Security and receive a 6-digit login code by email or WhatsApp, with a "trust this device for 30 days" option. Admins can reset it for a locked-out user, and the self-service kiosk handles the code step at setup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
63 lines
2.1 KiB
SQL
63 lines
2.1 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "TwoFactorMethod" AS ENUM ('email', 'whatsapp');
|
|
|
|
-- AlterEnum
|
|
-- This migration adds more than one value to an enum.
|
|
-- With PostgreSQL versions 11 and earlier, this is not possible
|
|
-- in a single migration. This can be worked around by creating
|
|
-- multiple migrations, each migration adding only one value to
|
|
-- the enum.
|
|
|
|
|
|
ALTER TYPE "SecurityEventType" ADD VALUE 'two_factor_enabled';
|
|
ALTER TYPE "SecurityEventType" ADD VALUE 'two_factor_disabled';
|
|
|
|
-- AlterTable
|
|
ALTER TABLE "User" ADD COLUMN "twoFactorEnabled" BOOLEAN NOT NULL DEFAULT false,
|
|
ADD COLUMN "twoFactorMethod" "TwoFactorMethod";
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "TwoFactorChallenge" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"purpose" TEXT NOT NULL,
|
|
"method" "TwoFactorMethod" NOT NULL,
|
|
"codeHash" TEXT NOT NULL,
|
|
"attempts" INTEGER NOT NULL DEFAULT 0,
|
|
"lastSentAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
"usedAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "TwoFactorChallenge_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "TrustedDevice" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"tokenHash" TEXT NOT NULL,
|
|
"device" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"lastUsedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "TrustedDevice_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "TwoFactorChallenge_userId_idx" ON "TwoFactorChallenge"("userId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "TrustedDevice_tokenHash_key" ON "TrustedDevice"("tokenHash");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "TrustedDevice_userId_idx" ON "TrustedDevice"("userId");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "TwoFactorChallenge" ADD CONSTRAINT "TwoFactorChallenge_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "TrustedDevice" ADD CONSTRAINT "TrustedDevice_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|