# Neon Auth

Implement authentication using Neon Auth with Better Auth for Next.js applications. This skill covers the complete authentication workflow including sign-up, sign-in, email verification, password reset, user management, and branch-isolated testing.

## When to Use This Skill

Use this skill when:
- Implementing authentication features with Neon Auth
- Setting up sign-up, sign-in, or sign-out flows
- Configuring email verification (codes or links)
- Implementing password reset functionality
- Managing user profiles and sessions
- Testing authentication with database branches
- Integrating auth with Row Level Security (RLS)

## Core Concepts

### What is Neon Auth?

Neon Auth is a managed authentication service built on Better Auth that stores all auth data directly in your Neon database's `neon_auth` schema. Key benefits:

- **Database-native**: Users, sessions, and config live in your database
- **Branch-compatible**: Auth data branches with your database for isolated testing
- **Zero infrastructure**: Managed REST API service, no servers to maintain
- **RLS integration**: Works with Row Level Security via JWT tokens
- **Better Auth foundation**: Familiar APIs and UI components

### Architecture

```
Your App (SDK)
    ↓ HTTP requests
Neon Auth Service (REST API)
    ↓ connects to database
Your Neon Database (neon_auth schema)
```

## Quick Setup (Next.js)

### 1. Install SDK

```bash
npm install @neondatabase/auth
```

### 2. Environment Variable

```env
NEON_AUTH_BASE_URL=https://ep-xxx.neonauth.us-east-1.aws.neon.tech/neondb/auth
```

### 3. API Route Handler

```typescript
// app/api/auth/[...path]/route.ts
import { authApiHandler } from '@neondatabase/auth/next/server';
export const { GET, POST } = authApiHandler();
```

### 4. Auth Middleware

```typescript
// proxy.ts
import { neonAuthMiddleware } from "@neondatabase/auth/next/server";

export default neonAuthMiddleware({
  loginUrl: "/auth/sign-in",
});

export const config = {
  matcher: ["/account/:path*"], // Protected routes
};
```

### 5. Auth Clients

```typescript
// lib/auth/client.ts
'use client';
import { createAuthClient } from '@neondatabase/auth/next';
export const authClient = createAuthClient();

// lib/auth/server.ts
import { createAuthServer } from '@neondatabase/auth/next/server';
export const authServer = createAuthServer();
```

## Implementation Approaches

### Option A: Pre-built UI Components

Use `NeonAuthUIProvider` and `AuthView` for quick setup:

```tsx
import { NeonAuthUIProvider, AuthView, UserButton } from '@neondatabase/auth/react';
import { authClient } from '@/lib/auth/client';

export default function RootLayout({ children }) {
  return (
    <NeonAuthUIProvider authClient={authClient} redirectTo="/account/settings" emailOTP>
      <header>
        <UserButton size="icon" />
      </header>
      {children}
    </NeonAuthUIProvider>
  );
}
```

Dynamic routes for auth pages:
- `/auth/sign-in` - Sign in
- `/auth/sign-up` - Sign up
- `/auth/sign-out` - Sign out
- `/account/settings` - Profile settings
- `/account/security` - Password and sessions

### Option B: Custom UI with SDK Methods

Build your own UI using SDK methods directly:

```typescript
// Server Action for sign-up
'use server';
import { authServer } from '@/lib/auth/server';

export async function signUpWithEmail(formData: FormData) {
  const { error } = await authServer.signUp.email({
    email: formData.get('email') as string,
    name: formData.get('name') as string,
    password: formData.get('password') as string,
  });
  if (error) return { error: error.message };
  redirect('/');
}
```

## Resources

This skill includes detailed resources for specific features:

| Resource | Description |
|----------|-------------|
| `sdk-methods.md` | Complete SDK API reference for client and server |
| `ui-components.md` | Pre-built UI components and provider setup |
| `email-verification.md` | Verification codes and links implementation |
| `user-management.md` | Profile updates, password changes, sessions |
| `organizations.md` | Multi-tenancy with organizations and membership |
| `trpc-integration.md` | tRPC context, auth middleware, procedure types |
| `registration-flow.md` | Complete sign-up → create-org → membership flow |
| `branching-auth.md` | Testing auth with database branches |
| `testing-patterns.md` | Integration testing with real auth (no mocks) |

## Key SDK Methods

### Client-side (authClient)

```typescript
authClient.signUp.email({ email, password, name })
authClient.signIn.email({ email, password })
authClient.signIn.social({ provider: 'google', callbackURL })
authClient.signOut()
authClient.getSession()
authClient.updateUser({ name })
authClient.changePassword({ currentPassword, newPassword })
authClient.emailOtp.verifyEmail({ email, otp })
authClient.sendVerificationEmail({ email, callbackURL })
```

### Server-side (authServer)

```typescript
authServer.signUp.email({ email, password, name })
authServer.signIn.email({ email, password })
authServer.getSession()
authServer.updateUser({ name })

// Quick session access
import { neonAuth } from "@neondatabase/auth/next/server";
const { session, user } = await neonAuth();
```

## Organizations & Multi-tenancy

Neon Auth supports organizations for multi-tenant applications. See `organizations.md` for details.

```typescript
// Create organization (user becomes owner automatically)
const { data } = await authClient.organization.create({
  name: 'My Organization',
  slug: 'my-organization',
})

// Get user's active organization
const { data: activeOrg } = await authServer.organization.getActive()
```

Organization membership is stored in `neon_auth.member` table and integrates with RLS policies.

## tRPC Integration

Use auth middleware in tRPC routers. See `trpc-integration.md` for full patterns.

```typescript
// Three procedure types based on auth requirements
publicProcedure     // No auth required
protectedProcedure  // Requires authenticated user
orgProcedure        // Requires user with active organization
```

Context provides `userId` and `organizationId` for all procedures.

## Session & JWT Flow

1. User signs in via SDK
2. Auth service validates credentials against `neon_auth.account`
3. Session created in `neon_auth.session`
4. HTTP-only cookie set: `__Secure-neonauth.session_token`
5. JWT token available in `session.access_token`
6. JWT used for Data API queries with RLS

JWT payload:
```json
{
  "sub": "user-uuid",
  "email": "user@example.com",
  "role": "authenticated",
  "exp": 1763848395
}
```

RLS policy using auth:
```sql
CREATE POLICY "Users can view own posts"
ON posts FOR SELECT TO authenticated
USING (user_id = auth.uid());
```

## Important Notes

- Safari requires HTTPS for auth (cookies are blocked on HTTP)
- Verification codes/links expire after 15 minutes
- Each branch gets its own isolated Auth URL and endpoint
- Sessions don't transfer between branches (intentional isolation)
- Password reset via SDK methods not fully supported yet - use UI components
- Email address changes not currently supported via `updateUser()`
