Auth Module
What auth-basic installs
$ asa install auth-basicNot a marketing mock. Every component below is from the actual module output.
This is real output from our architecture service — not a downloadable template.
Register
domains/auth/register/ui/AuthRegister.tsx
Validation State
Invalid email address
Password must be at least 8 characters
Display name is required
Success State
Account created
Redirecting to dashboard...
Zod validation: All fields validated server-side before Supabase call. Generic error on duplicate email — no account enumeration. Profile created in profiles table with RLS.
Login
domains/auth/login/ui/AuthLogin.tsx
Default State
No account? Create one
Error State
Invalid credentials
No hint whether email or password is wrong.
Server-verified: Uses getUser() — not getSession() — for JWT verification. HttpOnly cookie session. Generic error message prevents credential enumeration. Lint rule SEC-002 blocks getSession() misuse.
Reset Password
domains/auth/reset-password/ui/AuthResetPassword.tsx
Enter your email and we'll send you a reset link.
Security: Generic response for all emails (no enumeration). Reset token sent via Supabase Auth email flow.
What the Handler Looks Like
domains/auth/login/handler.ts — generated code
import { NextRequest, NextResponse } from 'next/server';
import { createBrowserClient } from '@/shared/db/supabase-client';
import { loginSchema } from './schemas';
export async function POST(request: NextRequest) {
const body = await request.json();
const parsed = loginSchema.safeParse(body);
if (!parsed.success) {
return NextResponse.json(
{ error: parsed.error.issues[0]?.message },
{ status: 400 }
);
}
const supabase = createBrowserClient();
const { data, error } = await supabase.auth.signInWithPassword({
email: parsed.data.email,
password: parsed.data.password,
});
if (error) {
return NextResponse.json(
{ error: 'Invalid credentials' }, // No enumeration
{ status: 401 }
);
}
return NextResponse.json({ user: data.user });
}Real generated code. Zod validation. Server-side auth. Generic error messages.
Server-Side Guards
shared/auth/guards.ts — always verify server-side
// Every protected handler uses this:
const { user, response } = await requireAuth(request);
if (response) return response; // 401 if not authenticated
// For role-based access:
const { user, response } = await requireRole(request, 'admin');
if (response) return response; // 403 if wrong roleProtected Route Redirect
shared/auth/middleware.ts — unauthenticated users never see protected content
Defense in depth: Middleware redirects unauthenticated users. Route handlers re-verify with requireAuth(). Even if middleware is bypassed, the handler rejects the request.
Complete Auth Flow
Register → Login → Protected Page — end to end
Register
Zod validated → Supabase Auth → Profile created → Redirect
Login
Server-verified → HttpOnly cookie → getUser() check
Middleware
Every request → getUser() → Redirect if unauthenticated
Dashboard
requireAuth() server-side → User data from verified JWT
Real auth output. Not a marketing mock.
Install auth-basic and get server-verified sessions, validation, and protected routes in your project.