Browse Source

feat(db): auth schema and migrations

Made-with: Cursor
feat/auth-user
npmrun 6 days ago
parent
commit
cd068d5863
  1. 72
      packages/drizzle-pkg/lib/schema/schema.ts
  2. 32
      packages/drizzle-pkg/migrations/0001_auth_user.sql
  3. 306
      packages/drizzle-pkg/migrations/meta/0001_snapshot.json
  4. 7
      packages/drizzle-pkg/migrations/meta/_journal.json

72
packages/drizzle-pkg/lib/schema/schema.ts

@ -1,8 +1,74 @@
import { integer, pgTable, varchar } from "drizzle-orm/pg-core"; import {
integer,
pgTable,
varchar,
timestamp,
text,
pgEnum,
uniqueIndex,
index,
} from "drizzle-orm/pg-core";
export const authChallengeTypeEnum = pgEnum("auth_challenge_type", [
"email_verify",
"password_reset",
]);
export const usersTable = pgTable("users_table", { export const usersTable = pgTable("users_table", {
id: integer().primaryKey().generatedAlwaysAsIdentity(), id: integer().primaryKey().generatedAlwaysAsIdentity(),
name: varchar().notNull(), name: varchar({ length: 255 }).notNull(),
age: integer().notNull(), age: integer().notNull(),
email: varchar().notNull().unique(), email: varchar({ length: 320 }).notNull().unique(),
passwordHash: text("password_hash").notNull(),
emailVerifiedAt: timestamp("email_verified_at", {
withTimezone: true,
}),
sessionVersion: integer("session_version").notNull().default(0),
createdAt: timestamp("created_at", { withTimezone: true })
.notNull()
.defaultNow(),
updatedAt: timestamp("updated_at", { withTimezone: true })
.notNull()
.defaultNow(),
}); });
export const authChallengesTable = pgTable(
"auth_challenges",
{
id: integer().primaryKey().generatedAlwaysAsIdentity(),
userId: integer("user_id")
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
type: authChallengeTypeEnum("type").notNull(),
tokenHash: varchar("token_hash", { length: 64 }).notNull(),
expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
consumedAt: timestamp("consumed_at", { withTimezone: true }),
createdAt: timestamp("created_at", { withTimezone: true })
.notNull()
.defaultNow(),
},
(t) => ({
tokenHashIdx: index("auth_challenges_token_hash_idx").on(t.tokenHash),
}),
);
export const linkedAccountsTable = pgTable(
"linked_accounts",
{
id: integer().primaryKey().generatedAlwaysAsIdentity(),
userId: integer("user_id")
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
provider: varchar({ length: 64 }).notNull(),
providerUserId: varchar("provider_user_id", { length: 255 }).notNull(),
createdAt: timestamp("created_at", { withTimezone: true })
.notNull()
.defaultNow(),
},
(t) => ({
providerUserUnique: uniqueIndex("linked_accounts_provider_uid").on(
t.provider,
t.providerUserId,
),
}),
);

32
packages/drizzle-pkg/migrations/0001_auth_user.sql

@ -0,0 +1,32 @@
CREATE TYPE "public"."auth_challenge_type" AS ENUM('email_verify', 'password_reset');--> statement-breakpoint
CREATE TABLE "auth_challenges" (
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "auth_challenges_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
"user_id" integer NOT NULL,
"type" "auth_challenge_type" NOT NULL,
"token_hash" varchar(64) NOT NULL,
"expires_at" timestamp with time zone NOT NULL,
"consumed_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE "linked_accounts" (
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "linked_accounts_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
"user_id" integer NOT NULL,
"provider" varchar(64) NOT NULL,
"provider_user_id" varchar(255) NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
ALTER TABLE "users_table" ALTER COLUMN "name" SET DATA TYPE varchar(255);--> statement-breakpoint
ALTER TABLE "users_table" ALTER COLUMN "email" SET DATA TYPE varchar(320);--> statement-breakpoint
ALTER TABLE "users_table" ADD COLUMN "password_hash" text;--> statement-breakpoint
UPDATE "users_table" SET "password_hash" = '$2b$10$eUiiFSTi9m98IWSuXJ80jun3VctJ0pKL44rRwvHT.9WOfxvc7r6Ey' WHERE "password_hash" IS NULL;--> statement-breakpoint
ALTER TABLE "users_table" ALTER COLUMN "password_hash" SET NOT NULL;--> statement-breakpoint
ALTER TABLE "users_table" ADD COLUMN "email_verified_at" timestamp with time zone;--> statement-breakpoint
ALTER TABLE "users_table" ADD COLUMN "session_version" integer DEFAULT 0 NOT NULL;--> statement-breakpoint
ALTER TABLE "users_table" ADD COLUMN "created_at" timestamp with time zone DEFAULT now() NOT NULL;--> statement-breakpoint
ALTER TABLE "users_table" ADD COLUMN "updated_at" timestamp with time zone DEFAULT now() NOT NULL;--> statement-breakpoint
ALTER TABLE "auth_challenges" ADD CONSTRAINT "auth_challenges_user_id_users_table_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users_table"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "linked_accounts" ADD CONSTRAINT "linked_accounts_user_id_users_table_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users_table"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
CREATE INDEX "auth_challenges_token_hash_idx" ON "auth_challenges" USING btree ("token_hash");--> statement-breakpoint
CREATE UNIQUE INDEX "linked_accounts_provider_uid" ON "linked_accounts" USING btree ("provider","provider_user_id");

306
packages/drizzle-pkg/migrations/meta/0001_snapshot.json

@ -0,0 +1,306 @@
{
"id": "d83420ac-013e-46cd-b8b4-82360fa63544",
"prevId": "ccacc841-1a4a-434b-bfaa-8d18a9a641b2",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.auth_challenges": {
"name": "auth_challenges",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"identity": {
"type": "always",
"name": "auth_challenges_id_seq",
"schema": "public",
"increment": "1",
"startWith": "1",
"minValue": "1",
"maxValue": "2147483647",
"cache": "1",
"cycle": false
}
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "auth_challenge_type",
"typeSchema": "public",
"primaryKey": false,
"notNull": true
},
"token_hash": {
"name": "token_hash",
"type": "varchar(64)",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"consumed_at": {
"name": "consumed_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"auth_challenges_token_hash_idx": {
"name": "auth_challenges_token_hash_idx",
"columns": [
{
"expression": "token_hash",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"auth_challenges_user_id_users_table_id_fk": {
"name": "auth_challenges_user_id_users_table_id_fk",
"tableFrom": "auth_challenges",
"tableTo": "users_table",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.linked_accounts": {
"name": "linked_accounts",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"identity": {
"type": "always",
"name": "linked_accounts_id_seq",
"schema": "public",
"increment": "1",
"startWith": "1",
"minValue": "1",
"maxValue": "2147483647",
"cache": "1",
"cycle": false
}
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"provider": {
"name": "provider",
"type": "varchar(64)",
"primaryKey": false,
"notNull": true
},
"provider_user_id": {
"name": "provider_user_id",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"linked_accounts_provider_uid": {
"name": "linked_accounts_provider_uid",
"columns": [
{
"expression": "provider",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "provider_user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"linked_accounts_user_id_users_table_id_fk": {
"name": "linked_accounts_user_id_users_table_id_fk",
"tableFrom": "linked_accounts",
"tableTo": "users_table",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.users_table": {
"name": "users_table",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "integer",
"primaryKey": true,
"notNull": true,
"identity": {
"type": "always",
"name": "users_table_id_seq",
"schema": "public",
"increment": "1",
"startWith": "1",
"minValue": "1",
"maxValue": "2147483647",
"cache": "1",
"cycle": false
}
},
"name": {
"name": "name",
"type": "varchar(255)",
"primaryKey": false,
"notNull": true
},
"age": {
"name": "age",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "varchar(320)",
"primaryKey": false,
"notNull": true
},
"password_hash": {
"name": "password_hash",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email_verified_at": {
"name": "email_verified_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"session_version": {
"name": "session_version",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"users_table_email_unique": {
"name": "users_table_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {
"public.auth_challenge_type": {
"name": "auth_challenge_type",
"schema": "public",
"values": [
"email_verify",
"password_reset"
]
}
},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

7
packages/drizzle-pkg/migrations/meta/_journal.json

@ -8,6 +8,13 @@
"when": 1775935934813, "when": 1775935934813,
"tag": "0000_init", "tag": "0000_init",
"breakpoints": true "breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1776000315737,
"tag": "0001_auth_user",
"breakpoints": true
} }
] ]
} }
Loading…
Cancel
Save