Documentation is currently in beta. Report issues →
API ReferenceAuthentication

Authentication API

Authentication is handled by Supabase Auth. This page documents the auth flow and related endpoints.

Auth Flow

Y3NKO uses Supabase Auth with the following providers:

  • Email/Password
  • Google OAuth
  • Magic Links

Sign Up

Email/Password

// Using Supabase client
import { createClient } from '@/lib/supabase/client'
 
const supabase = createClient()
 
const { data, error } = await supabase.auth.signUp({
  email: 'user@example.com',
  password: 'securepassword',
  options: {
    data: {
      first_name: 'Kwame',
      last_name: 'Asante'
    }
  }
})

Response

{
  "user": {
    "id": "uuid-here",
    "email": "user@example.com",
    "user_metadata": {
      "first_name": "Kwame",
      "last_name": "Asante"
    }
  },
  "session": null // Email confirmation required
}

Email confirmation is required. Users receive a confirmation email with a magic link.


Sign In

Email/Password

const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'securepassword'
})

Google OAuth

const { data, error } = await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: {
    redirectTo: `${window.location.origin}/auth/callback`
  }
})
const { data, error } = await supabase.auth.signInWithOtp({
  email: 'user@example.com',
  options: {
    emailRedirectTo: `${window.location.origin}/auth/callback`
  }
})

Auth Callback

Handle OAuth and magic link callbacks:

// app/auth/callback/route.ts
import { createClient } from '@/lib/supabase/server'
import { NextResponse } from 'next/server'
 
export async function GET(request: Request) {
  const { searchParams } = new URL(request.url)
  const code = searchParams.get('code')
  const next = searchParams.get('next') ?? '/dashboard'
 
  if (code) {
    const supabase = await createClient()
    const { error } = await supabase.auth.exchangeCodeForSession(code)
 
    if (!error) {
      return NextResponse.redirect(new URL(next, request.url))
    }
  }
 
  return NextResponse.redirect(new URL('/auth/error', request.url))
}

Sign Out

const { error } = await supabase.auth.signOut()

Get Current User

Client-side

const { data: { user } } = await supabase.auth.getUser()

Server-side

// In Server Component or Server Action
import { createClient } from '@/lib/supabase/server'
 
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()

Password Reset

Request Reset

const { data, error } = await supabase.auth.resetPasswordForEmail(
  'user@example.com',
  {
    redirectTo: `${window.location.origin}/auth/reset-password`
  }
)

Update Password

const { data, error } = await supabase.auth.updateUser({
  password: 'newSecurePassword'
})

Session Management

Sessions are automatically managed via HTTP-only cookies.

Check Session

const { data: { session } } = await supabase.auth.getSession()

Refresh Session

Sessions are automatically refreshed. For manual refresh:

const { data, error } = await supabase.auth.refreshSession()

User Profile Sync

After Supabase auth, sync user data to the application database:

// lib/auth.ts
import { createClient } from '@/lib/supabase/server'
import { prisma } from '@/lib/db'
 
export async function getCurrentUser() {
  const supabase = await createClient()
  const { data: { user } } = await supabase.auth.getUser()
 
  if (!user) return null
 
  // Find or create user in our database
  let dbUser = await prisma.user.findUnique({
    where: { id: user.id },
    include: { profile: true }
  })
 
  if (!dbUser) {
    dbUser = await prisma.user.create({
      data: {
        id: user.id,
        email: user.email!,
        emailVerified: user.email_confirmed_at ? new Date() : null,
        profile: {
          create: {
            firstName: user.user_metadata.first_name || '',
            lastName: user.user_metadata.last_name || '',
            avatarUrl: user.user_metadata.avatar_url
          }
        }
      },
      include: { profile: true }
    })
  }
 
  return dbUser
}

Protected Routes

Use middleware to protect routes:

// middleware.ts
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'
 
export async function middleware(request: NextRequest) {
  const response = NextResponse.next()
 
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            response.cookies.set(name, value, options)
          )
        },
      },
    }
  )
 
  const { data: { user } } = await supabase.auth.getUser()
 
  // Redirect unauthenticated users
  const protectedPaths = ['/dashboard', '/host', '/admin']
  const isProtected = protectedPaths.some(path =>
    request.nextUrl.pathname.startsWith(path)
  )
 
  if (isProtected && !user) {
    const loginUrl = new URL('/login', request.url)
    loginUrl.searchParams.set('next', request.nextUrl.pathname)
    return NextResponse.redirect(loginUrl)
  }
 
  return response
}
 
export const config = {
  matcher: ['/dashboard/:path*', '/host/:path*', '/admin/:path*']
}

Error Codes

CodeDescription
invalid_credentialsWrong email or password
email_not_confirmedEmail not verified
user_already_existsEmail already registered
weak_passwordPassword doesn’t meet requirements
over_email_send_rate_limitToo many email requests