From a7e30cfce208b0457289f9d6a0acba485d07aed7 Mon Sep 17 00:00:00 2001 From: Sanjib Kumar Sen Date: Sat, 11 Jan 2025 20:42:04 +0600 Subject: [PATCH] auth is working --- bun.lockb | Bin 172058 -> 172458 bytes docker-compose.yaml | 6 +++++ ...e_ben_parker.sql => 0000_rich_reavers.sql} | 14 +++++----- drizzle/meta/0000_snapshot.json | 24 ++++++++++-------- drizzle/meta/_journal.json | 4 +-- package.json | 6 ++++- src/api/user/user.model.ts | 23 ----------------- src/db/index.ts | 2 +- src/db/model.ts | 7 ----- src/db/schema.ts | 12 +++++---- src/index.ts | 11 +++++--- src/lib/auth/auth-view.ts | 2 +- src/lib/auth/auth.ts | 16 +++++++++++- 13 files changed, 67 insertions(+), 60 deletions(-) rename drizzle/{0000_elite_ben_parker.sql => 0000_rich_reavers.sql} (68%) delete mode 100644 src/api/user/user.model.ts delete mode 100644 src/db/model.ts diff --git a/bun.lockb b/bun.lockb index 975d250498cbd04eeabc35d16d3a5fd48f7a369e..b1220bfc067062977d43b54adfebd8000ebdd030 100755 GIT binary patch delta 27543 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 diff --git a/docker-compose.yaml b/docker-compose.yaml index 6beeec5..637acfe 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -5,6 +5,8 @@ services: dockerfile: Dockerfile ports: - "3000:3000" + env_file: + - .env environment: - NODE_ENV=production - OTEL_EXPORTER_OTLP_ENDPOINT=http://tracing:4318 @@ -27,10 +29,14 @@ services: db: image: postgres:latest + env_file: + - .env environment: POSTGRES_USER: ${DB_USER} POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: ${DB_NAME} + ports: + - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data networks: diff --git a/drizzle/0000_elite_ben_parker.sql b/drizzle/0000_rich_reavers.sql similarity index 68% rename from drizzle/0000_elite_ben_parker.sql rename to drizzle/0000_rich_reavers.sql index 64f5981..7a0e6df 100644 --- a/drizzle/0000_elite_ben_parker.sql +++ b/drizzle/0000_rich_reavers.sql @@ -1,4 +1,6 @@ -CREATE TABLE "account" ( +CREATE SCHEMA "auth"; +--> statement-breakpoint +CREATE TABLE "auth"."account" ( "id" text PRIMARY KEY NOT NULL, "account_id" text NOT NULL, "provider_id" text NOT NULL, @@ -14,7 +16,7 @@ CREATE TABLE "account" ( "updated_at" timestamp NOT NULL ); --> statement-breakpoint -CREATE TABLE "session" ( +CREATE TABLE "auth"."session" ( "id" text PRIMARY KEY NOT NULL, "expires_at" timestamp NOT NULL, "token" text NOT NULL, @@ -26,7 +28,7 @@ CREATE TABLE "session" ( CONSTRAINT "session_token_unique" UNIQUE("token") ); --> statement-breakpoint -CREATE TABLE "user" ( +CREATE TABLE "auth"."user" ( "id" text PRIMARY KEY NOT NULL, "name" text NOT NULL, "email" text NOT NULL, @@ -37,7 +39,7 @@ CREATE TABLE "user" ( CONSTRAINT "user_email_unique" UNIQUE("email") ); --> statement-breakpoint -CREATE TABLE "verification" ( +CREATE TABLE "auth"."verification" ( "id" text PRIMARY KEY NOT NULL, "identifier" text NOT NULL, "value" text NOT NULL, @@ -46,5 +48,5 @@ CREATE TABLE "verification" ( "updated_at" timestamp ); --> statement-breakpoint -ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint -ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action; \ No newline at end of file +ALTER TABLE "auth"."account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "auth"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "auth"."session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "auth"."user"("id") ON DELETE no action ON UPDATE no action; \ No newline at end of file diff --git a/drizzle/meta/0000_snapshot.json b/drizzle/meta/0000_snapshot.json index df9dd9b..6fff69e 100644 --- a/drizzle/meta/0000_snapshot.json +++ b/drizzle/meta/0000_snapshot.json @@ -1,12 +1,12 @@ { - "id": "f4717319-16e8-43a1-8b25-12a12964c98f", + "id": "1ada386b-032f-4c0c-a867-e25f2e921167", "prevId": "00000000-0000-0000-0000-000000000000", "version": "7", "dialect": "postgresql", "tables": { - "public.account": { + "auth.account": { "name": "account", - "schema": "", + "schema": "auth", "columns": { "id": { "name": "id", @@ -93,6 +93,7 @@ "name": "account_user_id_user_id_fk", "tableFrom": "account", "tableTo": "user", + "schemaTo": "auth", "columnsFrom": [ "user_id" ], @@ -109,9 +110,9 @@ "checkConstraints": {}, "isRLSEnabled": false }, - "public.session": { + "auth.session": { "name": "session", - "schema": "", + "schema": "auth", "columns": { "id": { "name": "id", @@ -168,6 +169,7 @@ "name": "session_user_id_user_id_fk", "tableFrom": "session", "tableTo": "user", + "schemaTo": "auth", "columnsFrom": [ "user_id" ], @@ -192,9 +194,9 @@ "checkConstraints": {}, "isRLSEnabled": false }, - "public.user": { + "auth.user": { "name": "user", - "schema": "", + "schema": "auth", "columns": { "id": { "name": "id", @@ -255,9 +257,9 @@ "checkConstraints": {}, "isRLSEnabled": false }, - "public.verification": { + "auth.verification": { "name": "verification", - "schema": "", + "schema": "auth", "columns": { "id": { "name": "id", @@ -306,7 +308,9 @@ } }, "enums": {}, - "schemas": {}, + "schemas": { + "auth": "auth" + }, "sequences": {}, "roles": {}, "policies": {}, diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 4e586cb..0ca736c 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -5,8 +5,8 @@ { "idx": 0, "version": "7", - "when": 1736255248333, - "tag": "0000_elite_ben_parker", + "when": 1736605568502, + "tag": "0000_rich_reavers", "breakpoints": true } ] diff --git a/package.json b/package.json index 39ae0d1..f5fa11e 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,13 @@ "test": "echo \"Error: no test specified\" && exit 1", "dev": "bun run --watch src/index.ts", "email": "email dev --dir src/emails", + "db:studio": "drizzle-kit studio", + "db:generate": "drizzle-kit generate", + "db:migrate": "drizzle-kit migrate", "build": "bun build --compile --minify-whitespace --minify-syntax --target bun --outfile server ./src/index.ts" }, "dependencies": { + "@elysiajs/cors": "^1.2.0", "@elysiajs/opentelemetry": "^1.2.0", "@elysiajs/server-timing": "^1.2.0", "@elysiajs/swagger": "^1.2.0", @@ -37,4 +41,4 @@ "tsx": "^4.19.2" }, "module": "src/index.js" -} \ No newline at end of file +} diff --git a/src/api/user/user.model.ts b/src/api/user/user.model.ts deleted file mode 100644 index dbb100d..0000000 --- a/src/api/user/user.model.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { pgTable, varchar, timestamp } from "drizzle-orm/pg-core"; - -import { createId } from "@paralleldrive/cuid2"; -import { createInsertSchema } from "drizzle-typebox"; -import { t } from "elysia"; - -export const user = pgTable("user", { - id: varchar("id") - .$defaultFn(() => createId()) - .primaryKey(), - username: varchar("username").notNull().unique(), - password: varchar("password").notNull(), - email: varchar("email").notNull().unique(), - salt: varchar("salt", { length: 64 }).notNull(), - createdAt: timestamp("created_at").defaultNow().notNull(), -}); - -const _createUser = createInsertSchema(user, { - email: t.String({ format: "email" }), -}); - -// ✅ This works, by referencing the type from `drizzle-typebox` -export const createUserType = t.Omit(_createUser, ["id", "salt", "createdAt"]); diff --git a/src/db/index.ts b/src/db/index.ts index eeef779..53dcac8 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -1,4 +1,4 @@ import "dotenv/config"; import { drizzle } from "drizzle-orm/node-postgres"; -const db = drizzle(process.env.DATABASE_URL!); +export const db = drizzle(process.env.DATABASE_URL!); diff --git a/src/db/model.ts b/src/db/model.ts deleted file mode 100644 index d50a294..0000000 --- a/src/db/model.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { createUserType } from "../api/user/user.model"; - -export const db = { - insert: { - user: createUserType, - }, -}; diff --git a/src/db/schema.ts b/src/db/schema.ts index 4214f12..61600f0 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -1,6 +1,8 @@ -import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core"; +import { pgTable, pgSchema, text, timestamp, boolean } from "drizzle-orm/pg-core"; -export const user = pgTable("user", { +export const auth_schema = pgSchema("auth") + +export const user = auth_schema.table("user", { id: text("id").primaryKey(), name: text("name").notNull(), email: text("email").notNull().unique(), @@ -10,7 +12,7 @@ export const user = pgTable("user", { updatedAt: timestamp("updated_at").notNull(), }); -export const session = pgTable("session", { +export const session = auth_schema.table("session", { id: text("id").primaryKey(), expiresAt: timestamp("expires_at").notNull(), token: text("token").notNull().unique(), @@ -23,7 +25,7 @@ export const session = pgTable("session", { .references(() => user.id), }); -export const account = pgTable("account", { +export const account = auth_schema.table("account", { id: text("id").primaryKey(), accountId: text("account_id").notNull(), providerId: text("provider_id").notNull(), @@ -41,7 +43,7 @@ export const account = pgTable("account", { updatedAt: timestamp("updated_at").notNull(), }); -export const verification = pgTable("verification", { +export const verification = auth_schema.table("verification", { id: text("id").primaryKey(), identifier: text("identifier").notNull(), value: text("value").notNull(), diff --git a/src/index.ts b/src/index.ts index 11fd30f..669072b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,22 +2,27 @@ import { Elysia } from "elysia"; import { swagger } from "@elysiajs/swagger"; import { opentelemetry } from "@elysiajs/opentelemetry"; import { serverTiming } from "@elysiajs/server-timing"; - +import { cors } from '@elysiajs/cors' import { note } from "./api/note/note.route"; import { betterAuthView } from "./lib/auth/auth-view"; import { userMiddleware, userInfo } from "./middlewares/auth-middleware"; const app = new Elysia() + .use(cors()) .use(opentelemetry()) - .use(swagger()) + .use(swagger({ + path: "/docs", + })) .use(serverTiming()) .onError(({ error, code }) => { if (code === "NOT_FOUND") return "Not Found :("; console.error(error); }) - .use(note) .derive(({ request }) => userMiddleware(request)) .all("/api/auth/*", betterAuthView) + .use(note) .get("/user", ({ user, session }) => userInfo(user, session)); app.listen(3000); + +console.log("Server is running on: http://localhost:3000") diff --git a/src/lib/auth/auth-view.ts b/src/lib/auth/auth-view.ts index 5bca005..0a76a8a 100644 --- a/src/lib/auth/auth-view.ts +++ b/src/lib/auth/auth-view.ts @@ -1,4 +1,4 @@ -import { Context, Elysia } from "elysia"; +import { Context } from "elysia"; import { auth } from "./auth"; export const betterAuthView = (context: Context) => { diff --git a/src/lib/auth/auth.ts b/src/lib/auth/auth.ts index dc116b6..226c052 100644 --- a/src/lib/auth/auth.ts +++ b/src/lib/auth/auth.ts @@ -1,14 +1,28 @@ import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; -import { db } from "../../db/model"; +import { db } from "../../db/index"; +import { openAPI } from "better-auth/plugins" +import { user, account, verification, session } from "../../db/schema"; + export const auth = betterAuth({ database: drizzleAdapter(db, { // We're using Drizzle as our database provider: "pg", + schema: { + user: user, + session: session, + account: account, + verification: verification + } }), emailAndPassword: { enabled: true, // If you want to use email and password auth }, + plugins: [ + openAPI({ + path: "/docs", + }), + ], socialProviders: { /* * We're using Google and Github as our social provider,