-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Feature - adding better auth for handling authentication and session management (server) #3446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
PurnenduMIshra129th
wants to merge
30
commits into
PalisadoesFoundation:develop-postgres
from
PurnenduMIshra129th:feature/betterAuth4
Closed
Changes from 3 commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
3a2f035
new commit
PurnenduMIshra129th 6277a88
fixed python workflow
PurnenduMIshra129th dbacceb
fixed test cases
PurnenduMIshra129th 6238cbe
Merge branch 'develop-postgres' of https://github.com/PalisadoesFound…
PurnenduMIshra129th 107c916
fixing code quality
PurnenduMIshra129th 1f6022d
fixed some type errors
PurnenduMIshra129th 093706f
fixed compose file in docker
PurnenduMIshra129th 12940aa
API_CORS_ORIGIN changed in compose file
PurnenduMIshra129th 0532750
fixed pinio pretty problem
PurnenduMIshra129th 7d74c83
Merge branch 'develop-postgres' of https://github.com/PalisadoesFound…
PurnenduMIshra129th d1996c1
fixed code quality
PurnenduMIshra129th b75e854
trying to fix code quality
PurnenduMIshra129th 0e02585
trying to fix code quality
PurnenduMIshra129th 8feec3e
fixed lockfile
PurnenduMIshra129th 3cc8b5a
not completed yet
PurnenduMIshra129th 40f2fe3
fixed all test cases
PurnenduMIshra129th 5bcc22d
fixed all test cases
PurnenduMIshra129th d8aee8b
Merge branch 'develop-postgres' of https://github.com/PalisadoesFound…
PurnenduMIshra129th 01077f4
fixed test cases
PurnenduMIshra129th 4fb3997
added test cases for createServer.test.ts for betterAuth
PurnenduMIshra129th 9b853c8
repushing code fix postgres connection not changed anything
PurnenduMIshra129th 92050b9
added test cases for auth.ts , db.ts , betterAuthSetUp.ts
PurnenduMIshra129th 05099e1
fixed test cases and added types to auth.spec ,db.spec
PurnenduMIshra129th 3529c04
added mocked database in createServer.ts
PurnenduMIshra129th 4b21bc4
added envConfig instead of process.env
PurnenduMIshra129th 4a058fa
fixed code quality
PurnenduMIshra129th 01fad41
added test host in db.ts
PurnenduMIshra129th 0f01aa6
reverted the db.ts addition of test_host
PurnenduMIshra129th a1b7af5
changed the createServer to testServer defined in test files which ca…
PurnenduMIshra129th f94000d
Merge branch 'develop-postgres' into feature/betterAuth4
palisadoes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
# Better Auth Integration with Fastify and GraphQL | ||
|
||
## Overview | ||
This document explains how **Better Auth** integrates with **Fastify** and **GraphQL** for authentication. It provides details on environment setup, database schema, middleware configuration, and how requests are handled. | ||
|
||
--- | ||
|
||
## 1. Setting Up Environment Variables | ||
Make sure you have the required environment variables in your `.env` file. The `BETTER_AUTH_SECRET` must be set, and its value can be generated from [this link](https://better-auth.vercel.app/docs/installation). | ||
|
||
### Required Environment Variables: | ||
```env | ||
BETTER_AUTH_SECRET=<your_generated_secret> | ||
API_POSTGRES_USER=<your_db_user> | ||
API_POSTGRES_PASSWORD=<your_db_password> | ||
API_POSTGRES_HOST=<your_db_host> | ||
API_POSTGRES_PORT=<your_db_port> | ||
API_POSTGRES_DATABASE=<your_db_name> | ||
API_CORS_ORIGIN = <your client URL> | ||
NODE_ENV=<Production or development or test> | ||
``` | ||
|
||
--- | ||
|
||
## 2. Connecting to PostgreSQL with Drizzle ORM | ||
|
||
We use **Drizzle ORM** to connect to the PostgreSQL database. The connection URL is dynamically constructed from environment variables. | ||
|
||
```typescript | ||
import dotenv from "dotenv"; | ||
import { drizzle } from "drizzle-orm/postgres-js"; | ||
import postgres from "postgres"; | ||
|
||
dotenv.config(); | ||
|
||
const DATABASE_URL = `postgres://${process.env.API_POSTGRES_USER}:${process.env.API_POSTGRES_PASSWORD}@${process.env.API_POSTGRES_HOST}:${process.env.API_POSTGRES_PORT}/${process.env.API_POSTGRES_DATABASE}`; | ||
|
||
const client = postgres(DATABASE_URL, { | ||
prepare: false, | ||
// debug: (connection, query, params) => { | ||
// console.log("Running SQL Query:", query); | ||
// console.log("📌 Query Parameters:", params); | ||
// }, | ||
}); | ||
|
||
// Connect Drizzle ORM | ||
export const db = drizzle(client); | ||
``` | ||
|
||
### Notes: | ||
- **Ensure `.env` variables are properly set** before running the application. | ||
- If you want to **debug SQL queries**, uncomment the `console.log` lines in the `debug` option. | ||
|
||
--- | ||
|
||
## 3. Database Schema & Migrations | ||
The required database tables for **Better Auth** are already created, and migration files are present. | ||
|
||
### Important Migrations: | ||
1. **Main Migration**: `20250122092015_sweet_scrambler.sql` | ||
2. **Better Auth Migration**: `20250303173255_cheerful_deadpool.sql` | ||
|
||
### To Apply Migrations: | ||
Run the following command to ensure all database changes are applied: | ||
```sh | ||
npm run apply_drizzle_migrations | ||
``` | ||
✅ If you have already migrated the **main migration file**, you only need to migrate `20250303173255_cheerful_deadpool.sql`. There is no need to manually create tables. | ||
|
||
--- | ||
|
||
## 4. Authentication Middleware | ||
To integrate **Better Auth** with Fastify, we redirect all `/api/auth/*` requests to `auth.ts`, where authentication logic is handled. | ||
|
||
### Updated `createServer` Code: | ||
```typescript | ||
fastify.all("/api/auth/*", async (req, reply) => { | ||
console.log(`✅ Route hit: ${req.method} ${req.url}`); | ||
|
||
const headers: Record<string, string> = {}; | ||
for (const [key, value] of Object.entries(req.headers)) { | ||
if (value) { | ||
headers[key] = Array.isArray(value) ? value.join(", ") : value; | ||
} | ||
} | ||
|
||
const fetchRequest = new Request( | ||
`${req.protocol}://${req.hostname}${req.url}`, | ||
{ | ||
method: req.method, | ||
headers, | ||
body: | ||
req.method !== "GET" && req.method !== "HEAD" | ||
? JSON.stringify(req.body) | ||
: undefined, | ||
} | ||
); | ||
|
||
// Handle authentication | ||
const response = await auth.handler(fetchRequest); | ||
|
||
// Send response back to Fastify | ||
reply.status(response.status); | ||
response.headers.forEach((value, key) => reply.header(key, value)); | ||
reply.send(await response.text()); | ||
}); | ||
``` | ||
|
||
- This ensures that all authentication-related requests are handled by **Better Auth** before reaching GraphQL. | ||
- It converts Fastify requests into **Fetch API** requests, making them compatible with **Better Auth** handlers. | ||
|
||
--- | ||
|
||
## 5. CORS Configuration | ||
To prevent **CORS errors**, we enable **CORS support** for both **GraphQL and Better Auth** using `fastify-cors`: | ||
|
||
```typescript | ||
fastify.register(fastifyCors, { | ||
origin: "http://localhost:4321", // Allow only your frontend origin | ||
credentials: true, // Allow sending cookies and authentication headers | ||
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], // Allowed methods | ||
allowedHeaders: [ | ||
"Content-Type", | ||
"Authorization", | ||
"apollo-require-preflight", | ||
], | ||
}); | ||
``` | ||
|
||
- **Origin restriction:** Allows requests only from `http://localhost:4321`. | ||
- **Credentials enabled:** Ensures authentication headers and cookies are passed. | ||
- **Allowed methods:** `GET`, `POST`, `PUT`, `DELETE`, `OPTIONS`. | ||
|
||
--- | ||
|
||
## 6. Better Auth Configuration (`auth.ts`) | ||
The authentication logic is defined inside `/src/lib/auth.ts`. Below is a summary of how **Better Auth** is configured: | ||
|
||
```typescript | ||
export const auth = betterAuth({ | ||
database: drizzleAdapter(db, { | ||
provider: "pg", | ||
schema: { | ||
user: usersTable, | ||
account: accountTable, | ||
session: sessionTable, | ||
verification: verificationTable, | ||
}, | ||
}), | ||
advanced: { | ||
generateId: false, | ||
}, | ||
user: { | ||
modelName: "user", | ||
fields: { | ||
email: "emailAddress", | ||
emailVerified: "isEmailAddressVerified", | ||
}, | ||
}, | ||
session: { | ||
expiresIn: 60 * 60 * 24 * 7, // 7 days | ||
updateAge: 60 * 60 * 24, // 1 day | ||
freshAge: 60 * 5, // 5 minutes | ||
cookieCache: { | ||
enabled: true, | ||
maxAge: 5 * 60, | ||
}, | ||
}, | ||
emailAndPassword: { | ||
enabled: true, | ||
}, | ||
trustedOrigins: ["http://localhost:4321"], | ||
}); | ||
``` | ||
|
||
### Key Features: | ||
- Uses **Drizzle ORM** as a database adapter. | ||
- Supports **email and password authentication**. | ||
- Implements **session management** with refresh-like cookie caching. | ||
- Allows **role-based access** and **trusted origins**. | ||
|
||
--- | ||
|
||
## Conclusion | ||
You have successfully integrated **Better Auth** with Fastify and GraphQL. Ensure the **environment variables**, **migrations**, and **CORS settings** are properly configured. 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
CREATE TABLE "account" ( | ||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, | ||
"account_id" text NOT NULL, | ||
"provider_id" text NOT NULL, | ||
"user_id" uuid NOT NULL, | ||
"access_token" text, | ||
"refresh_token" text, | ||
"id_token" text, | ||
"access_token_expires_at" timestamp, | ||
"refresh_token_expires_at" timestamp, | ||
"scope" text, | ||
"password" text, | ||
"created_at" timestamp NOT NULL, | ||
"updated_at" timestamp NOT NULL | ||
); | ||
--> statement-breakpoint | ||
CREATE TABLE "session" ( | ||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, | ||
"expires_at" timestamp NOT NULL, | ||
"token" text NOT NULL, | ||
"created_at" timestamp NOT NULL, | ||
"updated_at" timestamp NOT NULL, | ||
"ip_address" text, | ||
"user_agent" text, | ||
"user_id" uuid NOT NULL, | ||
CONSTRAINT "session_token_unique" UNIQUE("token") | ||
); | ||
--> statement-breakpoint | ||
CREATE TABLE "verification" ( | ||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, | ||
"identifier" text NOT NULL, | ||
"value" text NOT NULL, | ||
"expires_at" timestamp NOT NULL, | ||
"created_at" timestamp, | ||
"updated_at" timestamp | ||
); | ||
--> statement-breakpoint | ||
ALTER TABLE "users" ALTER COLUMN "is_email_address_verified" SET DEFAULT false;--> statement-breakpoint | ||
ALTER TABLE "users" ALTER COLUMN "is_email_address_verified" DROP NOT NULL;--> statement-breakpoint | ||
ALTER TABLE "users" ALTER COLUMN "password_hash" DROP NOT NULL;--> statement-breakpoint | ||
ALTER TABLE "users" ALTER COLUMN "role" SET DEFAULT 'regular';--> statement-breakpoint | ||
ALTER TABLE "users" ALTER COLUMN "role" DROP NOT NULL;--> statement-breakpoint | ||
ALTER TABLE "account" ADD CONSTRAINT "account_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint | ||
ALTER TABLE "session" ADD CONSTRAINT "session_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.