Files
editor/packages/auth/README.md
T
2026-02-11 15:23:18 +09:00

3.4 KiB

@pascal-app/auth

Authentication package for Pascal Editor using Better Auth.

Features

  • Magic Link Authentication - Passwordless email-based authentication
  • Session Management - Secure cookie-based sessions
  • Supabase Integration - Uses Supabase as the database adapter
  • Type-safe - Full TypeScript support with type inference

Setup

1. Configure environment variables

Add these to apps/editor/.env.local:

# Better Auth
BETTER_AUTH_SECRET=<generate_with_openssl_rand_base64_32>
BETTER_AUTH_URL=http://localhost:3000

Generate a secret for BETTER_AUTH_SECRET:

openssl rand -base64 32

2. Ensure database is running

Make sure you have Supabase running with the auth tables created. See @pascal-app/db package for setup.

Usage

Server-side (API routes, server actions)

import { auth } from '@pascal-app/auth/server'

// Get session in server component or action
const session = await auth.api.getSession({ headers: request.headers })

if (!session) {
  return { error: 'Unauthorized' }
}

// Access user data
const userId = session.user.id
const email = session.user.email

Client-side (React components)

'use client'

import { authClient } from '@pascal-app/auth/client'

function SignInButton() {
  const { signIn } = authClient

  const handleSignIn = async (email: string) => {
    await signIn.magicLink({
      email,
      callbackURL: '/dashboard',
    })
  }

  return <button onClick={() => handleSignIn('user@example.com')}>Sign In</button>
}

Using the auth hook

'use client'

import { authClient } from '@pascal-app/auth/client'

function Profile() {
  const { data: session, isPending } = authClient.useSession()

  if (isPending) return <div>Loading...</div>
  if (!session) return <div>Not signed in</div>

  return <div>Signed in as {session.user.email}</div>
}

API Routes

The auth package requires an API route handler in your Next.js app:

// app/api/auth/[...all]/route.ts
import { auth } from '@pascal-app/auth/server'
import { toNextJsHandler } from 'better-auth/next-js'

export const { GET, POST } = toNextJsHandler(auth)

This handles all Better Auth endpoints:

  • /api/auth/sign-in/magic-link - Send magic link
  • /api/auth/sign-in/magic-link/verify - Verify magic link
  • /api/auth/sign-out - Sign out
  • /api/auth/session - Get session
  • And more...

Email Configuration

By default, magic links are logged to the console. To send actual emails, you'll need to configure an email provider in packages/auth/src/server.ts:

magicLink({
  sendMagicLink: async ({ email, url }) => {
    // Use Resend, SendGrid, or your preferred email service
    await sendEmail({
      to: email,
      subject: 'Sign in to Pascal Editor',
      html: `Click here to sign in: <a href="${url}">${url}</a>`,
    })
  },
})

Database Schema

The auth package requires these tables (created by @pascal-app/db migrations):

  • users - User accounts
  • sessions - Active sessions
  • accounts - OAuth provider accounts (for future use)
  • verification_tokens - Magic link tokens

Security

  • Session cookies are httpOnly and secure (in production)
  • Sessions expire after 7 days
  • Session cache is enabled for 5 minutes to reduce database queries
  • Magic link tokens expire after 15 minutes
  • All sensitive operations require valid session tokens