Jstack and Better Auth ENV problem
Using jstack & better-auth in a Cloudflare Workers Environment
Hi,
I'm encountering some issues while trying to use better-auth with jstack. Below, I've detailed the steps I took and the problems I faced, particularly regarding accessing environment variables in the Cloudflare Workers environment where process.env is not available. I'm looking for guidance on how to integrate jstack and better-auth under these constraints.
1. Creating the db Object with Drizzle
First, in the src/lib/db.ts file, I created a db object using Drizzle:
import { drizzle } from "drizzle-orm/neon-http";
const getDbUrl = () => {
if (typeof process.env.DATABASE_URL === "undefined") {
throw new Error("DATABASE_URL is not defined");
}
return process.env.DATABASE_URL;
};
export const db = drizzle(getDbUrl());
2. Using the Drizzle Adapter for better-auth
In the src/lib/auth.ts file, I passed the drizzle adapter along with the necessary schemas to the better-auth function:
import { betterAuth } from "better-auth";
import { db } from "./db";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { posts } from "@/server/db/schema";
import { account, session, user, verification } from "../../auth-schema";
export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
schema: {
...posts,
user: user,
account: account,
session: session,
verification: verification,
},
}),
emailAndPassword: {
enabled: true,
},
});
3. Defining the API Route Handler
I defined the handler from the returned auth object as the route handler for POST and GET requests in src/server/index.ts:
const api = j
.router()
.basePath("/api")
.on(["POST", "GET"], "/auth/**", (c) => auth.handler(c.req.raw))
.use(j.defaults.cors)
.onError(j.defaults.errorHandler);
4. Setting Up the Auth Middleware
In the src/server/jstack.ts file, I defined an auth middleware that also makes use of the auth object:
// ... other code
const databaseMiddleware = j.middleware(async ({ c, next }) => {
const { DATABASE_URL } = env(c);
const db = drizzle(DATABASE_URL);
return await next({ db });
});
const authMiddleware = j.middleware(async ({ c, next }) => {
const session = await auth.api.getSession({ headers: c.req.raw.headers });
if (!session) {
throw new HTTPException(401, {
message: "Unauthorized",
});
}
return await next({ user: session.user });
});
// ... other code
export const privateProcedure = j.procedure.use(databaseMiddleware).use(authMiddleware);
5. Wrangler Configuration
While deploying to Cloudflare Workers, I initially encountered errors that were resolved by adding the compatibility_flags and updating the compatibility_date in my wrangler.toml file:
name = "app-name"
compatibility_flags = [ "nodejs_compat" ]
compatibility_date = "2024-09-23"
main = "src/server/index.ts"
[dev]
port = 8080
6. The Issue and Question
After the above steps, I began receiving an error in the src/lib/db.ts file because the Cloudflare Workers environment doesn't support accessing process.env.DATABASE_URL. Since Cloudflare Workers doesn't have the typical Node.js environment variables, they are instead provided via Workers bindings.
Question:
How should I access environment variables in a Cloudflare Workers environment when using jstack and better-auth together, instead of relying on process.env? What is the best practice in this situation? For instance, how can I structure the Workers bindings and integrate the drizzle adapter with better-auth in this context?
I'd appreciate any suggestions or recommendations on how to properly set up jstack and better-auth in a Cloudflare Workers environment.
Thanks!