skills/bom-98/auth/SKILL.md
Authentication and access control skill for Next.js 15 + Supabase applications. Use when implementing user authentication, protecting routes, managing user sessions, enforcing role-based access control (admin/member), or working with multi-tenant family-based data isolation. Covers login/logout, registration with email verification, OAuth (GitHub), route protection for Server Components and Server Actions, admin-only features, and multi-tenant data access patterns.
npx skillsauth add aiskillstore/marketplace authInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides workflows for implementing authentication and access control in this Next.js 15 + Supabase application using server-side auth with httpOnly cookies, hybrid route protection, and multi-tenant family-based data isolation.
To protect a route from unauthenticated users:
requireAuthRedirect from @/lib/auth/server-authawait requireAuthRedirect() at the start of the component/login if not authenticatedimport { requireAuthRedirect } from '@/lib/auth/server-auth';
export default async function ProtectedPage() {
await requireAuthRedirect();
// User guaranteed authenticated here
return <YourContent />;
}
To protect an entire route group, add this to the layout component. All child routes will inherit the protection.
To require authentication in a Server Action:
requireAuth from @/lib/auth/server-authconst user = await requireAuth() at the start of the actionUnauthorizedError if user not authenticated'use server';
import { requireAuth } from '@/lib/auth/server-auth';
export async function myAction() {
const user = await requireAuth();
// Proceed with authenticated action
}
getCurrentUser() - Auth user (email, id), returns null if not logged ingetUserData() - Extended profile (role, familyId, firstName, lastName, active)getCurrentFamilyId() - Just the family IDAll use React cache() - multiple calls in same request return cached value.
To restrict a page to admins:
import { requireAdminRedirect } from '@/lib/auth/server-auth';
export default async function AdminPage() {
await requireAdminRedirect();
// User guaranteed to be admin
return <AdminPanel />;
}
To restrict a Server Action to admins:
'use server';
import { requireAdmin } from '@/lib/auth/server-auth';
export async function adminAction() {
await requireAdmin(); // Throws if not admin
// Proceed
}
To conditionally show admin UI:
import { isAdmin } from '@/lib/auth/server-auth';
export default async function Page() {
const userIsAdmin = await isAdmin();
return (
<>
<RegularContent />
{userIsAdmin && <AdminControls />}
</>
);
}
To ensure users only access their own family's data:
'use server';
import { requireFamilyAccess } from '@/lib/auth/server-auth';
export async function updateFamilyData(familyId: string, data: any) {
await requireFamilyAccess(familyId); // Throws if user not in this family
// User guaranteed to belong to this family
await updateDatabase(familyId, data);
}
When fetching current user's family data, use getCurrentFamilyId() instead - no need for requireFamilyAccess since it's their own family.
To create a new auth page (login, register, password reset):
src/app/(auth)/page-name/(auth) group layout automatically redirects authenticated users to /dashboardactions.ts fileconst supabase = await createClient()Pages in (auth) group are automatically protected from authenticated users - they'll be redirected to dashboard if already logged in.
Use supabase.auth.signInWithPassword() for login and supabase.auth.signOut() for logout. See references/patterns.md for complete code examples.
supabase.auth.signInWithOAuth({ provider: 'github', options: {...} })src/app/auth/callback/route.tsSee references/patterns.md for full implementation examples.
supabase.auth.getUser() to validate tokens (revalidates with server)supabase.auth.getSession() in server code (can be spoofed)src/lib/auth/server-auth.ts are server-side only'use server' directive to server-auth.ts (breaks class exports)updateSession() from src/lib/supabase/middleware.tsgetUser() to revalidate tokensFor detailed information, see:
references/file-tree.md - Complete file structure and organizationreferences/security.md - Security best practices and requirementsreferences/patterns.md - Code examples and common patternsreferences/flows.md - Authentication flow diagramsKey Files: src/lib/auth/server-auth.ts (helpers), src/middleware.ts (token refresh), src/app/dashboard/layout.tsx (dashboard protection)
Environment: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, NEXT_PUBLIC_SITE_URL
Database: auth.users (Supabase auth), public.families (households), public.users (profiles)
'use server' export error: Remove 'use server' from server-auth.ts - these are utilities, not actions
Middleware redirect fails: Use requireAuth() in Server Actions - middleware redirects don't work with POST
Multi-tenant access denied: Use requireFamilyAccess(familyId) to validate family ownership
development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.