diff --git a/.agent/tools/api/better-auth.md b/.agent/tools/api/better-auth.md new file mode 100644 index 00000000..b5651945 --- /dev/null +++ b/.agent/tools/api/better-auth.md @@ -0,0 +1,273 @@ +--- +description: Better Auth - authentication library for Next.js, sessions, OAuth +mode: subagent +tools: + read: true + write: true + edit: true + bash: true + glob: true + grep: true + webfetch: true + task: true + context7_*: true +--- + +# Better Auth - Authentication Library + + + +## Quick Reference + +- **Purpose**: Full-featured authentication for Next.js applications +- **Packages**: `better-auth`, `@better-auth/expo`, `@better-auth/passkey` +- **Docs**: Use Context7 MCP for current documentation + +**Key Features**: +- Email/password, OAuth, magic links, passkeys +- Session management with database storage +- Built-in Drizzle adapter +- React hooks for client-side auth + +**Server Setup**: + +```tsx +// packages/auth/src/server.ts +import { betterAuth } from "better-auth"; +import { drizzleAdapter } from "better-auth/adapters/drizzle"; +import { db } from "@workspace/db"; + +// Validate required environment variables +const requiredEnvVars = ['GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET', 'BETTER_AUTH_SECRET'] as const; +for (const envVar of requiredEnvVars) { + if (!process.env[envVar]) { + throw new Error(`Missing required environment variable: ${envVar}`); + } +} + +export const auth = betterAuth({ + database: drizzleAdapter(db, { + provider: "pg", + }), + emailAndPassword: { + enabled: true, + }, + socialProviders: { + google: { + clientId: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET, + }, + }, +}); +``` + +**Client Hooks**: + +```tsx +// packages/auth/src/client/react.ts +import { createAuthClient } from "better-auth/react"; + +export const authClient = createAuthClient({ + baseURL: process.env.NEXT_PUBLIC_APP_URL, +}); + +export const { useSession, signIn, signOut, signUp } = authClient; +``` + +**Usage in Components**: + +```tsx +"use client"; +import { useSession, signIn, signOut } from "@workspace/auth/client/react"; + +function AuthButton() { + const { data: session, isPending } = useSession(); + + if (isPending) return
{part.text}
; + } + if (part.type === "tool-call") { + return{part.text}
+ ); + } + return null; + })} +{t("ai.sidebar.subtitle")}
+ +