6.9 KiB
ADDED Requirements
Requirement: Auth.js v5 configuration
The system SHALL configure Auth.js v5 (next-auth@5) in src/auth.ts with JWT session strategy, Credentials provider, and Google OAuth provider. The configuration SHALL export handlers, auth, signIn, and signOut functions.
Scenario: Auth config exports
- WHEN
src/auth.tsis imported - THEN it exports
handlers(GET/POST),auth(session getter),signIn, andsignOutfunctions
Scenario: JWT session strategy
- WHEN a user authenticates successfully
- THEN a JWT token is issued containing
user.id,user.email, anduser.name - AND no database session record is created
Scenario: JWT callbacks embed user ID
- WHEN the JWT callback fires after sign-in
- THEN the
token.idis set to the user's UUID from the database - AND the session callback maps
token.idtosession.user.id
Requirement: Credentials provider with email/password
The Credentials provider SHALL accept email and password fields. The authorize function SHALL look up the user by email in the users table, verify the password against the stored password_hash using bcryptjs, and return the user object on success or null on failure.
Scenario: Valid credentials
- WHEN a user submits correct email and password
- THEN the authorize function returns the user object with
id,email,name - AND a JWT session is created
Scenario: Invalid password
- WHEN a user submits correct email but wrong password
- THEN the authorize function returns
null - AND no session is created
Scenario: Non-existent email
- WHEN a user submits an email that does not exist in the database
- THEN the authorize function returns
null
Scenario: OAuth-only user attempts password login
- WHEN a user who registered via Google (no password_hash) submits their email with any password
- THEN the authorize function returns
null
Requirement: Google OAuth provider
The Google OAuth provider SHALL be configured with AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET environment variables. On first Google sign-in, the system SHALL create a new user record with provider: 'google' and provider_account_id set to the Google sub ID. On subsequent sign-ins, the system SHALL find the existing user by email.
Scenario: First Google sign-in creates user
- WHEN a user signs in with Google for the first time
- THEN a new user record is created with
provider: 'google',password_hash: null,provider_account_idset to the Google sub ID, andname/email/imagefrom the Google profile
Scenario: Returning Google sign-in
- WHEN a user signs in with Google and their email already exists in the database
- THEN the existing user is returned and no duplicate is created
Scenario: Missing Google credentials
- WHEN
AUTH_GOOGLE_IDorAUTH_GOOGLE_SECRETenvironment variables are not set - THEN the Google provider SHALL not be included in the providers list and email/password login remains available
Requirement: Auth API route handler
The system SHALL create src/app/api/auth/[...nextauth]/route.ts that exports the GET and POST handlers from src/auth.ts.
Scenario: Auth routes respond
- WHEN a request is made to
/api/auth/signin,/api/auth/signout,/api/auth/session, or/api/auth/callback/google - THEN the NextAuth handler processes the request
Requirement: Registration API endpoint
The system SHALL provide a POST /api/auth/register endpoint that creates a new user account. The endpoint SHALL accept { name, email, password } in the request body. The password SHALL be hashed with bcryptjs (salt rounds: 10) before storage. The email SHALL be checked for uniqueness.
Scenario: Successful registration
- WHEN POST /api/auth/register is called with valid name, email, and password (min 8 characters)
- THEN a new user is created with hashed password,
provider: 'credentials' - AND the response is HTTP 201 with
{ id, email, name }
Scenario: Duplicate email
- WHEN POST /api/auth/register is called with an email that already exists
- THEN the response is HTTP 409 with
{ error: "Email already registered" }
Scenario: Invalid password length
- WHEN POST /api/auth/register is called with a password shorter than 8 characters
- THEN the response is HTTP 400 with
{ error: "Password must be at least 8 characters" }
Scenario: Missing required fields
- WHEN POST /api/auth/register is called without email or password
- THEN the response is HTTP 400 with
{ error: "Email and password are required" }
Requirement: Auth proxy for route protection
The system SHALL create a proxy.ts file at the project root that uses Auth.js auth() to check JWT sessions. The proxy SHALL enforce authentication on protected routes.
Scenario: Unauthenticated access to /app
- WHEN an unauthenticated user requests any path under
/appor/app/* - THEN the proxy redirects to
/login
Scenario: Unauthenticated access to /api
- WHEN an unauthenticated user requests any path under
/api/*except/api/auth/*and/api/health - THEN the proxy returns HTTP 401
Scenario: Authenticated access to /login
- WHEN an authenticated user requests
/loginor/register - THEN the proxy redirects to
/app
Scenario: Public routes pass through
- WHEN any user requests
/,/login,/register,/api/auth/*, or/api/health - THEN the proxy allows the request to proceed without auth check
Requirement: Auth helper for API routes
The system SHALL provide a getAuthUser() helper function in src/lib/auth.ts that extracts the authenticated user from the current session. All protected API routes SHALL call this function.
Scenario: Authenticated request
- WHEN
getAuthUser()is called in an API route with a valid JWT session - THEN it returns
{ id, email, name }from the session
Scenario: Unauthenticated request
- WHEN
getAuthUser()is called in an API route without a valid session - THEN it returns
null
Requirement: SessionProvider wrapper
The system SHALL wrap the app layout with next-auth/react SessionProvider so client components can use the useSession() hook to access auth state.
Scenario: Session available in client components
- WHEN a client component calls
useSession()inside the protected app layout - THEN it receives
{ data: session, status: "authenticated" }withsession.user.id,session.user.email,session.user.name
Requirement: npm dependencies for auth
The project SHALL add next-auth@5 (Auth.js v5), bcryptjs, and @types/bcryptjs to the dependencies.
Scenario: Dependencies installed
- WHEN
package.jsonis inspected - THEN
next-auth,bcryptjsare independenciesand@types/bcryptjsis indevDependencies