From 9dc2d9f320dcbd8ad3dd7752d41971cd3aa46b75 Mon Sep 17 00:00:00 2001 From: Sanjib Sen Date: Wed, 15 Jan 2025 18:15:33 +0600 Subject: [PATCH] organized --- .env.services.example | 2 +- auth-schema.ts | 51 ------------------- docker-compose.services.yaml | 10 ++-- package.json | 1 + src/db/schema.ts | 99 ++++++++++++++++++------------------ src/lib/auth/auth.ts | 19 +++++++ 6 files changed, 76 insertions(+), 106 deletions(-) delete mode 100644 auth-schema.ts diff --git a/.env.services.example b/.env.services.example index 17b1303..a5e5d49 100644 --- a/.env.services.example +++ b/.env.services.example @@ -1,4 +1,4 @@ -DB_USERNAME= +DB_USER= DB_PASSWORD= DB_PORT= diff --git a/auth-schema.ts b/auth-schema.ts deleted file mode 100644 index 4214f12..0000000 --- a/auth-schema.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core"; - -export const user = pgTable("user", { - id: text("id").primaryKey(), - name: text("name").notNull(), - email: text("email").notNull().unique(), - emailVerified: boolean("email_verified").notNull(), - image: text("image"), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), -}); - -export const session = pgTable("session", { - id: text("id").primaryKey(), - expiresAt: timestamp("expires_at").notNull(), - token: text("token").notNull().unique(), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), - ipAddress: text("ip_address"), - userAgent: text("user_agent"), - userId: text("user_id") - .notNull() - .references(() => user.id), -}); - -export const account = pgTable("account", { - id: text("id").primaryKey(), - accountId: text("account_id").notNull(), - providerId: text("provider_id").notNull(), - userId: text("user_id") - .notNull() - .references(() => user.id), - accessToken: text("access_token"), - refreshToken: text("refresh_token"), - idToken: text("id_token"), - accessTokenExpiresAt: timestamp("access_token_expires_at"), - refreshTokenExpiresAt: timestamp("refresh_token_expires_at"), - scope: text("scope"), - password: text("password"), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), -}); - -export const verification = pgTable("verification", { - id: text("id").primaryKey(), - identifier: text("identifier").notNull(), - value: text("value").notNull(), - expiresAt: timestamp("expires_at").notNull(), - createdAt: timestamp("created_at"), - updatedAt: timestamp("updated_at"), -}); diff --git a/docker-compose.services.yaml b/docker-compose.services.yaml index 9de4fcb..def4fa0 100644 --- a/docker-compose.services.yaml +++ b/docker-compose.services.yaml @@ -9,14 +9,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" + - "${DB_PORT}:5432" + env_file: + - .env.services volumes: - postgres_data:/var/lib/postgresql/data @@ -25,11 +25,11 @@ services: ports: - "9000:9000" - "9001:9001" + env_file: + - .env.services environment: MINIO_ROOT_USER: ${MINIO_ROOT_USER} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} - MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY} - MINIO_SECRET_KEY: ${MINIO_SECRET_KEY} command: server /data --console-address ":9001" volumes: - minio_data:/data diff --git a/package.json b/package.json index 084b80a..2a26265 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "dev": "bun run --watch src/index.ts", "email": "email dev --dir src/emails", "db:studio": "drizzle-kit studio", + "auth:generate": "bun x @better-auth/cli generate --config src/lib/auth/auth.ts --output src/db/schema.ts && drizzle-kit migrate", "db:check": "drizzle-kit check", "db:generate": "drizzle-kit generate", "db:migrate": "drizzle-kit migrate", diff --git a/src/db/schema.ts b/src/db/schema.ts index 61600f0..1de748d 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -1,53 +1,54 @@ -import { pgTable, pgSchema, text, timestamp, boolean } from "drizzle-orm/pg-core"; +import { pgTable, text, integer, timestamp, boolean } from "drizzle-orm/pg-core"; + +export const user = pgTable("user", { + id: text("id").primaryKey(), + name: text('name').notNull(), + email: text('email').notNull().unique(), + emailVerified: boolean('email_verified').notNull(), + image: text('image'), + createdAt: timestamp('created_at').notNull(), + updatedAt: timestamp('updated_at').notNull() + }); -export const auth_schema = pgSchema("auth") +export const session = pgTable("session", { + id: text("id").primaryKey(), + expiresAt: timestamp('expires_at').notNull(), + token: text('token').notNull().unique(), + createdAt: timestamp('created_at').notNull(), + updatedAt: timestamp('updated_at').notNull(), + ipAddress: text('ip_address'), + userAgent: text('user_agent'), + userId: text('user_id').notNull().references(()=> user.id) + }); -export const user = auth_schema.table("user", { - id: text("id").primaryKey(), - name: text("name").notNull(), - email: text("email").notNull().unique(), - emailVerified: boolean("email_verified").notNull(), - image: text("image"), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), -}); +export const account = pgTable("account", { + id: text("id").primaryKey(), + accountId: text('account_id').notNull(), + providerId: text('provider_id').notNull(), + userId: text('user_id').notNull().references(()=> user.id), + accessToken: text('access_token'), + refreshToken: text('refresh_token'), + idToken: text('id_token'), + accessTokenExpiresAt: timestamp('access_token_expires_at'), + refreshTokenExpiresAt: timestamp('refresh_token_expires_at'), + scope: text('scope'), + password: text('password'), + createdAt: timestamp('created_at').notNull(), + updatedAt: timestamp('updated_at').notNull() + }); -export const session = auth_schema.table("session", { - id: text("id").primaryKey(), - expiresAt: timestamp("expires_at").notNull(), - token: text("token").notNull().unique(), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), - ipAddress: text("ip_address"), - userAgent: text("user_agent"), - userId: text("user_id") - .notNull() - .references(() => user.id), -}); +export const verification = pgTable("verification", { + id: text("id").primaryKey(), + identifier: text('identifier').notNull(), + value: text('value').notNull(), + expiresAt: timestamp('expires_at').notNull(), + createdAt: timestamp('created_at'), + updatedAt: timestamp('updated_at') + }); -export const account = auth_schema.table("account", { - id: text("id").primaryKey(), - accountId: text("account_id").notNull(), - providerId: text("provider_id").notNull(), - userId: text("user_id") - .notNull() - .references(() => user.id), - accessToken: text("access_token"), - refreshToken: text("refresh_token"), - idToken: text("id_token"), - accessTokenExpiresAt: timestamp("access_token_expires_at"), - refreshTokenExpiresAt: timestamp("refresh_token_expires_at"), - scope: text("scope"), - password: text("password"), - createdAt: timestamp("created_at").notNull(), - updatedAt: timestamp("updated_at").notNull(), -}); - -export const verification = auth_schema.table("verification", { - id: text("id").primaryKey(), - identifier: text("identifier").notNull(), - value: text("value").notNull(), - expiresAt: timestamp("expires_at").notNull(), - createdAt: timestamp("created_at"), - updatedAt: timestamp("updated_at"), -}); +export const rateLimit = pgTable("rate_limit", { + id: text("id").primaryKey(), + key: text('key'), + count: integer('count'), + lastRequest: integer('last_request') + }); diff --git a/src/lib/auth/auth.ts b/src/lib/auth/auth.ts index e044be6..bb65fdb 100644 --- a/src/lib/auth/auth.ts +++ b/src/lib/auth/auth.ts @@ -18,6 +18,25 @@ export const auth = betterAuth({ verification: verification } }), + rateLimit: { + window: 60, + max: 100, + storage: "database", + modelName: "rateLimit", //optional by default "rateLimit" is used + customRules: { + "/sign-in/email": { + window: 3600 * 12, + max: 10, + }, + "/two-factor/*": async (request) => { + // custom function to return rate limit window and max + return { + window: 3600 * 12, + max: 10, + } + } + }, + }, emailAndPassword: { enabled: true, // If you want to use email and password auth requireEmailVerification: false,