AGENTS.md · diff

git:20260823.e9f5b61 to git:20260914.834064b

4 added, 4 removed. Audit A to A.

# AI Assistant Guidelines
This document provides additional context for AI assistants working on this Better Auth Firebase Auth plugin project. **Please read [README.md](./README.md) first** for project overview and features.
**Note:** All planned phases are complete. The plugin is fully implemented and ready for use.
## Quick Reference
- **Main Documentation:** See [README.md](./README.md) for project overview
- **Contributing Guidelines:** See [Better Auth Contributing Guide](https://www.better-auth.com/docs/reference/contributing)
- **Plugin Architecture:** See [Better Auth Plugin Guide](https://www.better-auth.com/docs/guides/your-first-plugin)
## Current Project State
**Phase 1: Project Foundation** ✅ Complete
**Phase 2: Types and Core Structure** ✅ Complete
**Phase 3: Server Plugin - Endpoints** ✅ Complete
**Phase 4: Server Plugin - Hooks** ✅ Complete
**Phase 5: Client Plugin - Methods** ✅ Complete
**Phase 6: Tests** ✅ Complete
**Phase 7: CI/CD and Example Project** ✅ Complete
## Supported Firebase Auth Providers
The plugin currently implements a subset of Firebase Authentication methods:
### Implemented Providers
- **Google OAuth** (`/firebase-auth/sign-in-with-google` endpoint)
- **Email/Password** (`/firebase-auth/sign-in-with-email` endpoint)
- **Password Reset** with email verification and custom URLs
- `/firebase-auth/send-password-reset` - Send reset email
- `/firebase-auth/verify-password-reset-code` - Verify reset code
- `/firebase-auth/confirm-password-reset` - Complete password reset
### Not Implemented (but available in Firebase Auth)
**Social Providers:**
- Facebook, GitHub, Twitter/X, Microsoft, Apple, Yahoo, LinkedIn
**Phone/SMS Authentication:**
- Phone number sign-in with SMS verification
- Multi-factor authentication (MFA)
**Other Methods:**
- Anonymous authentication
- Custom authentication tokens
- SAML/OIDC providers
- Game Center (iOS), Play Games (Android)
### Key Implementation Pattern
All authentication methods follow the same core flow:
1. **Get Firebase ID token** (client-side or server-side)
2. **Verify token** with Firebase Admin SDK (`adminAuth.verifyIdToken()`)
3. **Create/update Better Auth user** via `internalAdapter.createUser()` / `internalAdapter.updateUser()`
4. **Create Better Auth session** via `internalAdapter.createSession()`
- 5. **Store account link** via `internalAdapter.linkAccount()` / `internalAdapter.updateAccount()` with `providerId: "firebase"`, `accountId: <Firebase UID>`, `issuer: FIREBASE_ACCOUNT_ISSUER`
+ 5. **Store account link** via `internalAdapter.linkAccount()` / `internalAdapter.updateAccount()` with `providerId: "firebase"`, `accountId: <Firebase UID>`, plus `issuer: FIREBASE_ACCOUNT_ISSUER` on Better Auth 1.7.0 – 1.7.2
When adding new providers, follow the `signInWithGoogle` endpoint pattern as a reference implementation.
### Important Notes
- All Firebase authentication methods use `providerId: "firebase"` in account records
- - `accountId` is the Firebase UID; `issuer` is `FIREBASE_ACCOUNT_ISSUER` (`"local:oauth:firebase"`)
+ - `accountId` is the Firebase UID; on Better Auth 1.7.0 – 1.7.2 rows also carry `issuer: FIREBASE_ACCOUNT_ISSUER` (`"local:oauth:firebase"`)
- User, account, and session operations all go through `internalAdapter` (not `adapter`) for proper database hooks and secondary storage support
- - Better Auth 1.7 keys accounts by `(issuer, accountId)` and removed `findOAuthUser`; 1.5 – 1.6 key them by `(providerId, accountId)`. `findFirebaseAccountOwner` in `src/firebase-auth-plugin.ts` feature-detects `findAccountOwnerByKey` so one build supports both. CI runs the tests against 1.5, 1.6, and 1.7 — keep that matrix green when touching the lookup
+ - Better Auth 1.7 replaced `findOAuthUser` with `findAccountOwnerByKey`. 1.7.0 – 1.7.2 key accounts by `(issuer, accountId)` and declare a required `account.issuer` field; 1.5 – 1.6 and 1.7.3+ key them by `(providerId, accountId)`. `findFirebaseAccountOwner` in `src/firebase-auth-plugin.ts` feature-detects both (`findAccountOwnerByKey` on the internal adapter, `issuer` in `context.tables.account.fields`) so one build supports every line. CI runs the tests against 1.5, 1.6, 1.7.2, and the latest 1.7 — keep that matrix green when touching the lookup
## Project Files
The project is complete and includes:
- **Configuration files:** `package.json`, `tsconfig.json`, `tsconfig.build.json`, `vitest.config.ts`, `biome.json`
- **Build tooling:** `.gitignore`, `.releaserc.json`
- **Documentation:** `README.md`, `AGENTS.md`, `LICENSE`
- **Source code:**
- `src/types.ts` - TypeScript interfaces and types
- `src/firebase-auth-plugin.ts` - Server plugin with endpoints and hooks
- `src/firebase-auth-client-plugin.ts` - Client plugin with methods
- `src/index.ts` - Main exports
- **Tests:**
- `src/firebase-auth-plugin.test.ts` - Server plugin tests (14 tests)
- `src/firebase-auth-client-plugin.test.ts` - Client plugin tests (10 tests)
- **CI/CD:** GitHub Actions workflows for testing and releases
- **Example:** Minimal Next.js example project in `examples/minimal/`
## Project Structure
```
src/
firebase-auth-plugin.ts # Server plugin implementation (endpoints and hooks complete)
firebase-auth-client-plugin.ts # Client plugin implementation (methods complete)
index.ts # Export both plugins and types
types.ts # Plugin-specific types and interfaces
examples/
minimal/ # Minimal Next.js example project
.github/
workflows/
release.yml # CI/CD release workflow
ci.yml # CI workflow for PRs
```
## Key Implementation Patterns
### Server Plugin Structure
- Export a function that returns a `BetterAuthPlugin`
- Plugin must have unique `id: "firebase-auth"`
- Use `createAuthEndpoint` from `better-auth/api` for endpoints
- Prefer `createAuthMiddleware` from `better-auth/api` for hooks
- Keep fallback compatibility with `better-auth/plugins` for older Better Auth versions
- Follow Better Auth plugin patterns from [plugin guide](https://www.better-auth.com/docs/guides/your-first-plugin)
### Client Plugin Structure
- Export a function that returns a `BetterAuthClientPlugin`
- Use `$InferServerPlugin` to infer types from server plugin
- Use `getActions` to provide client-side methods
- Methods should accept one data argument and optional `fetchOptions`
### Account Storage
- All Firebase Auth methods use `providerId: "firebase"` in account records
- - `accountId` is the Firebase UID; `issuer` is `FIREBASE_ACCOUNT_ISSUER`
+ - `accountId` is the Firebase UID; `issuer` is `FIREBASE_ACCOUNT_ISSUER` on Better Auth 1.7.0 – 1.7.2 only
- Use `context.internalAdapter.linkAccount()` / `updateAccount()` for account records
### Endpoint Creation Pattern
```ts
import { createAuthEndpoint } from "better-auth/api";
endpoints: {
signInWithGoogle: createAuthEndpoint("/firebase-auth/sign-in-with-google", {
method: "POST",
}, async (ctx) => {
// Implementation
return ctx.json({ success: true });
}),
}
```
### Hook Pattern
```ts
import { createAuthMiddleware } from "better-auth/api";
hooks: {
before: [
{
matcher: (context) => context.path.startsWith("/sign-in/email"),
handler: createAuthMiddleware(async (ctx) => {
// Implementation
return { context: ctx };
}),
},
],
}
```
### Error Handling Pattern
```ts
import { APIError } from "better-auth/api";
if (!token) {
throw new APIError("BAD_REQUEST", { message: "Token is required" });
}
```
### User and Session Creation
- Use `context.internalAdapter.createUser()` / `updateUser()` to create/update users (`createUser` takes a provisioning `source` on 1.7; older versions ignore it)
- Use `context.internalAdapter.createSession()` to create sessions
- Map Firebase user data (uid, email, name, photoURL) to Better Auth user schema
## Important Constraints
- When `serverSideOnly: true`, endpoints are NOT registered
- When `serverSideOnly: true`, client plugin returns empty object from `getActions`
- When `useClientSideTokens: false`, `firebaseConfig` is required
- When `overrideEmailPasswordFlow: true`, `firebaseConfig` is required
- All endpoints should be conditionally registered based on `serverSideOnly` flag
- Password reset requires Firebase Client SDK (needs `firebaseConfig`)
- Hooks intercept Better Auth's `/sign-in/email` and `/sign-up/email` endpoints when `overrideEmailPasswordFlow: true`
## Code Style
- Use BiomeJS for formatting (tab indentation)
- Follow TypeScript strict mode
- Avoid using Classes (follow Better Auth conventions)
- Keep functions small and focused
- Use meaningful variable and function names
## Testing
- Place test files next to source files they test
- Use Vitest for testing
- Use Better Auth test helpers when available
- Test all code paths and error scenarios
- Test with both `useClientSideTokens: true` and `false`
- Test with `overrideEmailPasswordFlow: true` and `false`
- Test with `serverSideOnly: true` and `false`
## Build Commands
- `pnpm install` - Install dependencies
- `pnpm build` - Build the project
- `pnpm test` - Run tests
- `pnpm lint` - Check for linting issues
- `pnpm lint:fix` - Fix auto-fixable linting issues
## Commit Messages
Follow Conventional Commits format:
- `feat(firebase-auth): description` - New features
- `fix(server): description` - Bug fixes
- `docs: description` - Documentation changes
- `chore: description` - Build/tooling changes
- `test(server): description` - Test changes
### What publishes a release
`semantic-release` publishes from `feat` (minor) and `fix` (patch) commits.
`chore`, `docs`, and `test` never publish, and never appear in the changelog.
Dependency bumps land as `chore(deps)` / `chore(deps-dev)` and are inert on
purpose: the package ships only `dist/` and declares every runtime dependency
as a peer, so a bump cannot change the published artifact. Merge Dependabot
PRs as-is.
Use `fix(deps):` or `fix(security):` when a change *should* reach consumers --
a `peerDependencies` range change, or a rebuild worth publishing. Those cut a
patch and show up in the changelog under Bug Fixes.
## References
- [Better Auth Plugin Guide](https://www.better-auth.com/docs/guides/your-first-plugin)
- [Better Auth Plugin Concepts](https://www.better-auth.com/docs/concepts/plugins)
- [Better Auth Contributing Guide](https://www.better-auth.com/docs/reference/contributing)
- [Better Auth Firestore Package](https://github.com/yultyyev/better-auth-firestore) (reference implementation)