Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/revokslab/shipfree/llms.txt

Use this file to discover all available pages before exploring further.

ShipFree uses Better-Auth for a complete authentication solution with support for email/password, OAuth providers, email OTP, and organizations.

Architecture

The authentication system consists of three main components:
  1. Server-side Auth Configuration (src/lib/auth/auth.ts)
  2. Client-side Auth Client (src/lib/auth/auth-client.ts)
  3. API Routes (src/app/api/auth/[...all]/route.ts)

Features

Email & Password Authentication

Email and password authentication with optional email verification:
import { client } from '@/lib/auth'

// Sign up with email and password
const { data, error } = await client.signUp.email({
  email: 'user@example.com',
  password: 'securePassword123',
  name: 'John Doe'
})

// Sign in
const { data, error } = await client.signIn.email({
  email: 'user@example.com',
  password: 'securePassword123'
})

Email OTP (One-Time Password)

Passwordless authentication via email OTP:
import { client } from '@/lib/auth'

// Send OTP to email
await client.emailOtp.sendVerificationOtp({
  email: 'user@example.com',
  type: 'sign-in' // or 'email-verification' or 'forget-password'
})

// Verify OTP and sign in
const { data, error } = await client.emailOtp.verifyEmail({
  email: 'user@example.com',
  otp: '123456'
})
Configuration (from src/lib/auth/auth.ts:130-188):
  • OTP Length: 6 digits
  • Expiration: 15 minutes
  • Types: sign-in, email-verification, forget-password
  • Email delivery: Configured via email service (Resend, Postmark, Plunk, or Nodemailer)

OAuth Providers

Supported OAuth providers (configured in src/lib/auth/auth.ts:45-78):

Google

Requires GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET

GitHub

Requires GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET

Microsoft

Requires MICROSOFT_CLIENT_ID and MICROSOFT_CLIENT_SECRET

Facebook

Requires FACEBOOK_CLIENT_ID and FACEBOOK_CLIENT_SECRET
Usage:
import { client } from '@/lib/auth'

// Initiate OAuth flow
await client.signIn.social({
  provider: 'google', // or 'github', 'microsoft', 'facebook'
  callbackURL: '/dashboard'
})

Session Management

Configuration from src/lib/auth/auth.ts:35-43:
Enable cookie-based session caching
Cache duration: 24 hours (in seconds)
expiresIn
number
default:2592000
Session lifetime: 30 days (in seconds)
updateAge
number
default:86400
How often to refresh expiry: 24 hours (in seconds)
freshAge
number
default:3600
Fresh session window: 1 hour (in seconds)
Get current session:
// Client-side
import { useSession } from '@/lib/auth'

function MyComponent() {
  const { data: session, isPending } = useSession()
  
  if (isPending) return <div>Loading...</div>
  if (!session) return <div>Not authenticated</div>
  
  return <div>Hello, {session.user.name}!</div>
}
// Server-side (Server Components or API Routes)
import { auth } from '@/lib/auth'
import { headers } from 'next/headers'

const session = await auth.api.getSession({
  headers: await headers()
})

if (!session) {
  // User is not authenticated
}

Organizations

Multi-tenant organization support via the organization plugin (src/lib/auth/auth.ts:190-211):
import { client } from '@/lib/auth'

// Create an organization
const { data } = await client.organization.create({
  name: 'My Company',
  slug: 'my-company'
})

// Invite members
await client.organization.inviteMember({
  organizationId: 'org_123',
  email: 'member@example.com',
  role: 'member' // or 'admin'
})

Database Schema

Better-Auth integrates with ShipFree’s PostgreSQL database via Drizzle ORM. See Database Schema for table structures. Key tables:
  • user - User accounts
  • session - Active sessions
  • account - OAuth accounts linked to users
  • verification - Email verification tokens and OTP codes

Email Verification

Email verification can be enabled/disabled via feature flag (src/config/feature-flags.ts). Configuration (src/lib/auth/auth.ts:80-126):
emailVerification: {
  autoSignInAfterVerification: true,
  afterEmailVerification: async (user) => {
    // Send welcome email after successful verification
  }
}

emailAndPassword: {
  enabled: true,
  requireEmailVerification: isEmailVerificationEnabled,
  sendResetPassword: async ({ user, url }) => {
    // Send password reset email
  }
}

Password Reset

Password reset flow:
import { client } from '@/lib/auth'

// Request password reset
await client.forgetPassword({
  email: 'user@example.com',
  redirectTo: '/reset-password'
})

// Reset with token
await client.resetPassword({
  newPassword: 'newSecurePassword123',
  token: 'reset_token_from_email'
})

Sign Out

import { signOut } from '@/lib/auth'

// Sign out current session
await signOut()

// Sign out and redirect
await signOut({ redirect: '/login' })

Custom Pages

Authentication pages are configured in src/lib/auth/auth.ts:214-219:
pages: {
  signIn: '/login',
  signUp: '/register',
  error: '/error',
  verify: '/verify'
}

Next Steps

API Endpoints

Explore all available authentication endpoints

Database Schema

View authentication-related database tables

Build docs developers (and LLMs) love